From e5b82a56c5a9dd5c40f2abe8ee5398fc8acdd4b4 Mon Sep 17 00:00:00 2001
From: Bastian Kauschke <bastian_kauschke@hotmail.de>
Date: Tue, 1 Sep 2020 14:30:16 +0200
Subject: [PATCH 1/3] allow concrete self types in consts

---
 compiler/rustc_hir/src/def.rs                 |  9 +++++-
 compiler/rustc_passes/src/dead.rs             |  2 +-
 compiler/rustc_resolve/src/diagnostics.rs     |  2 +-
 compiler/rustc_resolve/src/late.rs            |  7 +++--
 compiler/rustc_resolve/src/lib.rs             | 29 +++++++++++++------
 compiler/rustc_typeck/src/astconv/mod.rs      | 18 ++++++++++--
 src/librustdoc/clean/utils.rs                 |  2 +-
 .../min_const_generics/self-ty-in-const-1.rs  | 27 +++++++++++++++++
 .../self-ty-in-const-1.stderr                 | 24 +++++++++++++++
 .../min_const_generics/self-ty-in-const-2.rs  | 21 ++++++++++++++
 .../self-ty-in-const-2.stderr                 | 18 ++++++++++++
 11 files changed, 141 insertions(+), 18 deletions(-)
 create mode 100644 src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
 create mode 100644 src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
 create mode 100644 src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
 create mode 100644 src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr

diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index b019e518d0c54..730059e7eceb5 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -199,7 +199,14 @@ pub enum Res<Id = hir::HirId> {
 
     // Type namespace
     PrimTy(hir::PrimTy),
-    SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
+    /// `Self`, with both an optional trait and impl `DefId`.
+    ///
+    /// HACK: impl self types also have an optional requirement to not mention
+    /// any generic parameters to allow the following with `min_const_generics`.
+    /// `impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()]`.
+    ///
+    /// Once `lazy_normalization_consts` is stable, this bodge can be removed again.
+    SelfTy(Option<DefId> /* trait */, Option<(DefId, bool)> /* impl */),
     ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
 
     // Value namespace
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index c79542342ba78..fe6653e98da89 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -104,7 +104,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 if let Some(t) = t {
                     self.check_def_id(t);
                 }
-                if let Some(i) = i {
+                if let Some((i, _)) = i {
                     self.check_def_id(i);
                 }
             }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 7a0503d68f348..b80da64149150 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -112,7 +112,7 @@ impl<'a> Resolver<'a> {
                 match outer_res {
                     Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
                         if let Some(impl_span) =
-                            maybe_impl_defid.and_then(|def_id| self.opt_span(def_id))
+                            maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id))
                         {
                             err.span_label(
                                 reduce_impl_span_to_impl_keyword(sm, impl_span),
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 07f36c7b7ad36..6788df9be7820 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -110,6 +110,9 @@ crate enum RibKind<'a> {
     ItemRibKind(HasGenericParams),
 
     /// We're in a constant item. Can't refer to dynamic stuff.
+    ///
+    /// The `bool` indicates if this constant may reference generic parameters
+    /// and is used to only allow generic parameters to be used in trivial constant expressions.
     ConstantItemRibKind(bool),
 
     /// We passed through a module.
@@ -848,7 +851,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
                 let item_def_id = this.r.local_def_id(item.id).to_def_id();
-                this.with_self_rib(Res::SelfTy(None, Some(item_def_id)), |this| {
+                this.with_self_rib(Res::SelfTy(None, Some((item_def_id, false))), |this| {
                     visit::walk_item(this, item);
                 });
             });
@@ -1215,7 +1218,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 // Resolve the trait reference, if necessary.
                 this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
                     let item_def_id = this.r.local_def_id(item_id).to_def_id();
-                    this.with_self_rib(Res::SelfTy(trait_id, Some(item_def_id)), |this| {
+                    this.with_self_rib(Res::SelfTy(trait_id, Some((item_def_id, false))), |this| {
                         if let Some(trait_ref) = opt_trait_reference.as_ref() {
                             // Resolve type arguments in the trait path.
                             visit::walk_trait_ref(this, trait_ref);
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 0f5b9b518163f..1922f0d566e97 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -2539,7 +2539,7 @@ impl<'a> Resolver<'a> {
         &mut self,
         rib_index: usize,
         rib_ident: Ident,
-        res: Res,
+        mut res: Res,
         record_used: bool,
         span: Span,
         all_ribs: &[Rib<'a>],
@@ -2627,15 +2627,26 @@ impl<'a> Resolver<'a> {
                             continue;
                         }
                         ConstantItemRibKind(trivial) => {
-                            // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !trivial && self.session.features_untracked().min_const_generics {
-                                if record_used {
-                                    self.report_error(
-                                        span,
-                                        ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name),
-                                    );
+                            if self.session.features_untracked().min_const_generics {
+                                // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
+                                if !trivial {
+                                    // HACK(min_const_generics): If we encounter `Self` in an anonymous constant
+                                    // we can't easily tell if it's generic at this stage, so we instead remember
+                                    // this and then enforce the self type to be concrete later on.
+                                    if let Res::SelfTy(trait_def, Some((impl_def, _))) = res {
+                                        res = Res::SelfTy(trait_def, Some((impl_def, true)));
+                                    } else {
+                                        if record_used {
+                                            self.report_error(
+                                                span,
+                                                ResolutionError::ParamInNonTrivialAnonConst(
+                                                    rib_ident.name,
+                                                ),
+                                            );
+                                        }
+                                        return Res::Err;
+                                    }
                                 }
-                                return Res::Err;
                             }
 
                             if in_ty_param_default {
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 9e339b1082cb8..66d9d49d93fac 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1460,7 +1460,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         // Find the type of the associated item, and the trait where the associated
         // item is declared.
         let bound = match (&qself_ty.kind(), qself_res) {
-            (_, Res::SelfTy(Some(_), Some(impl_def_id))) => {
+            (_, Res::SelfTy(Some(_), Some((impl_def_id, _)))) => {
                 // `Self` in an impl of a trait -- we have a concrete self type and a
                 // trait reference.
                 let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
@@ -1917,12 +1917,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 self.prohibit_generics(path.segments);
                 tcx.types.self_param
             }
-            Res::SelfTy(_, Some(def_id)) => {
+            Res::SelfTy(_, Some((def_id, forbid_generic))) => {
                 // `Self` in impl (we know the concrete type).
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(path.segments);
                 // Try to evaluate any array length constants.
-                self.normalize_ty(span, tcx.at(span).type_of(def_id))
+                let normalized_ty = self.normalize_ty(span, tcx.at(span).type_of(def_id));
+                if forbid_generic && normalized_ty.needs_subst() {
+                    tcx.sess
+                        .struct_span_err(
+                            path.span,
+                            "generic `Self` types are currently not permitted in anonymous constants"
+                        )
+                        .span_note(tcx.def_span(def_id), "not a concrete type")
+                        .emit();
+                    tcx.ty_error()
+                } else {
+                    normalized_ty
+                }
             }
             Res::Def(DefKind::AssocTy, def_id) => {
                 debug_assert!(path.segments.len() >= 2);
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index c577b771d6094..58b76d24a5bdb 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -601,7 +601,7 @@ pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
         },
         Res::Def(DefKind::TraitAlias, i) => (i, TypeKind::TraitAlias),
         Res::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
-        Res::SelfTy(_, Some(impl_def_id)) => return impl_def_id,
+        Res::SelfTy(_, Some((impl_def_id, _))) => return impl_def_id,
         _ => return res.def_id(),
     };
     if did.is_local() {
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
new file mode 100644
index 0000000000000..0973b373c122c
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
@@ -0,0 +1,27 @@
+#![feature(min_const_generics)]
+
+trait Foo {
+    fn t1() -> [u8; std::mem::size_of::<Self>()]; //~ERROR generic parameters
+}
+
+struct Bar<T>(T);
+
+impl Bar<u8> {
+    fn t2() -> [u8; std::mem::size_of::<Self>()] { todo!() } // ok
+}
+
+impl<T> Bar<T> {
+    fn t3() -> [u8; std::mem::size_of::<Self>()] {} //~ERROR generic `Self`
+}
+
+trait Baz {
+    fn hey();
+}
+
+impl Baz for u16 {
+    fn hey() {
+        let _: [u8; std::mem::size_of::<Self>()]; // ok
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
new file mode 100644
index 0000000000000..94f67735fca44
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
@@ -0,0 +1,24 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/self-ty-in-const-1.rs:4:41
+   |
+LL |     fn t1() -> [u8; std::mem::size_of::<Self>()];
+   |                                         ^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
+   |
+   = help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
+
+error: generic `Self` types are currently not permitted in anonymous constants
+  --> $DIR/self-ty-in-const-1.rs:14:41
+   |
+LL |     fn t3() -> [u8; std::mem::size_of::<Self>()] {}
+   |                                         ^^^^
+   |
+note: not a concrete type
+  --> $DIR/self-ty-in-const-1.rs:13:1
+   |
+LL | / impl<T> Bar<T> {
+LL | |     fn t3() -> [u8; std::mem::size_of::<Self>()] {}
+LL | | }
+   | |_^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
new file mode 100644
index 0000000000000..e7f80d50082b3
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
@@ -0,0 +1,21 @@
+#![feature(min_const_generics)]
+
+struct Bar<T>(T);
+
+trait Baz {
+    fn hey();
+}
+
+impl Baz for u16 {
+    fn hey() {
+        let _: [u8; std::mem::size_of::<Self>()]; // ok
+    }
+}
+
+impl<T> Baz for Bar<T> {
+    fn hey() {
+        let _: [u8; std::mem::size_of::<Self>()]; //~ERROR generic `Self`
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
new file mode 100644
index 0000000000000..70f44e7de6337
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
@@ -0,0 +1,18 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+  --> $DIR/self-ty-in-const-2.rs:17:41
+   |
+LL |         let _: [u8; std::mem::size_of::<Self>()];
+   |                                         ^^^^
+   |
+note: not a concrete type
+  --> $DIR/self-ty-in-const-2.rs:15:1
+   |
+LL | / impl<T> Baz for Bar<T> {
+LL | |     fn hey() {
+LL | |         let _: [u8; std::mem::size_of::<Self>()];
+LL | |     }
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+

From c552717e9da86f70d49390bba1e4b305054d9ed4 Mon Sep 17 00:00:00 2001
From: Bastian Kauschke <bastian_kauschke@hotmail.de>
Date: Tue, 8 Sep 2020 11:37:27 +0200
Subject: [PATCH 2/3] review, improve note span

---
 compiler/rustc_hir/src/def.rs                 | 10 +++---
 compiler/rustc_resolve/src/lib.rs             | 34 +++++++++----------
 compiler/rustc_typeck/src/astconv/mod.rs      | 19 +++++++----
 .../self-ty-in-const-1.stderr                 |  8 ++---
 .../self-ty-in-const-2.stderr                 | 10 ++----
 5 files changed, 40 insertions(+), 41 deletions(-)

diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 730059e7eceb5..96fde48d96cc1 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -201,11 +201,13 @@ pub enum Res<Id = hir::HirId> {
     PrimTy(hir::PrimTy),
     /// `Self`, with both an optional trait and impl `DefId`.
     ///
-    /// HACK: impl self types also have an optional requirement to not mention
-    /// any generic parameters to allow the following with `min_const_generics`.
-    /// `impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()]`.
+    /// HACK(min_const_generics): impl self types also have an optional requirement to not mention
+    /// any generic parameters to allow the following with `min_const_generics`:
+    /// ```rust
+    /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] {} }
+    /// ```
     ///
-    /// Once `lazy_normalization_consts` is stable, this bodge can be removed again.
+    /// FIXME(lazy_normalization_consts): Remove this bodge once this feature is stable.
     SelfTy(Option<DefId> /* trait */, Option<(DefId, bool)> /* impl */),
     ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 1922f0d566e97..00a37d908cd07 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -2627,25 +2627,23 @@ impl<'a> Resolver<'a> {
                             continue;
                         }
                         ConstantItemRibKind(trivial) => {
-                            if self.session.features_untracked().min_const_generics {
-                                // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                                if !trivial {
-                                    // HACK(min_const_generics): If we encounter `Self` in an anonymous constant
-                                    // we can't easily tell if it's generic at this stage, so we instead remember
-                                    // this and then enforce the self type to be concrete later on.
-                                    if let Res::SelfTy(trait_def, Some((impl_def, _))) = res {
-                                        res = Res::SelfTy(trait_def, Some((impl_def, true)));
-                                    } else {
-                                        if record_used {
-                                            self.report_error(
-                                                span,
-                                                ResolutionError::ParamInNonTrivialAnonConst(
-                                                    rib_ident.name,
-                                                ),
-                                            );
-                                        }
-                                        return Res::Err;
+                            // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
+                            if !trivial && self.session.features_untracked().min_const_generics {
+                                // HACK(min_const_generics): If we encounter `Self` in an anonymous constant
+                                // we can't easily tell if it's generic at this stage, so we instead remember
+                                // this and then enforce the self type to be concrete later on.
+                                if let Res::SelfTy(trait_def, Some((impl_def, _))) = res {
+                                    res = Res::SelfTy(trait_def, Some((impl_def, true)));
+                                } else {
+                                    if record_used {
+                                        self.report_error(
+                                            span,
+                                            ResolutionError::ParamInNonTrivialAnonConst(
+                                                rib_ident.name,
+                                            ),
+                                        );
                                     }
+                                    return Res::Err;
                                 }
                             }
 
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 66d9d49d93fac..a743dc1cd2086 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1924,13 +1924,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // 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() {
-                    tcx.sess
-                        .struct_span_err(
-                            path.span,
-                            "generic `Self` types are currently not permitted in anonymous constants"
-                        )
-                        .span_note(tcx.def_span(def_id), "not a concrete type")
-                        .emit();
+                    let mut err = tcx.sess.struct_span_err(
+                        path.span,
+                        "generic `Self` types are currently not permitted in anonymous constants",
+                    );
+                    if let Some(hir::Node::Item(&hir::Item {
+                        kind: hir::ItemKind::Impl { self_ty, .. },
+                        ..
+                    })) = tcx.hir().get_if_local(def_id)
+                    {
+                        err.span_note(self_ty.span, "not a concrete type");
+                    }
+                    err.emit();
                     tcx.ty_error()
                 } else {
                     normalized_ty
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
index 94f67735fca44..89ce58564e465 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
@@ -13,12 +13,10 @@ LL |     fn t3() -> [u8; std::mem::size_of::<Self>()] {}
    |                                         ^^^^
    |
 note: not a concrete type
-  --> $DIR/self-ty-in-const-1.rs:13:1
+  --> $DIR/self-ty-in-const-1.rs:13:9
    |
-LL | / impl<T> Bar<T> {
-LL | |     fn t3() -> [u8; std::mem::size_of::<Self>()] {}
-LL | | }
-   | |_^
+LL | impl<T> Bar<T> {
+   |         ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
index 70f44e7de6337..9ac6410a290a5 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
@@ -5,14 +5,10 @@ LL |         let _: [u8; std::mem::size_of::<Self>()];
    |                                         ^^^^
    |
 note: not a concrete type
-  --> $DIR/self-ty-in-const-2.rs:15:1
+  --> $DIR/self-ty-in-const-2.rs:15:17
    |
-LL | / impl<T> Baz for Bar<T> {
-LL | |     fn hey() {
-LL | |         let _: [u8; std::mem::size_of::<Self>()];
-LL | |     }
-LL | | }
-   | |_^
+LL | impl<T> Baz for Bar<T> {
+   |                 ^^^^^^
 
 error: aborting due to previous error
 

From 90dd798cf53320b3478119d06d2d8c47880c9247 Mon Sep 17 00:00:00 2001
From: Bastian Kauschke <bastian_kauschke@hotmail.de>
Date: Sun, 13 Sep 2020 23:02:43 +0200
Subject: [PATCH 3/3] bless tests

---
 .../ui/const-generics/issues/issue-62504.min.stderr    | 10 +++++++---
 src/test/ui/const-generics/issues/issue-62504.rs       |  2 +-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/test/ui/const-generics/issues/issue-62504.min.stderr b/src/test/ui/const-generics/issues/issue-62504.min.stderr
index 752df17aad614..8f794312834b2 100644
--- a/src/test/ui/const-generics/issues/issue-62504.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62504.min.stderr
@@ -1,10 +1,14 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic `Self` types are currently not permitted in anonymous constants
   --> $DIR/issue-62504.rs:19:25
    |
 LL |         ArrayHolder([0; Self::SIZE])
-   |                         ^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
+   |                         ^^^^^^^^^^
    |
-   = help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
+note: not a concrete type
+  --> $DIR/issue-62504.rs:17:22
+   |
+LL | impl<const X: usize> ArrayHolder<X> {
+   |                      ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs
index b520dbe4e803b..015f170f00d1c 100644
--- a/src/test/ui/const-generics/issues/issue-62504.rs
+++ b/src/test/ui/const-generics/issues/issue-62504.rs
@@ -18,7 +18,7 @@ impl<const X: usize> ArrayHolder<X> {
     pub const fn new() -> Self {
         ArrayHolder([0; Self::SIZE])
         //[full]~^ ERROR constant expression depends on a generic parameter
-        //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+        //[min]~^^ ERROR generic `Self` types are currently
     }
 }