From 8a7ae23f75953cfb9ba1e07cc37be8455ac979c3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 3 Dec 2022 19:08:00 +0000 Subject: [PATCH] Properly substitute inherent associated types. --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 13 +++++++++---- .../associated-inherent-types/struct-generics.rs | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/associated-inherent-types/struct-generics.rs diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 82150310638..f204d59d005 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -347,7 +347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert!(self_ty.is_some()); } } else { - assert!(self_ty.is_none() && parent_substs.is_empty()); + assert!(self_ty.is_none()); } let arg_count = Self::check_generic_arg_count( @@ -1821,7 +1821,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Check if we have an enum variant. let mut variant_resolution = None; - if let ty::Adt(adt_def, _) = qself_ty.kind() { + if let ty::Adt(adt_def, adt_substs) = qself_ty.kind() { if adt_def.is_enum() { let variant_def = adt_def .variants() @@ -1923,8 +1923,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else { continue; }; - // FIXME(inherent_associated_types): This does not substitute parameters. - let ty = tcx.type_of(assoc_ty_did); + let item_substs = self.create_substs_for_associated_item( + span, + assoc_ty_did, + assoc_segment, + adt_substs, + ); + let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs); return Ok((ty, DefKind::AssocTy, assoc_ty_did)); } } diff --git a/src/test/ui/associated-inherent-types/struct-generics.rs b/src/test/ui/associated-inherent-types/struct-generics.rs new file mode 100644 index 00000000000..8952b379173 --- /dev/null +++ b/src/test/ui/associated-inherent-types/struct-generics.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S(T); + +impl S { + type P = T; +} + +fn main() { + type A = S<()>::P; + let _: A = (); +}