about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-30 07:52:18 +0000
committerbors <bors@rust-lang.org>2022-04-30 07:52:18 +0000
commit76d4862fdd131b6f79dc0a31857f888d26bcdb27 (patch)
treefa699104ad1098a95d9e25d704d517ddeb465a76
parent9a98c63b30bd8419be662b8fb3f3b22ba33d72c5 (diff)
parent7d990a8c1838a18c54a4b8a9f5fe74ea507ecbb3 (diff)
downloadrust-76d4862fdd131b6f79dc0a31857f888d26bcdb27.tar.gz
rust-76d4862fdd131b6f79dc0a31857f888d26bcdb27.zip
Auto merge of #95776 - cjgillot:ast-lifetimes-static, r=petrochenkov
Enforce static lifetimes in consts during late resolution

This PR moves the handling of implicitly and explicitly static lifetimes in constants from HIR to the AST.
-rw-r--r--compiler/rustc_resolve/src/late.rs48
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs77
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs15
-rw-r--r--src/test/ui/const-generics/const-arg-in-const-arg.min.stderr275
-rw-r--r--src/test/ui/const-generics/const-arg-in-const-arg.rs17
-rw-r--r--src/test/ui/const-generics/issues/issue-56445-1.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-56445-1.rs1
-rw-r--r--src/test/ui/error-codes/E0771.stderr16
8 files changed, 314 insertions, 146 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index aafef3e3137..53bd589fdcd 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -199,6 +199,16 @@ enum LifetimeRibKind {
     /// This rib declares generic parameters.
     Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind },
 
+    /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
+    /// generics. We are disallowing this until we can decide on how we want to handle non-'static
+    /// lifetimes in const generics. See issue #74052 for discussion.
+    ConstGeneric,
+
+    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
+    /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
+    /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
+    AnonConst,
+
     /// For **Modern** cases, create a new anonymous region parameter
     /// and reference that.
     ///
@@ -527,7 +537,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
     }
     fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
         // We deal with repeat expressions explicitly in `resolve_expr`.
-        self.resolve_anon_const(constant, IsRepeatExpr::No);
+        self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
+            this.resolve_anon_const(constant, IsRepeatExpr::No);
+        })
     }
     fn visit_expr(&mut self, expr: &'ast Expr) {
         self.resolve_expr(expr, None);
@@ -1102,14 +1114,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
                         this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
                         this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
-                        this.visit_ty(ty);
+                        this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
+                            this.visit_ty(ty)
+                        });
                         this.ribs[TypeNS].pop().unwrap();
                         this.ribs[ValueNS].pop().unwrap();
 
                         if let Some(ref expr) = default {
                             this.ribs[TypeNS].push(forward_ty_ban_rib);
                             this.ribs[ValueNS].push(forward_const_ban_rib);
-                            this.visit_anon_const(expr);
+                            this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
+                                this.resolve_anon_const(expr, IsRepeatExpr::No)
+                            });
                             forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
                             forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
                         }
@@ -1158,8 +1174,19 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 return;
             }
 
-            if let LifetimeRibKind::Item = rib.kind {
-                break;
+            match rib.kind {
+                LifetimeRibKind::Item => break,
+                LifetimeRibKind::ConstGeneric => {
+                    self.emit_non_static_lt_in_const_generic_error(lifetime);
+                    self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error);
+                    return;
+                }
+                LifetimeRibKind::AnonConst => {
+                    self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
+                    self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error);
+                    return;
+                }
+                _ => {}
             }
         }
 
@@ -3065,9 +3092,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             is_repeat,
             constant.value.is_potential_trivial_const_param(),
             None,
-            |this| {
-                visit::walk_anon_const(this, constant);
-            },
+            |this| visit::walk_anon_const(this, constant),
         );
     }
 
@@ -3218,7 +3243,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             }
             ExprKind::Repeat(ref elem, ref ct) => {
                 self.visit_expr(elem);
-                self.resolve_anon_const(ct, IsRepeatExpr::Yes);
+                self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
+                    this.resolve_anon_const(ct, IsRepeatExpr::Yes)
+                });
+            }
+            ExprKind::ConstBlock(ref ct) => {
+                self.resolve_anon_const(ct, IsRepeatExpr::No);
             }
             ExprKind::Index(ref elem, ref idx) => {
                 self.resolve_expr(elem, Some(expr));
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index a9edb713b0d..894ff0f17f8 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1886,6 +1886,37 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
         err.emit();
     }
