diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index b9197be444266..b2efb0380d357 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -183,7 +183,7 @@ pub(crate) use SubstructureFields::*; use rustc_ast::ptr::P; use rustc_ast::{ self as ast, AnonConst, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, - Generics, Mutability, PatKind, VariantData, + Generics, Mutability, PatKind, QSelf, VariantData, }; use rustc_attr_parsing::{AttributeKind, AttributeParser, ReprPacked}; use rustc_expand::base::{Annotatable, ExtCtxt}; @@ -409,6 +409,22 @@ fn find_type_parameters( type_params: Vec, } + impl Visitor<'_, '_> { + fn is_path_from_ty_param(&self, qself: &Option>, path: &ast::Path) -> bool { + if let Some(qself) = qself + && let ast::TyKind::Path(qself, path) = &qself.ty.kind + { + self.is_path_from_ty_param(&qself, &path) + } else if let Some(segment) = path.segments.first() + && self.ty_param_names.contains(&segment.ident.name) + { + true + } else { + false + } + } + } + impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> { fn visit_ty(&mut self, ty: &'a ast::Ty) { let stack_len = self.bound_generic_params_stack.len(); @@ -420,14 +436,13 @@ fn find_type_parameters( self.bound_generic_params_stack.extend(bare_fn.generic_params.iter().cloned()); } - if let ast::TyKind::Path(_, path) = &ty.kind - && let Some(segment) = path.segments.first() - && self.ty_param_names.contains(&segment.ident.name) - { - self.type_params.push(TypeParameter { - bound_generic_params: self.bound_generic_params_stack.clone(), - ty: P(ty.clone()), - }); + if let ast::TyKind::Path(qself, path) = &ty.kind { + if self.is_path_from_ty_param(qself, path) { + self.type_params.push(TypeParameter { + bound_generic_params: self.bound_generic_params_stack.clone(), + ty: P(ty.clone()), + }); + } } visit::walk_ty(self, ty); diff --git a/tests/ui/deriving/deriving-associated-types.rs b/tests/ui/deriving/deriving-associated-types.rs index 22dcd8d7cc035..873e85073a614 100644 --- a/tests/ui/deriving/deriving-associated-types.rs +++ b/tests/ui/deriving/deriving-associated-types.rs @@ -43,6 +43,16 @@ struct TupleStruct( ::Type, ) where C: WhereTrait; +#[derive(PartialEq, Debug)] +struct TupleStructJustQSelf( + ::Type, + ::Type, + Option<::Type>, + ::Type, + Option<::Type>, + ::Type, +) where C: WhereTrait; + #[derive(PartialEq, Debug)] pub struct Struct where C: WhereTrait { m1: module::Type, @@ -62,6 +72,16 @@ pub struct Struct where C: WhereTrait { d: ::Type, } +#[derive(PartialEq, Debug)] +pub struct StructJustQSelf where C: WhereTrait { + b1: ::Type, + b3: ::Type, + b4: Option<::Type>, + c3: ::Type, + c4: Option<::Type>, + d: ::Type, +} + #[derive(PartialEq, Debug)] enum Enum where C: WhereTrait { Unit, @@ -101,6 +121,29 @@ enum Enum where C: WhereTrait { }, } +#[derive(PartialEq, Debug)] +enum EnumJustQSelf where C: WhereTrait { + Unit, + Seq( + ::Type, + ::Type, + Option<::Type>, + ::Type, + ::Type, + Option<::Type>, + ::Type, + ), + Map { + b1: ::Type, + b3: ::Type, + b4: Option<::Type>, + c1: ::Type, + c3: ::Type, + c4: Option<::Type>, + d: ::Type, + }, +} + fn main() { let e: TupleStruct< i32, @@ -125,6 +168,19 @@ fn main() { ); assert_eq!(e, e); + let e: TupleStructJustQSelf< + i32, + i32, + > = TupleStructJustQSelf( + 0, + 0, + None, + 0, + None, + 0, + ); + assert_eq!(e, e); + let e: Struct< i32, i32, @@ -148,6 +204,19 @@ fn main() { }; assert_eq!(e, e); + let e: StructJustQSelf< + i32, + i32, + > = StructJustQSelf { + b1: 0, + b3: 0, + b4: None, + c3: 0, + c4: None, + d: 0, + }; + assert_eq!(e, e); + let e = Enum::Unit::; assert_eq!(e, e); @@ -196,4 +265,38 @@ fn main() { d: 0, }; assert_eq!(e, e); + + let e: EnumJustQSelf< + i32, + i32, + > = EnumJustQSelf::Unit; + assert_eq!(e, e); + + let e: EnumJustQSelf< + i32, + i32, + > = EnumJustQSelf::Seq( + 0, + 0, + None, + 0, + 0, + None, + 0, + ); + assert_eq!(e, e); + + let e: EnumJustQSelf< + i32, + i32, + > = EnumJustQSelf::Map { + b1: 0, + b3: 0, + b4: None, + c1: 0, + c3: 0, + c4: None, + d: 0, + }; + assert_eq!(e, e); }