Add associated functions that have custom linkage to reachable_set
This commit is contained in:
parent
eb2226b1f1
commit
c84beefd83
3 changed files with 53 additions and 13 deletions
|
@ -211,13 +211,15 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||||
if !self.any_library {
|
if !self.any_library {
|
||||||
// If we are building an executable, only explicitly extern
|
// If we are building an executable, only explicitly extern
|
||||||
// types need to be exported.
|
// types need to be exported.
|
||||||
if let Node::Item(item) = *node {
|
if let Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), def_id, .. })
|
||||||
let reachable = if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
|
| Node::ImplItem(hir::ImplItem {
|
||||||
sig.header.abi != Abi::Rust
|
kind: hir::ImplItemKind::Fn(sig, ..),
|
||||||
} else {
|
def_id,
|
||||||
false
|
..
|
||||||
};
|
}) = *node
|
||||||
let codegen_attrs = self.tcx.codegen_fn_attrs(item.def_id);
|
{
|
||||||
|
let reachable = sig.header.abi != Abi::Rust;
|
||||||
|
let codegen_attrs = self.tcx.codegen_fn_attrs(*def_id);
|
||||||
let is_extern = codegen_attrs.contains_extern_indicator();
|
let is_extern = codegen_attrs.contains_extern_indicator();
|
||||||
let std_internal =
|
let std_internal =
|
||||||
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
|
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
|
||||||
|
@ -335,17 +337,23 @@ struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
||||||
worklist: &'a mut Vec<LocalDefId>,
|
worklist: &'a mut Vec<LocalDefId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
impl CollectPrivateImplItemsVisitor<'_, '_> {
|
||||||
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
fn push_to_worklist_if_has_custom_linkage(&mut self, def_id: LocalDefId) {
|
||||||
// Anything which has custom linkage gets thrown on the worklist no
|
// Anything which has custom linkage gets thrown on the worklist no
|
||||||
// matter where it is in the crate, along with "special std symbols"
|
// matter where it is in the crate, along with "special std symbols"
|
||||||
// which are currently akin to allocator symbols.
|
// which are currently akin to allocator symbols.
|
||||||
let codegen_attrs = self.tcx.codegen_fn_attrs(item.def_id);
|
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
|
||||||
if codegen_attrs.contains_extern_indicator()
|
if codegen_attrs.contains_extern_indicator()
|
||||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
||||||
{
|
{
|
||||||
self.worklist.push(item.def_id);
|
self.worklist.push(def_id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
||||||
|
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
||||||
|
self.push_to_worklist_if_has_custom_linkage(item.def_id);
|
||||||
|
|
||||||
// We need only trait impls here, not inherent impls, and only non-exported ones
|
// We need only trait impls here, not inherent impls, and only non-exported ones
|
||||||
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
|
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
|
||||||
|
@ -375,8 +383,8 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
|
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {
|
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
|
||||||
// processed in visit_item above
|
self.push_to_worklist_if_has_custom_linkage(impl_item.def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {
|
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {
|
||||||
|
|
10
src/test/ui/auxiliary/no-mangle-associated-fn.rs
Normal file
10
src/test/ui/auxiliary/no-mangle-associated-fn.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
struct Bar;
|
||||||
|
|
||||||
|
impl Bar {
|
||||||
|
#[no_mangle]
|
||||||
|
fn bar() -> u8 {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
}
|
22
src/test/ui/no-mangle-associated-fn.rs
Normal file
22
src/test/ui/no-mangle-associated-fn.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// aux-build: no-mangle-associated-fn.rs
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
extern crate no_mangle_associated_fn;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
#[no_mangle]
|
||||||
|
fn foo() -> u8 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
extern "Rust" {
|
||||||
|
fn foo() -> u8;
|
||||||
|
fn bar() -> u8;
|
||||||
|
}
|
||||||
|
assert_eq!(unsafe { foo() }, 1);
|
||||||
|
assert_eq!(unsafe { bar() }, 2);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue