Skip to content

Commit 7a9b552

Browse files
committed
Auto merge of #80009 - jumbatm:issue79581-overeager-clashing-extern-decl, r=alexcrichton
Use tcx.symbol_name when determining clashing extern declarations. Fixes #79581. r? `@alexcrichton`
2 parents 704e47f + 4b740ac commit 7a9b552

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

compiler/rustc_lint/src/builtin.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use rustc_index::vec::Idx;
4343
use rustc_middle::lint::LintDiagnosticBuilder;
4444
use rustc_middle::ty::print::with_no_trimmed_paths;
4545
use rustc_middle::ty::subst::{GenericArgKind, Subst};
46+
use rustc_middle::ty::Instance;
4647
use rustc_middle::ty::{self, layout::LayoutError, Ty, TyCtxt};
4748
use rustc_session::Session;
4849
use rustc_span::edition::Edition;
@@ -2595,7 +2596,12 @@ declare_lint! {
25952596
}
25962597

25972598
pub struct ClashingExternDeclarations {
2598-
seen_decls: FxHashMap<Symbol, HirId>,
2599+
/// Map of function symbol name to the first-seen hir id for that symbol name.. If seen_decls
2600+
/// contains an entry for key K, it means a symbol with name K has been seen by this lint and
2601+
/// the symbol should be reported as a clashing declaration.
2602+
// FIXME: Technically, we could just store a &'tcx str here without issue; however, the
2603+
// `impl_lint_pass` macro doesn't currently support lints parametric over a lifetime.
2604+
seen_decls: FxHashMap<String, HirId>,
25992605
}
26002606

26012607
/// Differentiate between whether the name for an extern decl came from the link_name attribute or
@@ -2626,16 +2632,17 @@ impl ClashingExternDeclarations {
26262632
fn insert(&mut self, tcx: TyCtxt<'_>, fi: &hir::ForeignItem<'_>) -> Option<HirId> {
26272633
let hid = fi.hir_id;
26282634

2629-
let name =
2630-
&tcx.codegen_fn_attrs(tcx.hir().local_def_id(hid)).link_name.unwrap_or(fi.ident.name);
2631-
2632-
if self.seen_decls.contains_key(name) {
2635+
let local_did = tcx.hir().local_def_id(fi.hir_id);
2636+
let did = local_did.to_def_id();
2637+
let instance = Instance::new(did, ty::List::identity_for_item(tcx, did));
2638+
let name = tcx.symbol_name(instance).name;
2639+
if let Some(&hir_id) = self.seen_decls.get(name) {
26332640
// Avoid updating the map with the new entry when we do find a collision. We want to
26342641
// make sure we're always pointing to the first definition as the previous declaration.
26352642
// This lets us avoid emitting "knock-on" diagnostics.
2636-
Some(*self.seen_decls.get(name).unwrap())
2643+
Some(hir_id)
26372644
} else {
2638-
self.seen_decls.insert(*name, hid)
2645+
self.seen_decls.insert(name.to_owned(), hid)
26392646
}
26402647
}
26412648

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
#![crate_type = "lib"]
3+
4+
#[cfg(target_arch = "wasm32")]
5+
mod wasm_non_clash {
6+
mod a {
7+
#[link(wasm_import_module = "a")]
8+
extern "C" {
9+
pub fn foo();
10+
}
11+
}
12+
13+
mod b {
14+
#[link(wasm_import_module = "b")]
15+
extern "C" {
16+
pub fn foo() -> usize;
17+
// #79581: These declarations shouldn't clash because foreign fn names are mangled
18+
// on wasm32.
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)