diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 208fa238f80..87a04820f7e 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -449,7 +449,8 @@ fn infer_placeholder_type<'tcx>( }) .unwrap_or_else(|| { let mut visitor = HirPlaceholderCollector::default(); - if let Some(ty) = tcx.hir_node_by_def_id(def_id).ty() { + let node = tcx.hir_node_by_def_id(def_id); + if let Some(ty) = node.ty() { visitor.visit_ty(ty); } // If we have just one span, let's try to steal a const `_` feature error. @@ -465,7 +466,15 @@ fn infer_placeholder_type<'tcx>( } let mut diag = bad_placeholder(cx, visitor.spans, kind); - if !ty.references_error() { + // HACK(#69396): Stashing and stealing diagnostics does not interact + // well with macros which may delay more than one diagnostic on the + // same span. If this happens, we will fall through to this arm, so + // we need to suppress the suggestion since it's invalid. Ideally we + // would suppress the duplicated error too, but that's really hard. + if span.is_empty() && span.from_expansion() { + // An approximately better primary message + no suggestion... + diag.primary_message("missing type for item"); + } else if !ty.references_error() { if let Some(ty) = ty.make_suggestable(tcx, false, None) { diag.span_suggestion_verbose( span, diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs index 45a30857413..c200a1fd0b4 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs @@ -4,7 +4,7 @@ macro_rules! suite { const A = "A".$fn(); //~^ ERROR the name `A` is defined multiple times //~| ERROR missing type for `const` item - //~| ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~| ERROR missing type for item )* } } diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr index ef49a0bc2b5..4342d7d88f5 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr @@ -27,7 +27,7 @@ LL | | } | = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: missing type for item --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 | LL | const A = "A".$fn(); @@ -40,10 +40,6 @@ LL | | } | |_- in this macro invocation | = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -help: replace this with a fully-specified type - | -LL | const Abool = "A".$fn(); - | ++++ error: aborting due to 3 previous errors