about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_error_codes/error_codes.rs1
-rw-r--r--src/librustc_error_codes/error_codes/E0671.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0770.md15
-rw-r--r--src/librustc_hir/hir.rs6
-rw-r--r--src/librustc_resolve/diagnostics.rs13
-rw-r--r--src/librustc_resolve/late.rs14
-rw-r--r--src/librustc_resolve/lib.rs34
-rw-r--r--src/librustc_typeck/collect.rs61
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-const-param.rs15
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr24
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs2
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr16
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.rs11
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr19
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.rs10
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.stderr17
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.rs2
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.stderr17
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.stderr9
-rw-r--r--src/test/ui/const-generics/issues/issue-73491.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-74101.rs9
22 files changed, 271 insertions, 36 deletions
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 60aa12b0511..6160450d766 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -452,6 +452,7 @@ E0766: include_str!("./error_codes/E0766.md"),
 E0767: include_str!("./error_codes/E0767.md"),
 E0768: include_str!("./error_codes/E0768.md"),
 E0769: include_str!("./error_codes/E0769.md"),
+E0770: include_str!("./error_codes/E0770.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/src/librustc_error_codes/error_codes/E0671.md b/src/librustc_error_codes/error_codes/E0671.md
index 449fb8ffc89..a993ce826a7 100644
--- a/src/librustc_error_codes/error_codes/E0671.md
+++ b/src/librustc_error_codes/error_codes/E0671.md
@@ -3,7 +3,7 @@
 Const parameters cannot depend on type parameters.
 The following is therefore invalid:
 
-```compile_fail,E0741
+```compile_fail,E0770
 #![feature(const_generics)]
 
 fn const_id<T, const N: T>() -> T { // error
diff --git a/src/librustc_error_codes/error_codes/E0770.md b/src/librustc_error_codes/error_codes/E0770.md
new file mode 100644
index 00000000000..278bf9b907b
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0770.md
@@ -0,0 +1,15 @@
+The type of a const parameter references other generic parameters.
+
+Erroneous code example:
+
+```compile_fail,E0770
+#![feature(const_generics)]
+fn foo<T, const N: T>() {} // error!
+```
+
+To fix this error, use a concrete type for the const parameter:
+
+```
+#![feature(const_generics)]
+fn foo<T, const N: usize>() {}
+```
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index 07b489a7562..9204f778a24 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -2687,7 +2687,7 @@ pub enum Node<'hir> {
     Crate(&'hir CrateItem<'hir>),
 }
 
-impl Node<'_> {
+impl<'hir> Node<'hir> {
     pub fn ident(&self) -> Option<Ident> {
         match self {
             Node::TraitItem(TraitItem { ident, .. })
@@ -2698,7 +2698,7 @@ impl Node<'_> {
         }
     }
 
-    pub fn fn_decl(&self) -> Option<&FnDecl<'_>> {
+    pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> {
         match self {
             Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
             | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
@@ -2722,7 +2722,7 @@ impl Node<'_> {
         }
     }
 
-    pub fn generics(&self) -> Option<&Generics<'_>> {
+    pub fn generics(&self) -> Option<&'hir Generics<'hir>> {
         match self {
             Node::TraitItem(TraitItem { generics, .. })
             | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 4f25b948eb6..575049c6bac 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -442,6 +442,19 @@ impl<'a> Resolver<'a> {
                 );
                 err
             }
+            ResolutionError::ParamInTyOfConstArg(name) => {
+                let mut err = struct_span_err!(
+                    self.session,
+                    span,
+                    E0770,
+                    "the type of const parameters must not depend on other generic parameters"
+                );
+                err.span_label(
+                    span,
+                    format!("the type must not depend on the parameter `{}`", name),
+                );
+                err
+            }
             ResolutionError::SelfInTyParamDefault => {
                 let mut err = struct_span_err!(
                     self.session,
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 274f93dd50b..ed88e549692 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -123,6 +123,10 @@ crate enum RibKind<'a> {
     /// from the default of a type parameter because they're not declared
     /// before said type parameter. Also see the `visit_generics` override.
     ForwardTyParamBanRibKind,
+
+    /// We are inside of the type of a const parameter. Can't refer to any
+    /// parameters.
+    ConstParamTyRibKind,
 }
 
 impl RibKind<'_> {
@@ -135,7 +139,8 @@ impl RibKind<'_> {
             | FnItemRibKind
             | ConstantItemRibKind
             | ModuleRibKind(_)
-            | MacroDefinition(_) => false,
+            | MacroDefinition(_)
+            | ConstParamTyRibKind => false,
             AssocItemRibKind | ItemRibKind(_) | ForwardTyParamBanRibKind => true,
         }
     }
@@ -576,7 +581,11 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                     for bound in &param.bounds {
                         self.visit_param_bound(bound);
                     }
+                    self.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
+                    self.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
                     self.visit_ty(ty);
+                    self.ribs[TypeNS].pop().unwrap();
+                    self.ribs[ValueNS].pop().unwrap();
                 }
             }
         }
@@ -814,7 +823,8 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 | ItemRibKind(..)
                 | ConstantItemRibKind
                 | ModuleRibKind(..)
-                | ForwardTyParamBanRibKind => {
+                | ForwardTyParamBanRibKind
+                | ConstParamTyRibKind => {
                     return false;
                 }
             }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a265c15c18b..c3686ca4899 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -214,6 +214,8 @@ enum ResolutionError<'a> {
     BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
     /// Error E0128: type parameters with a default cannot use forward-declared identifiers.
     ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
+    /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
+    ParamInTyOfConstArg(Symbol),
     /// Error E0735: type parameters with a default cannot use `Self`
     SelfInTyParamDefault,
     /// Error E0767: use of unreachable label
@@ -2480,6 +2482,12 @@ impl<'a> Resolver<'a> {
                             }
                             return Res::Err;
                         }
+                        ConstParamTyRibKind => {
+                            if record_used {
+                                self.report_error(span, ParamInTyOfConstArg(rib_ident.name));
+                            }
+                            return Res::Err;
+                        }
                     }
                 }
                 if let Some(res_err) = res_err {
@@ -2503,6 +2511,15 @@ impl<'a> Resolver<'a> {
                         // This was an attempt to use a type parameter outside its scope.
                         ItemRibKind(has_generic_params) => has_generic_params,
                         FnItemRibKind => HasGenericParams::Yes,
+                        ConstParamTyRibKind => {
+                            if record_used {
+                                self.report_error(
+                                    span,
+                                    ResolutionError::ParamInTyOfConstArg(rib_ident.name),
+                                );
+                            }
+                            return Res::Err;
+                        }
                     };
 
                     if record_used {
@@ -2527,9 +2544,24 @@ impl<'a> Resolver<'a> {
                 }
                 for rib in ribs {
                     let has_generic_params = match rib.kind {
+                        NormalRibKind
+                        | ClosureOrAsyncRibKind
+                        | AssocItemRibKind
+                        | ModuleRibKind(..)
+                        | MacroDefinition(..)
+                        | ForwardTyParamBanRibKind
+                        | ConstantItemRibKind => continue,
                         ItemRibKind(has_generic_params) => has_generic_params,
                         FnItemRibKind => HasGenericParams::Yes,
-                        _ => continue,
+                        ConstParamTyRibKind => {
+                            if record_used {
+                                self.report_error(
+                                    span,
+                                    ResolutionError::ParamInTyOfConstArg(rib_ident.name),
+                                );
+                            }
+                            return Res::Err;
+                        }
                     };
 
                     // This was an attempt to use a const parameter outside its scope.
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 4354996614b..17212187e6a 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::weak_lang_items;
-use rustc_hir::{GenericParamKind, Node};
+use rustc_hir::{GenericParamKind, HirId, Node};
 use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::hir::map::Map;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -1155,6 +1155,35 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
     }
 }
 
+struct AnonConstInParamListDetector {
+    in_param_list: bool,
+    found_anon_const_in_list: bool,
+    ct: HirId,
+}
+
+impl<'v> Visitor<'v> for AnonConstInParamListDetector {
+    type Map = intravisit::ErasedMap<'v>;
+
+    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
+        NestedVisitorMap::None
+    }
+
+    fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
+        let prev = self.in_param_list;
+        self.in_param_list = true;
+        intravisit::walk_generic_param(self, p);
+        self.in_param_list = prev;
+    }
+
+    fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
+        if self.in_param_list && self.ct == c.hir_id {
+            self.found_anon_const_in_list = true;
+        } else {
+            intravisit::walk_anon_const(self, c)
+        }
+    }
+}
+
 fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
     use rustc_hir::*;
 
@@ -1176,10 +1205,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
             let parent_id = tcx.hir().get_parent_item(hir_id);
             let parent_def_id = tcx.hir().local_def_id(parent_id);
 
