Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, Diagnostic, MultiSpan, pluralize};
use rustc_hir as hir;
use rustc_middle::ty::{self as ty, AssocItem, AssocItems, TyCtxt};
use rustc_span::def_id::DefId;
use rustc_span::def_id::{DefId, LocalDefId};
use tracing::debug;

/// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
Expand All @@ -30,6 +30,9 @@ pub(crate) struct WrongNumberOfGenericArgs<'a, 'tcx> {

/// DefId of the generic type
pub(crate) def_id: DefId,

/// DefId of the type that contains the generic
pub(crate) cx_def_id: LocalDefId,
}

// Provides information about the kind of arguments that were provided for
Expand Down Expand Up @@ -94,6 +97,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
params_offset: usize,
gen_args: &'a hir::GenericArgs<'a>,
def_id: DefId,
cx_def_id: LocalDefId,
) -> Self {
let angle_brackets = if gen_args.span_ext().is_none() {
if gen_args.is_empty() { AngleBrackets::Missing } else { AngleBrackets::Implied }
Expand All @@ -110,6 +114,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
params_offset,
gen_args,
def_id,
cx_def_id,
}
}

Expand Down Expand Up @@ -1163,10 +1168,20 @@ impl<'a> Diagnostic<'a> for WrongNumberOfGenericArgs<'_, '_> {
err.code(E0107);
err.span(self.path_segment.ident.span);

self.notify(&mut err);
self.suggest(&mut err);
self.show_definition(&mut err);
self.note_synth_provided(&mut err);
let cx_span = self.tcx.def_span(self.cx_def_id);
if cx_span.in_derive_expansion() {
// Very likely this is a botched `derive` which passes the iten name straight
// through, but doesn't support type parameters.
err.span_label(
cx_span,
"this derive macro might not support items with generic parameters",
);
} else {
self.notify(&mut err);
self.suggest(&mut err);
self.show_definition(&mut err);
self.note_synth_provided(&mut err);
}
Comment thread
petrochenkov marked this conversation as resolved.

err
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ pub(crate) fn check_generic_arg_count(
has_self as usize,
gen_args,
def_id,
cx.item_def_id(),
));

Err(reported)
Expand Down Expand Up @@ -617,6 +618,7 @@ pub(crate) fn check_generic_arg_count(
params_offset,
gen_args,
def_id,
cx.item_def_id(),
))
.emit_err_unless_delay(all_params_are_binded || has_invalid_bound)
});
Expand Down
34 changes: 34 additions & 0 deletions tests/ui/derives/auxiliary/derive-no-generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#![feature(proc_macro_quote)]

extern crate proc_macro;

use proc_macro::{TokenStream, TokenTree, quote};

#[proc_macro_derive(A)]
pub fn derive(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 {
Comment thread
petrochenkov marked this conversation as resolved.
fn foo(&self) {
if let Self :: $variant(val) = self {
let _: $arg = val;
}
}
}

};
tokens
}
13 changes: 13 additions & 0 deletions tests/ui/derives/derive-macro-unsupported-type-params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//@ proc-macro: derive-no-generics.rs
#![crate_type = "lib"]

#[macro_use]
extern crate derive_no_generics;

#[derive(A)]
enum A<T> {
//~^ ERROR: missing generics for enum `A`
//~| ERROR: missing generics for enum `A`
Variant(T),
//~^ ERROR: cannot find type `T` in this scope
}
26 changes: 26 additions & 0 deletions tests/ui/derives/derive-macro-unsupported-type-params.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error[E0425]: cannot find type `T` in this scope
--> $DIR/derive-macro-unsupported-type-params.rs:11:13
|
LL | Variant(T),
| ^ not found in this scope

error[E0107]: missing generics for enum `A`
--> $DIR/derive-macro-unsupported-type-params.rs:8:6
|
LL | #[derive(A)]
| - this derive macro might not support items with generic parameters
LL | enum A<T> {
| ^

error[E0107]: missing generics for enum `A`
--> $DIR/derive-macro-unsupported-type-params.rs:8:6
|
LL | #[derive(A)]
| - this derive macro might not support items with generic parameters
LL | enum A<T> {
| ^

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0107, E0425.
For more information about an error, try `rustc --explain E0107`.
Loading