fix up diagnostics referring to the right items

This commit is contained in:
Jana Dönszelmann 2026-01-08 16:43:24 +01:00
parent e3cff18370
commit 5ddda0c37b
No known key found for this signature in database
11 changed files with 29 additions and 33 deletions

View file

@ -2117,10 +2117,9 @@ pub struct MacroDef {
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub struct EiiExternTarget {
/// path to the extern item we're targetting
/// path to the extern item we're targeting
pub extern_item_path: Path,
pub impl_unsafe: bool,
pub span: Span,
}
#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]

View file

@ -137,12 +137,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_eii_extern_target(
&mut self,
id: NodeId,
EiiExternTarget { extern_item_path, impl_unsafe, span }: &EiiExternTarget,
eii_name: Ident,
EiiExternTarget { extern_item_path, impl_unsafe }: &EiiExternTarget,
) -> Option<EiiDecl> {
self.lower_path_simple_eii(id, extern_item_path).map(|did| EiiDecl {
eii_extern_target: did,
impl_unsafe: *impl_unsafe,
span: self.lower_span(*span),
name: eii_name,
})
}
@ -159,13 +160,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
}: &EiiImpl,
) -> hir::attrs::EiiImpl {
let resolution = if let Some(target) = known_eii_macro_resolution
&& let Some(decl) = self.lower_eii_extern_target(*node_id, target)
{
EiiImplResolution::Known(
decl,
&& let Some(decl) = self.lower_eii_extern_target(
*node_id,
// the expect is ok here since we always generate this path in the eii macro.
eii_macro_path.segments.last().expect("at least one segment").ident.name,
)
eii_macro_path.segments.last().expect("at least one segment").ident,
target,
) {
EiiImplResolution::Known(decl)
} else if let Some(macro_did) = self.lower_path_simple_eii(*node_id, eii_macro_path) {
EiiImplResolution::Macro(macro_did)
} else {
@ -195,8 +196,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(),
))]
}
ItemKind::MacroDef(_, MacroDef { eii_extern_target: Some(target), .. }) => self
.lower_eii_extern_target(id, target)
ItemKind::MacroDef(name, MacroDef { eii_extern_target: Some(target), .. }) => self
.lower_eii_extern_target(id, *name, target)
.map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(decl))])
.unwrap_or_default(),

View file

@ -103,8 +103,6 @@ fn eii_(
// span of the declaring item without attributes
let item_span = func.sig.span;
// span of the eii attribute and the item below it, i.e. the full declaration
let decl_span = eii_attr_span.to(item_span);
let foreign_item_name = func.ident;
let mut return_items = Vec::new();
@ -134,7 +132,6 @@ fn eii_(
macro_name,
foreign_item_name,
impl_unsafe,
decl_span,
)));
return_items.into_iter().map(wrap_item).collect()
@ -213,7 +210,6 @@ fn generate_default_impl(
known_eii_macro_resolution: Some(ast::EiiExternTarget {
extern_item_path: ast::Path::from_ident(foreign_item_name),
impl_unsafe,
span: item_span,
}),
});
@ -359,7 +355,6 @@ fn generate_attribute_macro_to_implement(
macro_name: Ident,
foreign_item_name: Ident,
impl_unsafe: bool,
decl_span: Span,
) -> ast::Item {
let mut macro_attrs = ThinVec::new();
@ -401,7 +396,6 @@ fn generate_attribute_macro_to_implement(
eii_extern_target: Some(ast::EiiExternTarget {
extern_item_path: ast::Path::from_ident(foreign_item_name),
impl_unsafe,
span: decl_span,
}),
},
),
@ -458,7 +452,7 @@ pub(crate) fn eii_extern_target(
false
};
d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe, span });
d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe });
// Return the original item and the new methods.
vec![item]

View file

@ -301,7 +301,7 @@ fn process_builtin_attrs(
};
extern_item
}
EiiImplResolution::Known(decl, _) => decl.eii_extern_target,
EiiImplResolution::Known(decl) => decl.eii_extern_target,
EiiImplResolution::Error(_eg) => continue,
};