-            // HACK(eddyb) this provides the correct generics when
-            // `feature(const_generics)` is enabled, so that const expressions
-            // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
-            if tcx.lazy_normalization() {
+            let mut in_param_list = false;
+            for (_parent, node) in tcx.hir().parent_iter(hir_id) {
+                if let Some(generics) = node.generics() {
+                    let mut visitor = AnonConstInParamListDetector {
+                        in_param_list: false,
+                        found_anon_const_in_list: false,
+                        ct: hir_id,
+                    };
+
+                    visitor.visit_generics(generics);
+                    in_param_list = visitor.found_anon_const_in_list;
+                    break;
+                }
+            }
+
+            if in_param_list {
+                // We do not allow generic parameters in anon consts if we are inside
+                // of a param list.
+                //
+                // This affects both default type bindings, e.g. `struct<T, U = [u8; std::mem::size_of::<T>()]>(T, U)`,
+                // and the types of const parameters, e.g. `struct V<const N: usize, const M: [u8; N]>();`.
+                None
+            } else if tcx.lazy_normalization() {
+                // HACK(eddyb) this provides the correct generics when
+                // `feature(const_generics)` is enabled, so that const expressions
+                // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
                 Some(parent_def_id.to_def_id())
             } else {
                 let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs
new file mode 100644
index 00000000000..5aa3617d1d7
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs
@@ -0,0 +1,15 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete
+
+// Currently, const parameters cannot depend on other generic parameters,
+// as our current implementation can't really support this.
+//
+// We may want to lift this restriction in the future.
+
+pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
+//~^ ERROR: the type of const parameters must not depend on other generic parameters
+
+pub struct SelfDependent<const N: [u8; N]>;
+//~^ ERROR: the type of const parameters must not depend on other generic parameters
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr
new file mode 100644
index 00000000000..f6606aea726
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr
@@ -0,0 +1,24 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/const-param-type-depends-on-const-param.rs:9:52
+   |
+LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
+   |                                                    ^ the type must not depend on the parameter `N`
+
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/const-param-type-depends-on-const-param.rs:12:40
+   |
+LL | pub struct SelfDependent<const N: [u8; N]>;
+   |                                        ^ the type must not depend on the parameter `N`
+
+warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/const-param-type-depends-on-const-param.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
index 86ab8075896..db15ececfa4 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
@@ -1,6 +1,6 @@
 use std::marker::PhantomData;
 
 struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
-//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
+//~^ ERROR the type of const parameters must not depend on other generic parameters
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
index 92a7edf96bc..35996e83361 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
@@ -1,3 +1,9 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
+   |
+LL | struct B<T, const N: T>(PhantomData<[T; N]>);
+   |                      ^ the type must not depend on the parameter `T`
+
 error[E0658]: const generics are unstable
   --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19
    |
@@ -7,15 +13,7 @@ LL | struct B<T, const N: T>(PhantomData<[T; N]>);
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
-error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
-  --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
-   |
-LL | struct B<T, const N: T>(PhantomData<[T; N]>);
-   |                      ^ `T` may not derive both `PartialEq` and `Eq`
-   |
-   = note: it is not currently possible to use a type parameter as the type of a const parameter
-
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0658, E0741.
+Some errors have detailed explanations: E0658, E0770.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
index 654e36df37e..7fe04a43412 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
@@ -1,12 +1,13 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete
 
-// Currently, const parameters cannot depend on type parameters, because there is no way to
-// enforce the structural-match property on an arbitrary type parameter. This restriction
-// may be relaxed in the future. See https://github.com/rust-lang/rfcs/pull/2000 for more
-// details.
+// Currently, const parameters cannot depend on other generic parameters,
+// as our current implementation can't really support this.
+//
+// We may want to lift this restriction in the future.
 
 pub struct Dependent<T, const X: T>([(); X]);
-//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
+//~^ ERROR: the type of const parameters must not depend on other generic parameters
+//~| ERROR: parameter `T` is never used
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr
index ed05264161e..d081dcbbc7a 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr
@@ -1,3 +1,9 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/const-param-type-depends-on-type-param.rs:9:34
+   |
+LL | pub struct Dependent<T, const X: T>([(); X]);
+   |                                  ^ the type must not depend on the parameter `T`
+
 warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/const-param-type-depends-on-type-param.rs:1:12
    |
@@ -7,14 +13,15 @@ LL | #![feature(const_generics)]
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
 
-error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
-  --> $DIR/const-param-type-depends-on-type-param.rs:9:34
+error[E0392]: parameter `T` is never used
+  --> $DIR/const-param-type-depends-on-type-param.rs:9:22
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
-   |                                  ^ `T` may not derive both `PartialEq` and `Eq`
+   |                      ^ unused parameter
    |
-   = note: it is not currently possible to use a type parameter as the type of a const parameter
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0741`.
+Some errors have detailed explanations: E0392, E0770.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/src/test/ui/const-generics/issues/issue-71169.rs b/src/test/ui/const-generics/issues/issue-71169.rs
new file mode 100644
index 00000000000..943a16cfcd6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71169.rs
@@ -0,0 +1,10 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
+//~^ ERROR the type of const parameters must not
+fn main() {
+    const DATA: [u8; 4] = *b"ABCD";
+    foo::<4, DATA>();
+    //~^ ERROR constant expression depends on
+}
diff --git a/src/test/ui/const-generics/issues/issue-71169.stderr b/src/test/ui/const-generics/issues/issue-71169.stderr
new file mode 100644
index 00000000000..6d4cf4027c1
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71169.stderr
@@ -0,0 +1,17 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71169.rs:4:43
+   |
+LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
+   |                                           ^^^ the type must not depend on the parameter `LEN`
+
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-71169.rs:8:14
+   |
+LL |     foo::<4, DATA>();
+   |              ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-71381.rs b/src/test/ui/const-generics/issues/issue-71381.rs
index c32bd2847f8..08f94823942 100644
--- a/src/test/ui/const-generics/issues/issue-71381.rs
+++ b/src/test/ui/const-generics/issues/issue-71381.rs
@@ -12,6 +12,7 @@ unsafe extern "C" fn pass(args: PassArg) {
 impl Test {
     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
         //~^ ERROR: using function pointers as const generic parameters is forbidden
+        //~| ERROR: the type of const parameters must not depend on other generic parameters
         self.0 = Self::trampiline::<Args, IDX, FN> as _
     }
 
@@ -20,6 +21,7 @@ impl Test {
         const IDX: usize,
         const FN: unsafe extern "C" fn(Args),
         //~^ ERROR: using function pointers as const generic parameters is forbidden
+        //~| ERROR: the type of const parameters must not depend on other generic parameters
     >(
         args: Args,
     ) {
diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.stderr
index 6bb776fcfc0..fd4ebe3dead 100644
--- a/src/test/ui/const-generics/issues/issue-71381.stderr
+++ b/src/test/ui/const-generics/issues/issue-71381.stderr
@@ -1,3 +1,15 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71381.rs:13:82
+   |
+LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
+   |                                                                                  ^^^^ the type must not depend on the parameter `Args`
+
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71381.rs:22:40
+   |
+LL |         const FN: unsafe extern "C" fn(Args),
+   |                                        ^^^^ the type must not depend on the parameter `Args`
+
 error: using function pointers as const generic parameters is forbidden
   --> $DIR/issue-71381.rs:13:61
    |
@@ -5,10 +17,11 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:21:19
+  --> $DIR/issue-71381.rs:22:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-71611.rs b/src/test/ui/const-generics/issues/issue-71611.rs
index 64a049e743f..06ff38dec66 100644
--- a/src/test/ui/const-generics/issues/issue-71611.rs
+++ b/src/test/ui/const-generics/issues/issue-71611.rs
@@ -3,6 +3,7 @@
 
 fn func<A, const F: fn(inner: A)>(outer: A) {
     //~^ ERROR: using function pointers as const generic parameters is forbidden
+    //~| ERROR: the type of const parameters must not depend on other generic parameters
     F(outer);
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.stderr
index 9a7bf1c0a88..e2c9f22361e 100644
--- a/src/test/ui/const-generics/issues/issue-71611.stderr
+++ b/src/test/ui/const-generics/issues/issue-71611.stderr
@@ -1,8 +1,15 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71611.rs:4:31
+   |
+LL | fn func<A, const F: fn(inner: A)>(outer: A) {
+   |                               ^ the type must not depend on the parameter `A`
+
 error: using function pointers as const generic parameters is forbidden
   --> $DIR/issue-71611.rs:4:21
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                     ^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-73491.rs b/src/test/ui/const-generics/issues/issue-73491.rs
new file mode 100644
index 00000000000..05e1513bb75
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-73491.rs
@@ -0,0 +1,9 @@
+// check-pass
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+const LEN: usize = 1024;
+
+fn hoge<const IN: [u32; LEN]>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-74101.rs b/src/test/ui/const-generics/issues/issue-74101.rs
new file mode 100644
index 00000000000..2f427ef3a27
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-74101.rs
@@ -0,0 +1,9 @@
+// check-pass
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+fn test<const N: [u8; 1 + 2]>() {}
+
+struct Foo<const N: [u8; 1 + 2]>;
+
+fn main() {}