Skip to content

Commit 65607fb

Browse files
authored
Rollup merge of #72308 - Aaron1011:fix/hygiene-error-message, r=matthewjasper
Emit a better diagnostic when function actually has a 'self' parameter Fixes #66898 When we are unable to resolve a reference to `self`, we current assume that the containing function doesn't have a `self` parameter, and emit an error message accordingly. However, if the reference to `self` was created by a macro invocation, then resolution will correctly fail, due to hygiene. In this case, we don't want to tell the user that the containing fuction doesn't have a 'self' paramter if it actually has one. This PR checks for the precense of a 'self' parameter, and adjusts the error message we emit accordingly. TODO: The exact error message we emit could probably be improved. Should we explicitly mention hygiene?
2 parents d5250c1 + b684448 commit 65607fb

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

src/librustc_resolve/late.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ struct DiagnosticMetadata<'ast> {
347347
currently_processing_generics: bool,
348348

349349
/// The current enclosing function (used for better errors).
350-
current_function: Option<Span>,
350+
current_function: Option<(FnKind<'ast>, Span)>,
351351

352352
/// A list of labels as of yet unused. Labels will be removed from this map when
353353
/// they are used (in a `break` or `continue` statement)
@@ -466,7 +466,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
466466
FnKind::Fn(FnCtxt::Free | FnCtxt::Foreign, ..) => FnItemRibKind,
467467
FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind,
468468
};
469-
let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));
469+
let previous_value =
470+
replace(&mut self.diagnostic_metadata.current_function, Some((fn_kind, sp)));
470471
debug!("(resolving function) entering function");
471472
let declaration = fn_kind.decl();
472473

src/librustc_resolve/late/diagnostics.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,15 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
195195
_ => "`self` value is a keyword only available in methods with a `self` parameter"
196196
.to_string(),
197197
});
198-
if let Some(span) = &self.diagnostic_metadata.current_function {
199-
err.span_label(*span, "this function doesn't have a `self` parameter");
198+
if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function {
199+
// The current function has a `self' parameter, but we were unable to resolve
200+
// a reference to `self`. This can only happen if the `self` identifier we
201+
// are resolving came from a different hygiene context.
202+
if fn_kind.decl().inputs.get(0).map(|p| p.is_self()).unwrap_or(false) {
203+
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
204+
} else {
205+
err.span_label(*span, "this function doesn't have a `self` parameter");
206+
}
200207
}
201208
return (err, Vec::new());
202209
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Regression test for issue #66898
2+
// Tests that we don't emit a nonsensical error message
3+
// when a macro invocation tries to access `self` from a function
4+
// that has a 'self' parameter
5+
6+
pub struct Foo;
7+
8+
macro_rules! call_bar {
9+
() => {
10+
self.bar(); //~ ERROR expected value
11+
}
12+
}
13+
14+
impl Foo {
15+
pub fn foo(&self) {
16+
call_bar!();
17+
}
18+
19+
pub fn bar(&self) {
20+
}
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0424]: expected value, found module `self`
2+
--> $DIR/missing-self-diag.rs:10:9
3+
|
4+
LL | self.bar();
5+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
6+
...
7+
LL | / pub fn foo(&self) {
8+
LL | | call_bar!();
9+
| | ------------ in this macro invocation
10+
LL | | }
11+
| |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
12+
|
13+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0424`.

0 commit comments

Comments
 (0)