From 76c562f3b30e0d033902d004fdb0069d5584d78a Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 9 Feb 2022 12:29:43 +0100 Subject: [PATCH] fix min_const_generics oversight --- compiler/rustc_typeck/src/astconv/mod.rs | 25 ++++++++++++++++--- .../forbid-self-no-normalize.rs | 15 +++++++++++ .../forbid-self-no-normalize.stderr | 14 +++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs create mode 100644 src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 0ad2242f667..aa054043c4e 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2281,8 +2281,27 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert_eq!(opt_self_ty, None); self.prohibit_generics(path.segments); // Try to evaluate any array length constants. - let normalized_ty = self.normalize_ty(span, tcx.at(span).type_of(def_id)); - if forbid_generic && normalized_ty.needs_subst() { + let ty = tcx.at(span).type_of(def_id); + // HACK(min_const_generics): Forbid generic `Self` types + // here as we can't easily do that during nameres. + // + // We do this before normalization as we otherwise allow + // ```rust + // trait AlwaysApplicable { type Assoc; } + // impl AlwaysApplicable for T { type Assoc = usize; } + // + // trait BindsParam { + // type ArrayTy; + // } + // impl BindsParam for ::Assoc { + // type ArrayTy = [u8; Self::MAX]; + // } + // ``` + // Note that the normalization happens in the param env of + // the anon const, which is empty. This is why the + // `AlwaysApplicable` impl needs a `T: ?Sized` bound for + // this to compile if we were to normalize here. + if forbid_generic && ty.needs_subst() { let mut err = tcx.sess.struct_span_err( path.span, "generic `Self` types are currently not permitted in anonymous constants", @@ -2297,7 +2316,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.emit(); tcx.ty_error() } else { - normalized_ty + self.normalize_ty(span, ty) } } Res::Def(DefKind::AssocTy, def_id) => { diff --git a/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs new file mode 100644 index 00000000000..e1cf7b579aa --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs @@ -0,0 +1,15 @@ +trait AlwaysApplicable { + type Assoc; +} +impl AlwaysApplicable for T { + type Assoc = usize; +} + +trait BindsParam { + type ArrayTy; +} +impl BindsParam for ::Assoc { + type ArrayTy = [u8; Self::MAX]; //~ ERROR generic `Self` types +} + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr new file mode 100644 index 00000000000..bda88597006 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr @@ -0,0 +1,14 @@ +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/forbid-self-no-normalize.rs:12:25 + | +LL | type ArrayTy = [u8; Self::MAX]; + | ^^^^ + | +note: not a concrete type + --> $DIR/forbid-self-no-normalize.rs:11:27 + | +LL | impl BindsParam for ::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error +