From 28583f5e83b76960018cf623ad54e5a8ec80447c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Sep 2026 00:57:01 +0000 Subject: [PATCH 1/4] Add more test cases of type not found caused by derive macro --- .../derives/auxiliary/derive-no-generics.rs | 50 +++++++++++++ .../derive-macro-unsupported-type-params.rs | 15 ++++ ...erive-macro-unsupported-type-params.stderr | 73 ++++++++++++++++++- 3 files changed, 137 insertions(+), 1 deletion(-) diff --git a/tests/ui/derives/auxiliary/derive-no-generics.rs b/tests/ui/derives/auxiliary/derive-no-generics.rs index ea9a2e5b1c89a..66de6b8115071 100644 --- a/tests/ui/derives/auxiliary/derive-no-generics.rs +++ b/tests/ui/derives/auxiliary/derive-no-generics.rs @@ -32,3 +32,53 @@ pub fn derive(item: TokenStream) -> TokenStream { }; tokens } + +#[proc_macro_derive(B)] +pub fn derive_2(item: TokenStream) -> TokenStream { + let mut tokens = item.into_iter(); + let _enum = tokens.next(); + let name = tokens.next().unwrap(); + let _ = tokens.next().unwrap(); + let _ = tokens.next().unwrap(); + let _ = tokens.next().unwrap(); + let TokenTree::Group(group) = tokens.next().unwrap() else { panic!() }; + let mut group = group.stream().into_iter(); + let variant = group.next().unwrap(); + let TokenTree::Group(args) = group.next().unwrap() else { panic!() }; + let arg = args.stream().into_iter().next().unwrap(); + let tokens = quote! { + trait X {} + impl X for $name {} + + impl $name { + fn foo(&self) { + if let Self :: $variant(val) = self { + let _: T = val; + } + } + } + + }; + tokens +} + +#[proc_macro_derive(C)] +pub fn derive_3(item: TokenStream) -> TokenStream { + let mut tokens = item.into_iter(); + let _enum = tokens.next(); + let name = tokens.next().unwrap(); + let _ = tokens.next().unwrap(); + let _ = tokens.next().unwrap(); + let _ = tokens.next().unwrap(); + let TokenTree::Group(group) = tokens.next().unwrap() else { panic!() }; + let mut group = group.stream().into_iter(); + let variant = group.next().unwrap(); + let TokenTree::Group(args) = group.next().unwrap() else { panic!() }; + let arg = args.stream().into_iter().next().unwrap(); + let tokens = quote! { + fn foo(val: $name<$arg>) { + $name :: $variant($arg) = val; + } + }; + tokens +} \ No newline at end of file diff --git a/tests/ui/derives/derive-macro-unsupported-type-params.rs b/tests/ui/derives/derive-macro-unsupported-type-params.rs index d80064b4eb094..0ee096b5ad734 100644 --- a/tests/ui/derives/derive-macro-unsupported-type-params.rs +++ b/tests/ui/derives/derive-macro-unsupported-type-params.rs @@ -11,3 +11,18 @@ enum A { Variant(T), //~^ ERROR: cannot find type `T` in this scope } + +// Resolution error comes entirely from within the derive macro: +#[derive(B)] //~ ERROR: cannot find type `T` in this scope +enum B { + //~^ ERROR: missing generics for enum `B` + //~| ERROR: missing generics for enum `B` + Variant(T), +} + +#[derive(C)] +enum C { + Variant(T), + //~^ ERROR: cannot find value `T` in this scope + //~| ERROR: cannot find type `T` in this scope +} diff --git a/tests/ui/derives/derive-macro-unsupported-type-params.stderr b/tests/ui/derives/derive-macro-unsupported-type-params.stderr index e57490e79cc9f..0af20858f3d9c 100644 --- a/tests/ui/derives/derive-macro-unsupported-type-params.stderr +++ b/tests/ui/derives/derive-macro-unsupported-type-params.stderr @@ -4,6 +4,59 @@ error[E0425]: cannot find type `T` in this scope LL | Variant(T), | ^ not found in this scope +error[E0425]: cannot find type `T` in this scope + --> $DIR/derive-macro-unsupported-type-params.rs:16:10 + | +LL | #[derive(B)] + | ^ not found in this scope + | +note: similarly named enum `A` defined here + --> $DIR/derive-macro-unsupported-type-params.rs:8:1 + | +LL | enum A { + | ^^^^^^^^^ + = note: this error originates in the derive macro `B` (in Nightly builds, run with -Z macro-backtrace for more info) +help: an enum with a similar name exists + --> $DIR/auxiliary/derive-no-generics.rs:56:28 + | +LL - let _: T = val; +LL + let _: A = val; + | + +error[E0425]: cannot find type `T` in this scope + --> $DIR/derive-macro-unsupported-type-params.rs:25:13 + | +LL | Variant(T), + | ^ not found in this scope + | +note: similarly named enum `A` defined here + --> $DIR/derive-macro-unsupported-type-params.rs:8:1 + | +LL | enum A { + | ^^^^^^^^^ +help: an enum with a similar name exists + | +LL - Variant(T), +LL + Variant(A), + | +help: you might be missing a type parameter + --> $DIR/auxiliary/derive-no-generics.rs:79:15 + | +LL | fn foo(val: $name<$arg>) { + | +++ + +error[E0425]: cannot find value `T` in this scope + --> $DIR/derive-macro-unsupported-type-params.rs:25:13 + | +LL | Variant(T), + | ^ not found in this scope + | +help: you might be missing a const parameter + --> $DIR/auxiliary/derive-no-generics.rs:79:15 + | +LL | fn foo(val: $name<$arg>) { + | +++++++++++++++++++++ + error[E0107]: missing generics for enum `A` --> $DIR/derive-macro-unsupported-type-params.rs:8:6 | @@ -22,7 +75,25 @@ LL | enum A { | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error[E0107]: missing generics for enum `B` + --> $DIR/derive-macro-unsupported-type-params.rs:17:6 + | +LL | #[derive(B)] + | - this derive macro might not support items with generic parameters +LL | enum B { + | ^ + +error[E0107]: missing generics for enum `B` + --> $DIR/derive-macro-unsupported-type-params.rs:17:6 + | +LL | #[derive(B)] + | - this derive macro might not support items with generic parameters +LL | enum B { + | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0107, E0425. For more information about an error, try `rustc --explain E0107`. From c77999a146c62a1907af4f5da38a31c2d1aab10e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Sep 2026 01:00:43 +0000 Subject: [PATCH 2/4] On name not found in derive macro, point at the attribute ``` error[E0425]: cannot find type `T` in this scope --> $DIR/derive-macro-unsupported-type-params.rs:11:13 | LL | #[derive(A)] | - in this derive macro ... LL | Variant(T), | ^ not found in this scope ``` --- .../rustc_resolve/src/late/diagnostics.rs | 21 +++++++++++++++++++ ...erive-macro-unsupported-type-params.stderr | 9 ++++++++ .../tokenstream-ice-issue-149954.stderr | 5 +++-- .../issue-119493-type-error-ice.stderr | 2 ++ .../issue-119778-type-error-ice.stderr | 2 ++ tests/ui/traits/issue-50480.stderr | 4 ++++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ddde9982c0cae..a6002d86b5dbb 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -713,6 +713,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); self.suggest_range_struct_destructuring(&mut err, path, source); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); + self.detect_resolution_error_in_derive(&mut err, base_error.span); if let Some((span, label)) = base_error.span_label { err.span_label(span, label); @@ -1904,6 +1905,26 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + /// If the name resolution error occurs in an ident that has no span context, but the enclosing + /// item is within a derive macro, point at the derive, as the error can either be because of an + /// invalid derive macro *or* a non-existing item that will already have been reported through + /// the annotated item. + fn detect_resolution_error_in_derive(&self, err: &mut Diag<'_>, span: Span) { + if let Some(item) = self.diag_metadata.current_item + && !item.span.eq_ctxt(span) + && item.span.in_derive_expansion() + { + // `item` comes from a `#[derive()]`, but the error `span` doesn't, which means that the + // derive is referencing a name coming from the annotated item. If the item exists, then + // the derive macro itself is buggy. If the item exists, then an error will have already + // been emitted while evaluating the annotated item itself, but we can't silence this + // one because one *can* write a derive macro referencing a non-existing item that is + // part of the expansion, *not* from the user's code. Because of that, at least for now, + // we just add context to the current error. + err.span_label(item.span, "in this derive macro"); + } + } + fn explain_functions_in_pattern( &self, err: &mut Diag<'_>, diff --git a/tests/ui/derives/derive-macro-unsupported-type-params.stderr b/tests/ui/derives/derive-macro-unsupported-type-params.stderr index 0af20858f3d9c..afe2dadbb47b4 100644 --- a/tests/ui/derives/derive-macro-unsupported-type-params.stderr +++ b/tests/ui/derives/derive-macro-unsupported-type-params.stderr @@ -1,6 +1,9 @@ error[E0425]: cannot find type `T` in this scope --> $DIR/derive-macro-unsupported-type-params.rs:11:13 | +LL | #[derive(A)] + | - in this derive macro +... LL | Variant(T), | ^ not found in this scope @@ -26,6 +29,9 @@ LL + let _: A = val; error[E0425]: cannot find type `T` in this scope --> $DIR/derive-macro-unsupported-type-params.rs:25:13 | +LL | #[derive(C)] + | - in this derive macro +LL | enum C { LL | Variant(T), | ^ not found in this scope | @@ -48,6 +54,9 @@ LL | fn foo(val: $name<$arg>) { error[E0425]: cannot find value `T` in this scope --> $DIR/derive-macro-unsupported-type-params.rs:25:13 | +LL | #[derive(C)] + | - in this derive macro +LL | enum C { LL | Variant(T), | ^ not found in this scope | diff --git a/tests/ui/macros/tokenstream-ice-issue-149954.stderr b/tests/ui/macros/tokenstream-ice-issue-149954.stderr index b1a589e76c323..45377188bff9b 100644 --- a/tests/ui/macros/tokenstream-ice-issue-149954.stderr +++ b/tests/ui/macros/tokenstream-ice-issue-149954.stderr @@ -82,13 +82,14 @@ LL | A: A<{ struct A> ; enum A } error[E0404]: expected trait, found struct `A` --> $DIR/tokenstream-ice-issue-149954.rs:10:16 | +LL | #[derive(Debug)] + | ----- in this derive macro +... LL | A: A<{ struct A> ; enum A } | ________________^ ... | LL | | >; | |_________^ not a trait - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0404]: expected trait, found type parameter `A` --> $DIR/tokenstream-ice-issue-149954.rs:10:32 diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr index 06e13aa2ea01d..0c35a6d9d04e4 100644 --- a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr @@ -7,6 +7,8 @@ LL | struct Foo(NonExistent); error[E0425]: cannot find type `NonExistent` in this scope --> $DIR/issue-119493-type-error-ice.rs:5:16 | +LL | #[derive(Copy, Clone)] + | ----- in this derive macro LL | struct Foo(NonExistent); | ^^^^^^^^^^^ not found in this scope | diff --git a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr index 7da384d613efb..09a7dc7d4aaff 100644 --- a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr @@ -12,6 +12,8 @@ LL | struct Foo([u8; S]); error[E0425]: cannot find value `S` in this scope --> $DIR/issue-119778-type-error-ice.rs:5:21 | +LL | #[derive(Copy, Clone)] + | ----- in this derive macro LL | struct Foo([u8; S]); | ^ not found in this scope | diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index e7a93dc52579e..1eacd352ca8b2 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -18,6 +18,8 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); error[E0425]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:2:12 | +LL | #[derive(Clone, Copy)] + | ----- in this derive macro LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^ not found in this scope | @@ -29,6 +31,8 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); error[E0425]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:2:15 | +LL | #[derive(Clone, Copy)] + | ----- in this derive macro LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope | From 2ac39939fa0499d52ee3449506dc84c21b685c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Sep 2026 01:02:40 +0000 Subject: [PATCH 3/4] Do not provide useless context on resolve error in derive macro --- compiler/rustc_resolve/src/diagnostics/impls.rs | 3 +++ .../derive-macro-unsupported-type-params.stderr | 11 ----------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index 744e7c22265ea..06c2742c489be 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -2314,6 +2314,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // | ^ return; } + if span.in_derive_expansion() { + return; + } let span = self.tcx.sess.source_map().guess_head_span(def_span); let candidate_descr = suggestion.res.descr(); let candidate = suggestion.candidate; diff --git a/tests/ui/derives/derive-macro-unsupported-type-params.stderr b/tests/ui/derives/derive-macro-unsupported-type-params.stderr index afe2dadbb47b4..a38ea2ea98fea 100644 --- a/tests/ui/derives/derive-macro-unsupported-type-params.stderr +++ b/tests/ui/derives/derive-macro-unsupported-type-params.stderr @@ -13,18 +13,7 @@ error[E0425]: cannot find type `T` in this scope LL | #[derive(B)] | ^ not found in this scope | -note: similarly named enum `A` defined here - --> $DIR/derive-macro-unsupported-type-params.rs:8:1 - | -LL | enum A { - | ^^^^^^^^^ = note: this error originates in the derive macro `B` (in Nightly builds, run with -Z macro-backtrace for more info) -help: an enum with a similar name exists - --> $DIR/auxiliary/derive-no-generics.rs:56:28 - | -LL - let _: T = val; -LL + let _: A = val; - | error[E0425]: cannot find type `T` in this scope --> $DIR/derive-macro-unsupported-type-params.rs:25:13 From 746e15573e0b226b7c80b8b7369ccf9b60950706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Sep 2026 01:05:33 +0000 Subject: [PATCH 4/4] Do not suggest adding params to item when error comes from derive macro --- compiler/rustc_resolve/src/late/diagnostics.rs | 3 +++ tests/ui/derives/auxiliary/derive-no-generics.rs | 2 +- .../derive-macro-unsupported-type-params.stderr | 11 ----------- .../usefulness/issue-119493-type-error-ice.stderr | 5 ----- .../usefulness/issue-119778-type-error-ice.stderr | 5 ----- tests/ui/traits/issue-50480.stderr | 10 ---------- 6 files changed, 4 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a6002d86b5dbb..c3421a735ddae 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3702,6 +3702,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { (Some(Item { kind: ItemKind::Fn(fn_), .. }), _, _) if fn_.ident.name == sym::main => { // Ignore `fn main()` as we don't want to suggest `fn main()` } + (Some(Item { span, .. }), _, _) if span.in_derive_expansion() => { + return (None, None); + } ( Some(Item { kind: diff --git a/tests/ui/derives/auxiliary/derive-no-generics.rs b/tests/ui/derives/auxiliary/derive-no-generics.rs index 66de6b8115071..affa9ac44d616 100644 --- a/tests/ui/derives/auxiliary/derive-no-generics.rs +++ b/tests/ui/derives/auxiliary/derive-no-generics.rs @@ -81,4 +81,4 @@ pub fn derive_3(item: TokenStream) -> TokenStream { } }; tokens -} \ No newline at end of file +} diff --git a/tests/ui/derives/derive-macro-unsupported-type-params.stderr b/tests/ui/derives/derive-macro-unsupported-type-params.stderr index a38ea2ea98fea..28f844f6d39ac 100644 --- a/tests/ui/derives/derive-macro-unsupported-type-params.stderr +++ b/tests/ui/derives/derive-macro-unsupported-type-params.stderr @@ -34,11 +34,6 @@ help: an enum with a similar name exists LL - Variant(T), LL + Variant(A), | -help: you might be missing a type parameter - --> $DIR/auxiliary/derive-no-generics.rs:79:15 - | -LL | fn foo(val: $name<$arg>) { - | +++ error[E0425]: cannot find value `T` in this scope --> $DIR/derive-macro-unsupported-type-params.rs:25:13 @@ -48,12 +43,6 @@ LL | #[derive(C)] LL | enum C { LL | Variant(T), | ^ not found in this scope - | -help: you might be missing a const parameter - --> $DIR/auxiliary/derive-no-generics.rs:79:15 - | -LL | fn foo(val: $name<$arg>) { - | +++++++++++++++++++++ error[E0107]: missing generics for enum `A` --> $DIR/derive-macro-unsupported-type-params.rs:8:6 diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr index 0c35a6d9d04e4..b9def607e0b46 100644 --- a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr @@ -11,11 +11,6 @@ LL | #[derive(Copy, Clone)] | ----- in this derive macro LL | struct Foo(NonExistent); | ^^^^^^^^^^^ not found in this scope - | -help: you might be missing a type parameter - | -LL | struct Foo(NonExistent); - | +++++++++++++ error[E0658]: `impl Trait` in type aliases is unstable --> $DIR/issue-119493-type-error-ice.rs:9:14 diff --git a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr index 09a7dc7d4aaff..9bcf4a9ce8d42 100644 --- a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr @@ -16,11 +16,6 @@ LL | #[derive(Copy, Clone)] | ----- in this derive macro LL | struct Foo([u8; S]); | ^ not found in this scope - | -help: you might be missing a const parameter - | -LL | struct Foo([u8; S]); - | +++++++++++++++++++++ error[E0658]: `impl Trait` in type aliases is unstable --> $DIR/issue-119778-type-error-ice.rs:9:14 diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 1eacd352ca8b2..a8b6ff4d0d924 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -22,11 +22,6 @@ LL | #[derive(Clone, Copy)] | ----- in this derive macro LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^ not found in this scope - | -help: you might be missing a type parameter - | -LL | struct Foo(N, NotDefined, ::Item, Vec, String); - | +++ error[E0425]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:2:15 @@ -35,11 +30,6 @@ LL | #[derive(Clone, Copy)] | ----- in this derive macro LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope - | -help: you might be missing a type parameter - | -LL | struct Foo(N, NotDefined, ::Item, Vec, String); - | ++++++++++++ error[E0425]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:12:18