+
+    crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
+        struct_span_err!(
+            self.r.session,
+            lifetime_ref.ident.span,
+            E0771,
+            "use of non-static lifetime `{}` in const generic",
+            lifetime_ref.ident
+        )
+        .note(
+            "for more information, see issue #74052 \
+            <https://github.com/rust-lang/rust/issues/74052>",
+        )
+        .emit();
+    }
+
+    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
+    /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
+    /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
+    crate fn maybe_emit_forbidden_non_static_lifetime_error(&self, lifetime_ref: &ast::Lifetime) {
+        let feature_active = self.r.session.features_untracked().generic_const_exprs;
+        if !feature_active {
+            feature_err(
+                &self.r.session.parse_sess,
+                sym::generic_const_exprs,
+                lifetime_ref.ident.span,
+                "a non-static lifetime is not allowed in a `const`",
+            )
+            .emit();
+        }
+    }
 }
 
 impl<'tcx> LifetimeContext<'_, 'tcx> {
@@ -1982,24 +2013,6 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         }
     }
 
-    // FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
-    // generics. We are disallowing this until we can decide on how we want to handle non-'static
-    // lifetimes in const generics. See issue #74052 for discussion.
-    crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) {
-        let mut err = struct_span_err!(
-            self.tcx.sess,
-            lifetime_ref.span,
-            E0771,
-            "use of non-static lifetime `{}` in const generic",
-            lifetime_ref
-        );
-        err.note(
-            "for more information, see issue #74052 \
-            <https://github.com/rust-lang/rust/issues/74052>",
-        );
-        err.emit();
-    }
-
     crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool {
         if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res {
             if [
@@ -2401,32 +2414,4 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
             _ => unreachable!(),
         }
     }
-
-    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
-    /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
-    /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
-    crate fn maybe_emit_forbidden_non_static_lifetime_error(
-        &self,
-        body_id: hir::BodyId,
-        lifetime_ref: &'tcx hir::Lifetime,
-    ) {
-        let is_anon_const = matches!(
-            self.tcx.def_kind(self.tcx.hir().body_owner_def_id(body_id)),
-            hir::def::DefKind::AnonConst
-        );
-        let is_allowed_lifetime = matches!(
-            lifetime_ref.name,
-            hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
-        );
-
-        if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime {
-            feature_err(
-                &self.tcx.sess.parse_sess,
-                sym::generic_const_exprs,
-                lifetime_ref.span,
-                "a non-static lifetime is not allowed in a `const`",
-            )
-            .emit();
-        }
-    }
 }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index ce3069265d0..35a40a0a321 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -164,8 +164,6 @@ crate struct LifetimeContext<'a, 'tcx> {
     map: &'a mut NamedRegionMap,
     scope: ScopeRef<'a>,
 
-    is_in_const_generic: bool,
-
     /// Indicates that we only care about the definition of a trait. This should
     /// be false if the `Item` we are resolving lifetimes for is not a trait or
     /// we eventually need lifetimes resolve for trait items.
@@ -452,7 +450,6 @@ fn do_resolve(
         tcx,
         map: &mut named_region_map,
         scope: ROOT_SCOPE,
-        is_in_const_generic: false,
         trait_definition_only,
         labels_in_fn: vec![],
         xcrate_object_lifetime_defaults: Default::default(),
@@ -1266,10 +1263,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             self.insert_lifetime(lifetime_ref, Region::Static);
             return;
         }
-        if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error {
-            self.emit_non_static_lt_in_const_generic_error(lifetime_ref);
-            return;
-        }
         self.resolve_lifetime_ref(lifetime_ref);
     }
 
@@ -1341,14 +1334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         }
                     }
                     GenericParamKind::Const { ref ty, default } => {
-                        let was_in_const_generic = this.is_in_const_generic;
-                        this.is_in_const_generic = true;
                         walk_list!(this, visit_param_bound, param.bounds);
                         this.visit_ty(&ty);
                         if let Some(default) = default {
                             this.visit_body(this.tcx.hir().body(default.body));
                         }
-                        this.is_in_const_generic = was_in_const_generic;
                     }
                 }
             }
@@ -1798,7 +1788,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             tcx: *tcx,
             map,
             scope: &wrap_scope,
