delegation: Fix hygiene for self
And fix diagnostics for `self` from a macro.
This commit is contained in:
parent
f8e5660532
commit
cbc3bdbe01
5 changed files with 80 additions and 21 deletions
|
@ -3281,17 +3281,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
}
|
||||
self.visit_path(&delegation.path, delegation.id);
|
||||
if let Some(body) = &delegation.body {
|
||||
// `PatBoundCtx` is not necessary in this context
|
||||
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
|
||||
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
|
||||
// `PatBoundCtx` is not necessary in this context
|
||||
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
|
||||
|
||||
let span = delegation.path.segments.last().unwrap().ident.span;
|
||||
self.fresh_binding(
|
||||
Ident::new(kw::SelfLower, span),
|
||||
delegation.id,
|
||||
PatternSource::FnParam,
|
||||
&mut bindings,
|
||||
);
|
||||
self.visit_block(body);
|
||||
let span = delegation.path.segments.last().unwrap().ident.span;
|
||||
this.fresh_binding(
|
||||
Ident::new(kw::SelfLower, span),
|
||||
delegation.id,
|
||||
PatternSource::FnParam,
|
||||
&mut bindings,
|
||||
);
|
||||
this.visit_block(body);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1021,12 +1021,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
},
|
||||
);
|
||||
let is_assoc_fn = self.self_type_is_available();
|
||||
let self_from_macro = "a `self` parameter, but a macro invocation can only \
|
||||
access identifiers it receives from parameters";
|
||||
if let Some((fn_kind, span)) = &self.diag_metadata.current_function {
|
||||
// The current function has a `self` parameter, but we were unable to resolve
|
||||
// a reference to `self`. This can only happen if the `self` identifier we
|
||||
// are resolving came from a different hygiene context.
|
||||
if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
|
||||
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
|
||||
err.span_label(*span, format!("this function has {self_from_macro}"));
|
||||
} else {
|
||||
let doesnt = if is_assoc_fn {
|
||||
let (span, sugg) = fn_kind
|
||||
|
@ -1068,14 +1070,18 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
}
|
||||
}
|
||||
} else if let Some(item_kind) = self.diag_metadata.current_item {
|
||||
err.span_label(
|
||||
item_kind.ident.span,
|
||||
format!(
|
||||
"`self` not allowed in {} {}",
|
||||
item_kind.kind.article(),
|
||||
item_kind.kind.descr()
|
||||
),
|
||||
);
|
||||
if matches!(item_kind.kind, ItemKind::Delegation(..)) {
|
||||
err.span_label(item_kind.span, format!("delegation supports {self_from_macro}"));
|
||||
} else {
|
||||
err.span_label(
|
||||
item_kind.ident.span,
|
||||
format!(
|
||||
"`self` not allowed in {} {}",
|
||||
item_kind.kind.article(),
|
||||
item_kind.kind.descr()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue