currently_processing_generics: bool,
/// The current enclosing function (used for better errors).
- current_function: Option<Span>,
+ current_function: Option<(FnKind<'ast>, Span)>,
/// A list of labels as of yet unused. Labels will be removed from this map when
/// they are used (in a `break` or `continue` statement)
FnKind::Fn(FnCtxt::Free | FnCtxt::Foreign, ..) => FnItemRibKind,
FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind,
};
- let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));
+ let previous_value =
+ replace(&mut self.diagnostic_metadata.current_function, Some((fn_kind, sp)));
debug!("(resolving function) entering function");
let declaration = fn_kind.decl();
_ => "`self` value is a keyword only available in methods with a `self` parameter"
.to_string(),
});
- if let Some(span) = &self.diagnostic_metadata.current_function {
- err.span_label(*span, "this function doesn't have a `self` parameter");
+ if let Some((fn_kind, span)) = &self.diagnostic_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).map(|p| p.is_self()).unwrap_or(false) {
+ err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
+ } else {
+ err.span_label(*span, "this function doesn't have a `self` parameter");
+ }
}
return (err, Vec::new());
}
--- /dev/null
+// Regression test for issue #66898
+// Tests that we don't emit a nonsensical error message
+// when a macro invocation tries to access `self` from a function
+// that has a 'self' parameter
+
+pub struct Foo;
+
+macro_rules! call_bar {
+ () => {
+ self.bar(); //~ ERROR expected value
+ }
+}
+
+impl Foo {
+ pub fn foo(&self) {
+ call_bar!();
+ }
+
+ pub fn bar(&self) {
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0424]: expected value, found module `self`
+ --> $DIR/missing-self-diag.rs:10:9
+ |
+LL | self.bar();
+ | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+...
+LL | / pub fn foo(&self) {
+LL | | call_bar!();
+ | | ------------ in this macro invocation
+LL | | }
+ | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0424`.