-            is_in_const_generic: self.is_in_const_generic,
             trait_definition_only: self.trait_definition_only,
             labels_in_fn,
             xcrate_object_lifetime_defaults,
@@ -2254,10 +2243,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         let result = loop {
             match *scope {
                 Scope::Body { id, s } => {
-                    // Non-static lifetimes are prohibited in anonymous constants without
-                    // `generic_const_exprs`.
-                    self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
-
                     outermost_body = Some(id);
                     scope = s;
                 }
diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
index ac693426fbd..88d9ed46e1a 100644
--- a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -16,53 +16,8 @@ LL |     let _: [u8; bar::<N>()];
    = help: const parameters may only be used as standalone arguments, i.e. `N`
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
-error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:24:23
-   |
-LL |     let _ = [0; bar::<N>()];
-   |                       ^ cannot perform const operation using `N`
-   |
-   = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-
-error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:29:24
-   |
-LL |     let _: Foo<{ foo::<T>() }>;
-   |                        ^ cannot perform const operation using `T`
-   |
-   = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-
-error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:30:24
-   |
-LL |     let _: Foo<{ bar::<N>() }>;
-   |                        ^ cannot perform const operation using `N`
-   |
-   = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-
-error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:35:27
-   |
-LL |     let _ = Foo::<{ foo::<T>() }>;
-   |                           ^ cannot perform const operation using `T`
-   |
-   = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-
-error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:36:27
-   |
-LL |     let _ = Foo::<{ bar::<N>() }>;
-   |                           ^ cannot perform const operation using `N`
-   |
-   = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:15:23
+  --> $DIR/const-arg-in-const-arg.rs:16:23
    |
 LL |     let _: [u8; faz::<'a>(&())];
    |                       ^^
@@ -71,7 +26,7 @@ LL |     let _: [u8; faz::<'a>(&())];
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:16:23
+  --> $DIR/const-arg-in-const-arg.rs:18:23
    |
 LL |     let _: [u8; baz::<'a>(&())];
    |                       ^^
@@ -80,7 +35,7 @@ LL |     let _: [u8; baz::<'a>(&())];
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:17:23
+  --> $DIR/const-arg-in-const-arg.rs:19:23
    |
 LL |     let _: [u8; faz::<'b>(&())];
    |                       ^^
@@ -89,7 +44,7 @@ LL |     let _: [u8; faz::<'b>(&())];
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:18:23
+  --> $DIR/const-arg-in-const-arg.rs:21:23
    |
 LL |     let _: [u8; baz::<'b>(&())];
    |                       ^^
@@ -97,8 +52,17 @@ LL |     let _: [u8; baz::<'b>(&())];
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:24:23
+   |
+LL |     let _ = [0; bar::<N>()];
+   |                       ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:25:23
+  --> $DIR/const-arg-in-const-arg.rs:26:23
    |
 LL |     let _ = [0; faz::<'a>(&())];
    |                       ^^
@@ -107,7 +71,7 @@ LL |     let _ = [0; faz::<'a>(&())];
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:26:23
+  --> $DIR/const-arg-in-const-arg.rs:28:23
    |
 LL |     let _ = [0; baz::<'a>(&())];
    |                       ^^
@@ -116,7 +80,7 @@ LL |     let _ = [0; baz::<'a>(&())];
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:27:23
+  --> $DIR/const-arg-in-const-arg.rs:29:23
    |
 LL |     let _ = [0; faz::<'b>(&())];
    |                       ^^
@@ -125,7 +89,7 @@ LL |     let _ = [0; faz::<'b>(&())];
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:28:23
+  --> $DIR/const-arg-in-const-arg.rs:31:23
    |
 LL |     let _ = [0; baz::<'b>(&())];
    |                       ^^
@@ -133,8 +97,26 @@ LL |     let _ = [0; baz::<'b>(&())];
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:32:24
+   |
+LL |     let _: Foo<{ foo::<T>() }>;
+   |                        ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:33:24
+   |
+LL |     let _: Foo<{ bar::<N>() }>;
+   |                        ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:31:24
+  --> $DIR/const-arg-in-const-arg.rs:35:24
    |
 LL |     let _: Foo<{ faz::<'a>(&()) }>;
    |                        ^^
@@ -143,7 +125,7 @@ LL |     let _: Foo<{ faz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:32:24
+  --> $DIR/const-arg-in-const-arg.rs:37:24
    |
 LL |     let _: Foo<{ baz::<'a>(&()) }>;
    |                        ^^
@@ -152,7 +134,7 @@ LL |     let _: Foo<{ baz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:33:24
+  --> $DIR/const-arg-in-const-arg.rs:38:24
    |
 LL |     let _: Foo<{ faz::<'b>(&()) }>;
    |                        ^^
@@ -161,7 +143,7 @@ LL |     let _: Foo<{ faz::<'b>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:34:24
+  --> $DIR/const-arg-in-const-arg.rs:40:24
    |
 LL |     let _: Foo<{ baz::<'b>(&()) }>;
    |                        ^^
@@ -169,8 +151,26 @@ LL |     let _: Foo<{ baz::<'b>(&()) }>;
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:41:27
+   |
+LL |     let _ = Foo::<{ foo::<T>() }>;
+   |                           ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:42:27
+   |
+LL |     let _ = Foo::<{ bar::<N>() }>;
+   |                           ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:37:27
+  --> $DIR/const-arg-in-const-arg.rs:44:27
    |
 LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    |                           ^^
@@ -179,7 +179,7 @@ LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:38:27
+  --> $DIR/const-arg-in-const-arg.rs:46:27
    |
 LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    |                           ^^
@@ -188,7 +188,7 @@ LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:39:27
+  --> $DIR/const-arg-in-const-arg.rs:47:27
    |
 LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    |                           ^^
@@ -197,7 +197,7 @@ LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:40:27
+  --> $DIR/const-arg-in-const-arg.rs:49:27
    |
 LL |     let _ = Foo::<{ baz::<'b>(&()) }>;
    |                           ^^
@@ -205,6 +205,155 @@ LL |     let _ = Foo::<{ baz::<'b>(&()) }>;
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
    = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
 
-error: aborting due to 23 previous errors
+error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/const-arg-in-const-arg.rs:14:23
+   |
+LL |     let _: [u8; bar::<N>()];
+   |                       ^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |     let _: [u8; bar::<{ N }>()];
+   |                       +   +
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:16:23
+   |
+LL |     let _: [u8; faz::<'a>(&())];
+   |                       ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:19:23
+   |
+LL |     let _: [u8; faz::<'b>(&())];
+   |                       ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/const-arg-in-const-arg.rs:24:23
+   |
+LL |     let _ = [0; bar::<N>()];
+   |                       ^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |     let _ = [0; bar::<{ N }>()];
+   |                       +   +
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:26:23
+   |
+LL |     let _ = [0; faz::<'a>(&())];
+   |                       ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:29:23
+   |
+LL |     let _ = [0; faz::<'b>(&())];
+   |                       ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/const-arg-in-const-arg.rs:33:24
+   |
+LL |     let _: Foo<{ bar::<N>() }>;
+   |                        ^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |     let _: Foo<{ bar::<{ N }>() }>;
+   |                        +   +
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:35:24
+   |
+LL |     let _: Foo<{ faz::<'a>(&()) }>;
+   |                        ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:38:24
+   |
+LL |     let _: Foo<{ faz::<'b>(&()) }>;
+   |                        ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error: constant expression depends on a generic parameter
+  --> $DIR/const-arg-in-const-arg.rs:23:17
+   |
+LL |     let _ = [0; foo::<T>()];
+   |                 ^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/const-arg-in-const-arg.rs:42:27
+   |
+LL |     let _ = Foo::<{ bar::<N>() }>;
+   |                           ^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |     let _ = Foo::<{ bar::<{ N }>() }>;
+   |                           +   +
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:44:27
+   |
+LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
+   |                           ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:47:27
+   |
+LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
+   |                           ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:8:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error: aborting due to 36 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0658, E0747.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.rs b/src/test/ui/const-generics/const-arg-in-const-arg.rs
index 39f0b237330..b9daadb5474 100644
--- a/src/test/ui/const-generics/const-arg-in-const-arg.rs
+++ b/src/test/ui/const-generics/const-arg-in-const-arg.rs
@@ -12,31 +12,40 @@ struct Foo<const N: usize>;
 fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
     let _: [u8; foo::<T>()]; //~ ERROR generic parameters may not
     let _: [u8; bar::<N>()]; //~ ERROR generic parameters may not
+                             //~^ ERROR unresolved item provided when a constant was expected
     let _: [u8; faz::<'a>(&())]; //~ ERROR a non-static lifetime
+                                 //~^ ERROR cannot specify lifetime arguments
     let _: [u8; baz::<'a>(&())]; //~ ERROR a non-static lifetime
     let _: [u8; faz::<'b>(&())]; //~ ERROR a non-static lifetime
+                                 //~^ ERROR cannot specify lifetime arguments
     let _: [u8; baz::<'b>(&())]; //~ ERROR a non-static lifetime
 
-    // NOTE: This can be a future compat warning instead of an error,
-    // so we stop compilation before emitting this error in this test.
-    let _ = [0; foo::<T>()];
-
+    let _ = [0; foo::<T>()]; //~ ERROR constant expression depends on a generic parameter
     let _ = [0; bar::<N>()]; //~ ERROR generic parameters may not
+                             //~^ ERROR unresolved item provided when a constant was expected
     let _ = [0; faz::<'a>(&())]; //~ ERROR a non-static lifetime
+                                 //~^ ERROR cannot specify lifetime arguments
     let _ = [0; baz::<'a>(&())]; //~ ERROR a non-static lifetime
     let _ = [0; faz::<'b>(&())]; //~ ERROR a non-static lifetime
+                                 //~^ ERROR cannot specify lifetime arguments
     let _ = [0; baz::<'b>(&())]; //~ ERROR a non-static lifetime
     let _: Foo<{ foo::<T>() }>; //~ ERROR generic parameters may not
     let _: Foo<{ bar::<N>() }>; //~ ERROR generic parameters may not
+                                //~^ ERROR unresolved item provided when a constant was expected
     let _: Foo<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime
+                                    //~^ ERROR cannot specify lifetime arguments
     let _: Foo<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime
     let _: Foo<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime
+                                    //~^ ERROR cannot specify lifetime arguments
     let _: Foo<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime
     let _ = Foo::<{ foo::<T>() }>; //~ ERROR generic parameters may not
     let _ = Foo::<{ bar::<N>() }>; //~ ERROR generic parameters may not
+                                   //~^ ERROR unresolved item provided when a constant was expected
     let _ = Foo::<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime
+                                       //~^ ERROR cannot specify lifetime arguments
     let _ = Foo::<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime
     let _ = Foo::<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime
+                                       //~^ ERROR cannot specify lifetime arguments
     let _ = Foo::<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-56445-1.min.stderr b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr
index 179643a7552..43a5df117fd 100644
--- a/src/test/ui/const-generics/issues/issue-56445-1.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr
@@ -6,6 +6,15 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
    |
    = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
 
-error: aborting due to previous error
+error: `&'static str` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-56445-1.rs:9:25
+   |
+LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
+   |                         ^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0771`.
diff --git a/src/test/ui/const-generics/issues/issue-56445-1.rs b/src/test/ui/const-generics/issues/issue-56445-1.rs
index aeef778991f..13eb2ea9f69 100644
--- a/src/test/ui/const-generics/issues/issue-56445-1.rs
+++ b/src/test/ui/const-generics/issues/issue-56445-1.rs
@@ -8,5 +8,6 @@ use std::marker::PhantomData;
 
 struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
 //~^ ERROR: use of non-static lifetime `'a` in const generic
+//[min]~| ERROR: `&'static str` is forbidden as the type of a const generic parameter
 
 impl Bug<'_, ""> {}
diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr
index 5a16d5845a6..3ab727f5f69 100644
--- a/src/test/ui/error-codes/E0771.stderr
+++ b/src/test/ui/error-codes/E0771.stderr
@@ -1,3 +1,11 @@
+error[E0771]: use of non-static lifetime `'a` in const generic
+  --> $DIR/E0771.rs:4:41
+   |
+LL | fn function_with_str<'a, const STRING: &'a str>() {}
+   |                                         ^^
+   |
+   = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
+
 warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/E0771.rs:1:12
    |
@@ -7,14 +15,6 @@ LL | #![feature(adt_const_params)]
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
 
-error[E0771]: use of non-static lifetime `'a` in const generic
-  --> $DIR/E0771.rs:4:41
-   |
-LL | fn function_with_str<'a, const STRING: &'a str>() {}
-   |                                         ^^
-   |
-   = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
-
 error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0771`.