View file

@ -27,7 +27,7 @@ pub enum EiiImplResolution {
Macro(DefId),
/// Sometimes though, we already know statically and can skip some name resolution.
/// Stored together with the eii's name for diagnostics.
Known(EiiDecl, Symbol),
Known(EiiDecl),
/// For when resolution failed, but we want to continue compilation
Error(ErrorGuaranteed),
}
@ -46,7 +46,7 @@ pub struct EiiDecl {
pub eii_extern_target: DefId,
/// whether or not it is unsafe to implement this EII
pub impl_unsafe: bool,
pub span: Span,
pub name: Ident,
}
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)]

View file

@ -1213,7 +1213,7 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) {
continue;
}
}
EiiImplResolution::Known(decl, name) => (decl.eii_extern_target, *name),
EiiImplResolution::Known(decl) => (decl.eii_extern_target, decl.name.name),
EiiImplResolution::Error(_eg) => continue,
};

View file

@ -40,7 +40,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap
};
decl
}
EiiImplResolution::Known(decl, _) => decl,
EiiImplResolution::Known(decl) => decl,
EiiImplResolution::Error(_eg) => continue,
};

View file

@ -761,7 +761,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
for i in impls {
let name = match i.resolution {
EiiImplResolution::Macro(def_id) => self.tcx.item_name(def_id),
EiiImplResolution::Known(_, name) => name,
EiiImplResolution::Known(decl) => decl.name.name,
EiiImplResolution::Error(_eg) => continue,
};
self.dcx().emit_err(errors::EiiWithTrackCaller {

View file

@ -80,6 +80,8 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, ():
}
}
println!("{eiis:#?}");
// now we have all eiis! For each of them, choose one we want to actually generate.
for (foreign_item, FoundEii { decl, decl_crate, impls }) in eiis {
let mut default_impls = Vec::new();
@ -97,7 +99,7 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, ():
// is instantly an error.
if explicit_impls.len() > 1 {
tcx.dcx().emit_err(DuplicateEiiImpls {
name: tcx.item_name(foreign_item),
name: decl.name.name,
first_span: tcx.def_span(explicit_impls[0].0),
first_crate: tcx.crate_name(explicit_impls[0].1),
second_span: tcx.def_span(explicit_impls[1].0),
@ -140,8 +142,8 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, ():
current_crate_name: tcx.crate_name(LOCAL_CRATE),
decl_crate_name: tcx.crate_name(decl_crate),
// FIXME: shouldn't call `item_name`
name: tcx.item_name(foreign_item),
span: decl.span,
name: decl.name.name,
span: decl.name.span,
help: (),
});

View file

@ -2929,7 +2929,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.parent_scope.macro_rules = self.r.macro_rules_scopes[&def_id];
}
if let Some(EiiExternTarget { extern_item_path, impl_unsafe: _, span: _ }) =
if let Some(EiiExternTarget { extern_item_path, impl_unsafe: _ }) =
&macro_def.eii_extern_target
{
self.smart_resolve_path(

View file

@ -17,18 +17,18 @@ LL | fn decl1(x: u64);
| ^^^^^^^^^^^^^^^^^
error: `#[eii2]` required, but not found
--> $DIR/auxiliary/codegen3.rs:9:1
--> $DIR/auxiliary/codegen3.rs:9:7
|
LL | #[eii(eii2)]
| ^^^^^^^^^^^^ expected because `#[eii2]` was declared here in crate `codegen3`
| ^^^^ expected because `#[eii2]` was declared here in crate `codegen3`
|
= help: expected at least one implementation in crate `privacy2` or any of its dependencies
error: `#[eii3]` required, but not found
--> $DIR/auxiliary/codegen3.rs:13:5
--> $DIR/auxiliary/codegen3.rs:13:11
|
LL | #[eii(eii3)]
| ^^^^^^^^^^^^ expected because `#[eii3]` was declared here in crate `codegen3`
| ^^^^ expected because `#[eii3]` was declared here in crate `codegen3`
|
= help: expected at least one implementation in crate `privacy2` or any of its dependencies