Skip to content

Commit 70b49d8

Browse files
committed
Rework the extern detection
1 parent c59d89f commit 70b49d8

File tree

5 files changed

+41
-41
lines changed

5 files changed

+41
-41
lines changed

src/librustc/metadata/csearch.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ pub fn is_const_fn(cstore: &cstore::CStore, did: DefId) -> bool {
344344
decoder::is_const_fn(&*cdata, did.index)
345345
}
346346

347-
pub fn is_extern_static(cstore: &cstore::CStore, did: DefId) -> bool {
347+
pub fn is_extern_item(cstore: &cstore::CStore, did: DefId, tcx: &ty::ctxt) -> bool {
348348
let cdata = cstore.get_crate_data(did.krate);
349-
decoder::is_extern_static(&*cdata, did.index)
349+
decoder::is_extern_item(&*cdata, did.index, tcx)
350350
}
351351

352352
pub fn is_impl(cstore: &cstore::CStore, did: DefId) -> bool {
@@ -381,12 +381,6 @@ pub fn is_default_impl(cstore: &cstore::CStore, impl_did: DefId) -> bool {
381381
decoder::is_default_impl(&*cdata, impl_did.index)
382382
}
383383

384-
pub fn is_extern_fn(cstore: &cstore::CStore, did: DefId,
385-
tcx: &ty::ctxt) -> bool {
386-
let cdata = cstore.get_crate_data(did.krate);
387-
decoder::is_extern_fn(&*cdata, did.index, tcx)
388-
}
389-
390384
pub fn closure_kind<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureKind {
391385
assert!(!def_id.is_local());
392386
let cdata = tcx.sess.cstore.get_crate_data(def_id.krate);

src/librustc/metadata/decoder.rs

+20-22
Original file line numberDiff line numberDiff line change
@@ -1425,14 +1425,28 @@ pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
14251425
}
14261426
}
14271427

1428-
pub fn is_extern_static(cdata: Cmd, id: DefIndex) -> bool {
1429-
let item_doc = cdata.lookup_item(id);
1430-
match item_family(item_doc) {
1431-
ImmStatic | MutStatic => {
1432-
let attrs = get_attributes(item_doc);
1433-
attr::contains_name(&attrs, "no_mangle")
1428+
pub fn is_extern_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
1429+
let item_doc = match cdata.get_item(id) {
1430+
Some(doc) => doc,
1431+
None => return false,
1432+
};
1433+
let applicable = match item_family(item_doc) {
1434+
ImmStatic | MutStatic => true,
1435+
Fn => {
1436+
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
1437+
let no_generics = generics.types.is_empty();
1438+
match ty.sty {
1439+
ty::TyBareFn(_, fn_ty) if fn_ty.abi != abi::Rust => return no_generics,
1440+
_ => no_generics,
1441+
}
14341442
},
14351443
_ => false,
1444+
};
1445+
1446+
if applicable {
1447+
attr::contains_extern_indicator(&get_attributes(item_doc))
1448+
} else {
1449+
false
14361450
}
14371451
}
14381452

@@ -1552,22 +1566,6 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
15521566
}).collect()
15531567
}
15541568

1555-
pub fn is_extern_fn(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
1556-
let item_doc = match cdata.get_item(id) {
1557-
Some(doc) => doc,
1558-
None => return false,
1559-
};
1560-
if let Fn = item_family(item_doc) {
1561-
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
1562-
generics.types.is_empty() && match ty.sty {
1563-
ty::TyBareFn(_, fn_ty) => fn_ty.abi != abi::Rust,
1564-
_ => false,
1565-
}
1566-
} else {
1567-
false
1568-
}
1569-
}
1570-
15711569
pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
15721570
let closure_doc = cdata.lookup_item(closure_id);
15731571
let closure_kind_doc = reader::get_doc(closure_doc, tag_items_closure_kind);

src/librustc/middle/reachable.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -235,16 +235,16 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
235235
fn propagate_node(&mut self, node: &ast_map::Node,
236236
search_item: ast::NodeId) {
237237
if !self.any_library {
238-
// If we are building an executable, then there's no need to flag
239-
// anything as external except for `extern fn` types. These
240-
// functions may still participate in some form of native interface,
241-
// but all other rust-only interfaces can be private (they will not
242-
// participate in linkage after this product is produced)
238+
// If we are building an executable, only explicitly extern
239+
// types need to be exported.
243240
if let ast_map::NodeItem(item) = *node {
244-
if let hir::ItemFn(_, _, _, abi, _, _) = item.node {
245-
if abi != abi::Rust {
246-
self.reachable_symbols.insert(search_item);
247-
}
241+
let reachable = if let hir::ItemFn(_, _, _, abi, _, _) = item.node {
242+
abi != abi::Rust
243+
} else {
244+
false
245+
};
246+
if reachable || attr::contains_extern_indicator(&item.attrs) {
247+
self.reachable_symbols.insert(search_item);
248248
}
249249
}
250250
} else {

src/librustc_trans/trans/base.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2875,8 +2875,7 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>,
28752875
sess.cstore.iter_crate_data(|cnum, _| {
28762876
let syms = csearch::get_reachable_ids(&sess.cstore, cnum);
28772877
reachable_symbols.extend(syms.into_iter().filter(|did| {
2878-
csearch::is_extern_fn(&sess.cstore, *did, shared_ccx.tcx()) ||
2879-
csearch::is_extern_static(&sess.cstore, *did)
2878+
csearch::is_extern_item(&sess.cstore, *did, shared_ccx.tcx())
28802879
}).map(|did| {
28812880
csearch::get_symbol(&sess.cstore, did)
28822881
}));

src/libsyntax/attr.rs

+9
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,15 @@ pub fn find_export_name_attr(diag: &SpanHandler, attrs: &[Attribute]) -> Option<
312312
})
313313
}
314314

315+
pub fn contains_extern_indicator(attrs: &[Attribute]) -> bool {
316+
contains_name(attrs, "no_mangle") ||
317+
contains_name(attrs, "export_name") ||
318+
first_attr_value_str_by_name(attrs, "linkage").map(|v| match &*v {
319+
"external" | "extern_weak" => true,
320+
_ => false,
321+
}).unwrap_or(false)
322+
}
323+
315324
#[derive(Copy, Clone, PartialEq)]
316325
pub enum InlineAttr {
317326
None,

0 commit comments

Comments
 (0)