Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21692 from ChayimFriedman2/builtin-derive-param
fix: Fix another case where we forgot to put the type param for `PartialOrd` and `PartialEq` in builtin derives
| -rw-r--r-- | crates/hir-ty/src/builtin_derive.rs | 82 |
1 files changed, 52 insertions, 30 deletions
diff --git a/crates/hir-ty/src/builtin_derive.rs b/crates/hir-ty/src/builtin_derive.rs index b7a1585c80..5a93c2b536 100644 --- a/crates/hir-ty/src/builtin_derive.rs +++ b/crates/hir-ty/src/builtin_derive.rs @@ -35,6 +35,24 @@ fn coerce_pointee_new_type_param(trait_id: TraitId) -> TypeParamId { }) } +fn trait_args(trait_: BuiltinDeriveImplTrait, self_ty: Ty<'_>) -> GenericArgs<'_> { + match trait_ { + BuiltinDeriveImplTrait::Copy + | BuiltinDeriveImplTrait::Clone + | BuiltinDeriveImplTrait::Default + | BuiltinDeriveImplTrait::Debug + | BuiltinDeriveImplTrait::Hash + | BuiltinDeriveImplTrait::Eq + | BuiltinDeriveImplTrait::Ord => GenericArgs::new_from_slice(&[self_ty.into()]), + BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::PartialEq => { + GenericArgs::new_from_slice(&[self_ty.into(), self_ty.into()]) + } + BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { + panic!("`CoerceUnsized` and `DispatchFromDyn` have special generics") + } + } +} + pub(crate) fn generics_of<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplId) -> Generics { let db = interner.db; let loc = id.loc(db); @@ -95,21 +113,19 @@ pub fn impl_trait<'db>( | BuiltinDeriveImplTrait::Debug | BuiltinDeriveImplTrait::Hash | BuiltinDeriveImplTrait::Ord - | BuiltinDeriveImplTrait::Eq => { + | BuiltinDeriveImplTrait::Eq + | BuiltinDeriveImplTrait::PartialOrd + | BuiltinDeriveImplTrait::PartialEq => { let self_ty = Ty::new_adt( interner, loc.adt, GenericArgs::identity_for_item(interner, loc.adt.into()), ); - EarlyBinder::bind(TraitRef::new(interner, trait_id.into(), [self_ty])) - } - BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::PartialEq => { - let self_ty = Ty::new_adt( + EarlyBinder::bind(TraitRef::new_from_args( interner, - loc.adt, - GenericArgs::identity_for_item(interner, loc.adt.into()), - ); - EarlyBinder::bind(TraitRef::new(interner, trait_id.into(), [self_ty, self_ty])) + trait_id.into(), + trait_args(loc.trait_, self_ty), + )) } BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { let generic_params = GenericParams::new(db, loc.adt.into()); @@ -260,21 +276,7 @@ fn simple_trait_predicates<'db>( let param_idx = param_idx.into_raw().into_u32() + (generic_params.len_lifetimes() as u32); let param_ty = Ty::new_param(interner, param_id, param_idx); - let trait_args = match loc.trait_ { - BuiltinDeriveImplTrait::Copy - | BuiltinDeriveImplTrait::Clone - | BuiltinDeriveImplTrait::Default - | BuiltinDeriveImplTrait::Debug - | BuiltinDeriveImplTrait::Hash - | BuiltinDeriveImplTrait::Ord - | BuiltinDeriveImplTrait::Eq => GenericArgs::new_from_slice(&[param_ty.into()]), - BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::PartialEq => { - GenericArgs::new_from_slice(&[param_ty.into(), param_ty.into()]) - } - BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { - unreachable!() - } - }; + let trait_args = trait_args(loc.trait_, param_ty); let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), trait_args); trait_ref.upcast(interner) }); @@ -285,12 +287,14 @@ fn simple_trait_predicates<'db>( &mut assoc_type_bounds, interner.db.field_types(id.into()), trait_id, + loc.trait_, ), AdtId::UnionId(id) => extend_assoc_type_bounds( interner, &mut assoc_type_bounds, interner.db.field_types(id.into()), trait_id, + loc.trait_, ), AdtId::EnumId(id) => { for &(variant_id, _, _) in &id.enum_variants(interner.db).variants { @@ -299,6 +303,7 @@ fn simple_trait_predicates<'db>( &mut assoc_type_bounds, interner.db.field_types(variant_id.into()), trait_id, + loc.trait_, ) } } @@ -320,12 +325,14 @@ fn extend_assoc_type_bounds<'db>( interner: DbInterner<'db>, assoc_type_bounds: &mut Vec<Clause<'db>>, fields: &ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>, - trait_: TraitId, + trait_id: TraitId, + trait_: BuiltinDeriveImplTrait, ) { struct ProjectionFinder<'a, 'db> { interner: DbInterner<'db>, assoc_type_bounds: &'a mut Vec<Clause<'db>>, - trait_: TraitId, + trait_id: TraitId, + trait_: BuiltinDeriveImplTrait, } impl<'db> TypeVisitor<DbInterner<'db>> for ProjectionFinder<'_, 'db> { @@ -334,7 +341,12 @@ fn extend_assoc_type_bounds<'db>( fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result { if let TyKind::Alias(AliasTyKind::Projection, _) = t.kind() { self.assoc_type_bounds.push( - TraitRef::new(self.interner, self.trait_.into(), [t]).upcast(self.interner), + TraitRef::new_from_args( + self.interner, + self.trait_id.into(), + trait_args(self.trait_, t), + ) + .upcast(self.interner), ); } @@ -342,7 +354,7 @@ fn extend_assoc_type_bounds<'db>( } } - let mut visitor = ProjectionFinder { interner, assoc_type_bounds, trait_ }; + let mut visitor = ProjectionFinder { interner, assoc_type_bounds, trait_id, trait_ }; for (_, field) in fields.iter() { field.get().instantiate_identity().visit_with(&mut visitor); } @@ -503,10 +515,12 @@ struct MultiGenericParams<'a, T, #[pointee] U: ?Sized, const N: usize>(*const U) #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] struct Simple; -trait Trait {} +trait Trait { + type Assoc; +} #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N]); +struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N], T::Assoc); "#, expect![[r#" @@ -529,41 +543,49 @@ struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N]); Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Debug, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Debug, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Clone, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Clone, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Copy, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Copy, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: PartialEq<[#1]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): PartialEq<[Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. })]>, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Eq, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Eq, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: PartialOrd<[#1]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): PartialOrd<[Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. })]>, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Ord, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Ord, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) Clause(Binder { value: TraitPredicate(#1: Hash, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Hash, polarity:Positive), bound_vars: [] }) "#]], ); |