about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2025-03-12 10:19:28 -0700
committerGitHub <noreply@github.com>2025-03-12 10:19:28 -0700
commit2d7a592c62f162d3f96192e2381bb1afbcb94e42 (patch)
tree26d1365a109659ce2e562c5e3f1eb2266591288e
parent40c7a9014eb4cad066f6d990d0e0527faf877dab (diff)
parent42773bfcac71decb4058ca1c3b4eff816235549f (diff)
downloadrust-2d7a592c62f162d3f96192e2381bb1afbcb94e42.tar.gz
rust-2d7a592c62f162d3f96192e2381bb1afbcb94e42.zip
Rollup merge of #138259 - compiler-errors:disentangle-ribs, r=BoxyUwU
Disentangle `ForwardGenericParamBan` and `ConstParamTy` ribs

In #137617, the `ConstParamTy` rib was adjusted to act kinda like the `ForwardGenericParamBan`. However, this means that it no longer served its purpose banning generics from *parent items*. Although we still are checking for param type validity using the `ConstParamTy_` trait, which means that we weren't accepting code we shouldn't, I think it's a bit strange for us not to be rejecting code like this during *resolution* and instead letting these malformed const generics leak into the type system:

```rust
trait Foo<T> {
  fn bar<const N: T>() {}
}
```

This PR does a few things:
1. Introduce a `ForwardGenericParamBanReason` enum, and start using the `ForwardGenericParamBan` rib to ban forward-declared params in const tys when `generic_const_parameter_types` is enabled.
2. Start using the `ConstParamTy` rib to ban *all* generics when `generic_const_parameter_types` is disabled.
3. Improve the diagnostics for both of the cases above, and for forward-declared params in parameter defaults too :3

r? `@BoxyUwU` or reassign
-rw-r--r--compiler/rustc_resolve/messages.ftl12
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs30
-rw-r--r--compiler/rustc_resolve/src/errors.rs18
-rw-r--r--compiler/rustc_resolve/src/ident.rs61
-rw-r--r--compiler/rustc_resolve/src/late.rs42
-rw-r--r--compiler/rustc_resolve/src/lib.rs9
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-const-param.rs8
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-parent-param.rs8
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr9
-rw-r--r--tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr6
-rw-r--r--tests/ui/const-generics/defaults/forward-declared.rs8
-rw-r--r--tests/ui/const-generics/defaults/forward-declared.stderr16
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs4
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr9
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr15
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs5
-rw-r--r--tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr4
-rw-r--r--tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr4
-rw-r--r--tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs2
-rw-r--r--tests/ui/error-codes/E0128.stderr4
-rw-r--r--tests/ui/generics/generic-non-trailing-defaults.rs2
-rw-r--r--tests/ui/generics/generic-non-trailing-defaults.stderr4
-rw-r--r--tests/ui/generics/generic-type-params-forward-mention.rs2
-rw-r--r--tests/ui/generics/generic-type-params-forward-mention.stderr4
-rw-r--r--tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr12
-rw-r--r--tests/ui/issues/issue-18183.stderr4
-rw-r--r--tests/ui/issues/issue-26812.rs2
-rw-r--r--tests/ui/issues/issue-26812.stderr4
29 files changed, 196 insertions, 114 deletions
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 9f062b3935f..817aa5b4385 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -153,9 +153,13 @@ resolve_extern_crate_self_requires_renaming =
     `extern crate self;` requires renaming
     .suggestion = rename the `self` crate to be able to import it
 
+resolve_forward_declared_generic_in_const_param_ty =
+    const parameter types cannot reference parameters before they are declared
+    .label = const parameter type cannot reference `{$param}` before it is declared
+
 resolve_forward_declared_generic_param =
-    generic parameters with a default cannot use forward declared identifiers
-    .label = defaulted generic parameters cannot be forward declared
+    generic parameter defaults cannot reference parameters before they are declared
+    .label = cannot reference `{$param}` before it is declared
 
 resolve_found_an_item_configured_out =
     found an item that was configured out
@@ -377,9 +381,11 @@ resolve_self_imports_only_allowed_within_multipart_suggestion =
 resolve_self_imports_only_allowed_within_suggestion =
     consider importing the module directly
 
+resolve_self_in_const_generic_ty =
+    cannot use `Self` in const parameter type
+
 resolve_self_in_generic_param_default =
     generic parameters cannot use `Self` in their defaults
-    .label = `Self` in generic parameter default
 
 resolve_similarly_named_defined_here =
     similarly named {$candidate_descr} `{$candidate}` defined here
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 88d1126de1a..41f4254eede 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -42,10 +42,10 @@ use crate::imports::{Import, ImportKind};
 use crate::late::{PatternSource, Rib};
 use crate::{
     AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
-    HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, ModuleKind,
-    ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError,
-    ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError,
-    errors as errs, path_names_to_string,
+    ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
+    ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
+    PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
+    VisResolutionError, errors as errs, path_names_to_string,
 };
 
 type Res = def::Res<ast::NodeId>;
@@ -887,9 +887,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 participle,
                 name,
             }),
-            ResolutionError::ForwardDeclaredGenericParam => {
-                self.dcx().create_err(errs::ForwardDeclaredGenericParam { span })
-            }
+            ResolutionError::ForwardDeclaredGenericParam(param, reason) => match reason {
+                ForwardGenericParamBanReason::Default => {
+                    self.dcx().create_err(errs::ForwardDeclaredGenericParam { param, span })
+                }
+                ForwardGenericParamBanReason::ConstParamTy => self
+                    .dcx()
+                    .create_err(errs::ForwardDeclaredGenericInConstParamTy { param, span }),
+            },
             ResolutionError::ParamInTyOfConstParam { name } => {
                 self.dcx().create_err(errs::ParamInTyOfConstParam { span, name })
             }
@@ -908,9 +913,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
                 .dcx()
                 .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
-            ResolutionError::SelfInGenericParamDefault => {
-                self.dcx().create_err(errs::SelfInGenericParamDefault { span })
-            }
+            ResolutionError::ForwardDeclaredSelf(reason) => match reason {
+                ForwardGenericParamBanReason::Default => {
+                    self.dcx().create_err(errs::SelfInGenericParamDefault { span })
+                }
+                ForwardGenericParamBanReason::ConstParamTy => {
+                    self.dcx().create_err(errs::SelfInConstGenericTy { span })
+                }
+            },
             ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
                 let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
                     match suggestion {
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index b5d3e5ea776..2ae6892bc93 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -338,6 +338,16 @@ pub(crate) struct ForwardDeclaredGenericParam {
     #[primary_span]
     #[label]
     pub(crate) span: Span,
+    pub(crate) param: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_forward_declared_generic_in_const_param_ty)]
+pub(crate) struct ForwardDeclaredGenericInConstParamTy {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) param: Symbol,
 }
 
 #[derive(Diagnostic)]
@@ -353,7 +363,13 @@ pub(crate) struct ParamInTyOfConstParam {
 #[diag(resolve_self_in_generic_param_default, code = E0735)]
 pub(crate) struct SelfInGenericParamDefault {
     #[primary_span]
-    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_in_const_generic_ty)]
+pub(crate) struct SelfInConstGenericTy {
+    #[primary_span]
     pub(crate) span: Span,
 }
 
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index d9776be4dd0..5f0a2a597e9 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1117,13 +1117,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         debug!("validate_res_from_ribs({:?})", res);
         let ribs = &all_ribs[rib_index + 1..];
 
-        // An invalid forward use of a generic parameter from a previous default.
-        if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
+        // An invalid forward use of a generic parameter from a previous default
+        // or in a const param ty.
+        if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
             if let Some(span) = finalize {
                 let res_error = if rib_ident.name == kw::SelfUpper {
-                    ResolutionError::SelfInGenericParamDefault
+                    ResolutionError::ForwardDeclaredSelf(reason)
                 } else {
-                    ResolutionError::ForwardDeclaredGenericParam
+                    ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
                 };
                 self.report_error(span, res_error);
             }
@@ -1131,17 +1132,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             return Res::Err;
         }
 
-        if let RibKind::ConstParamTy = all_ribs[rib_index].kind {
-            if let Some(span) = finalize {
-                self.report_error(
-                    span,
-                    ResolutionError::ParamInTyOfConstParam { name: rib_ident.name },
-                );
-            }
-            assert_eq!(res, Res::Err);
-            return Res::Err;
-        }
-
         match res {
             Res::Local(_) => {
                 use ResolutionError::*;
@@ -1153,7 +1143,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         | RibKind::FnOrCoroutine
                         | RibKind::Module(..)
                         | RibKind::MacroDefinition(..)
-                        | RibKind::ForwardGenericParamBan => {
+                        | RibKind::ForwardGenericParamBan(_) => {
                             // Nothing to do. Continue.
                         }
                         RibKind::Item(..) | RibKind::AssocItem => {
@@ -1247,12 +1237,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         | RibKind::MacroDefinition(..)
                         | RibKind::InlineAsmSym
                         | RibKind::AssocItem
-                        | RibKind::ConstParamTy
-                        | RibKind::ForwardGenericParamBan => {
+                        | RibKind::ForwardGenericParamBan(_) => {
                             // Nothing to do. Continue.
                             continue;
                         }
 
+                        RibKind::ConstParamTy => {
+                            if !self.tcx.features().generic_const_parameter_types() {
+                                if let Some(span) = finalize {
+                                    self.report_error(
+                                        span,
+                                        ResolutionError::ParamInTyOfConstParam {
+                                            name: rib_ident.name,
+                                        },
+                                    );
+                                }
+                                return Res::Err;
+                            } else {
+                                continue;
+                            }
+                        }
+
                         RibKind::ConstantItem(trivial, _) => {
                             if let ConstantHasGenerics::No(cause) = trivial {
                                 // HACK(min_const_generics): If we encounter `Self` in an anonymous
@@ -1325,8 +1330,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         | RibKind::MacroDefinition(..)
                         | RibKind::InlineAsmSym
                         | RibKind::AssocItem
-                        | RibKind::ConstParamTy
-                        | RibKind::ForwardGenericParamBan => continue,
+                        | RibKind::ForwardGenericParamBan(_) => continue,
+
+                        RibKind::ConstParamTy => {
+                            if !self.tcx.features().generic_const_parameter_types() {
+                                if let Some(span) = finalize {
+                                    self.report_error(
+                                        span,
+                                        ResolutionError::ParamInTyOfConstParam {
+                                            name: rib_ident.name,
+                                        },
+                                    );
+                                }
+                                return Res::Err;
+                            } else {
+                                continue;
+                            }
+                        }
 
                         RibKind::ConstantItem(trivial, _) => {
                             if let ConstantHasGenerics::No(cause) = trivial {
@@ -1377,6 +1397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             }
             _ => {}
         }
+
         res
     }
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 2c3e4bb505c..d28988cd74f 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -207,7 +207,7 @@ pub(crate) enum RibKind<'ra> {
     /// All bindings in this rib are generic parameters that can't be used
     /// from the default of a generic parameter because they're not declared
     /// before said generic parameter. Also see the `visit_generics` override.
-    ForwardGenericParamBan,
+    ForwardGenericParamBan(ForwardGenericParamBanReason),
 
     /// We are inside of the type of a const parameter. Can't refer to any
     /// parameters.
@@ -218,6 +218,12 @@ pub(crate) enum RibKind<'ra> {
     InlineAsmSym,
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub(crate) enum ForwardGenericParamBanReason {
+    Default,
+    ConstParamTy,
+}
+
 impl RibKind<'_> {
     /// Whether this rib kind contains generic parameters, as opposed to local
     /// variables.
@@ -232,7 +238,7 @@ impl RibKind<'_> {
             RibKind::ConstParamTy
             | RibKind::AssocItem
             | RibKind::Item(..)
-            | RibKind::ForwardGenericParamBan => true,
+            | RibKind::ForwardGenericParamBan(_) => true,
         }
     }
 
@@ -246,7 +252,7 @@ impl RibKind<'_> {
             | RibKind::Item(..)
             | RibKind::ConstantItem(..)
             | RibKind::Module(..)
-            | RibKind::ForwardGenericParamBan
+            | RibKind::ForwardGenericParamBan(_)
             | RibKind::ConstParamTy
             | RibKind::InlineAsmSym => true,
         }
@@ -1561,8 +1567,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         // provide previous type parameters as they're built. We
         // put all the parameters on the ban list and then remove
         // them one by one as they are processed and become available.
-        let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
-        let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
+        let mut forward_ty_ban_rib =
+            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
+        let mut forward_const_ban_rib =
+            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
         for param in params.iter() {
             match param.kind {
                 GenericParamKind::Type { .. } => {
@@ -1593,16 +1601,24 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
         }
 
+        // NOTE: We use different ribs here not for a technical reason, but just
+        // for better diagnostics.
         let mut forward_ty_ban_rib_const_param_ty = Rib {
             bindings: forward_ty_ban_rib.bindings.clone(),
             patterns_with_skipped_bindings: FxHashMap::default(),
-            kind: RibKind::ConstParamTy,
+            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
         };
         let mut forward_const_ban_rib_const_param_ty = Rib {
             bindings: forward_const_ban_rib.bindings.clone(),
             patterns_with_skipped_bindings: FxHashMap::default(),
-            kind: RibKind::ConstParamTy,
+            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
         };
+        // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
+        // diagnostics, so we don't mention anything about const param tys having generics at all.
+        if !self.r.tcx.features().generic_const_parameter_types() {
+            forward_ty_ban_rib_const_param_ty.bindings.clear();
+            forward_const_ban_rib_const_param_ty.bindings.clear();
+        }
 
         self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
             for param in params {
@@ -1628,9 +1644,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         // Allow all following defaults to refer to this type parameter.
                         let i = &Ident::with_dummy_span(param.ident.name);
                         forward_ty_ban_rib.bindings.remove(i);
-                        if this.r.tcx.features().generic_const_parameter_types() {
-                            forward_ty_ban_rib_const_param_ty.bindings.remove(i);
-                        }
+                        forward_ty_ban_rib_const_param_ty.bindings.remove(i);
                     }
                     GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
                         // Const parameters can't have param bounds.
@@ -1641,9 +1655,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         if this.r.tcx.features().generic_const_parameter_types() {
                             this.visit_ty(ty)
                         } else {
+                            this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
+                            this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
                             this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
                                 this.visit_ty(ty)
                             });
+                            this.ribs[TypeNS].pop().unwrap();
+                            this.ribs[ValueNS].pop().unwrap();
                         }
                         forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
                         forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
@@ -1662,9 +1680,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         // Allow all following defaults to refer to this const parameter.
                         let i = &Ident::with_dummy_span(param.ident.name);
                         forward_const_ban_rib.bindings.remove(i);
-                        if this.r.tcx.features().generic_const_parameter_types() {
-                            forward_const_ban_rib_const_param_ty.bindings.remove(i);
-                        }
+                        forward_const_ban_rib_const_param_ty.bindings.remove(i);
                     }
                 }
             }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index ccdca855232..e6fc390f24c 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -32,7 +32,10 @@ use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
 use effective_visibilities::EffectiveVisibilitiesVisitor;
 use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
 use imports::{Import, ImportData, ImportKind, NameResolution};
-use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification};
+use late::{
+    ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
+    UnnecessaryQualification,
+};
 use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
 use rustc_arena::{DroplessArena, TypedArena};
 use rustc_ast::expand::StrippedCfgItem;
@@ -273,7 +276,7 @@ enum ResolutionError<'ra> {
         shadowed_binding_span: Span,
     },
     /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
-    ForwardDeclaredGenericParam,
+    ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason),
     // FIXME(generic_const_parameter_types): This should give custom output specifying it's only
     // problematic to use *forward declared* parameters when the feature is enabled.
     /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
@@ -287,7 +290,7 @@ enum ResolutionError<'ra> {
     /// This error is emitted even with `generic_const_exprs`.
     ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
     /// Error E0735: generic parameters with a default cannot use `Self`
-    SelfInGenericParamDefault,
+    ForwardDeclaredSelf(ForwardGenericParamBanReason),
     /// Error E0767: use of unreachable label
     UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },
     /// Error E0323, E0324, E0325: mismatch between trait item and impl item.
diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs
index ee0e1326baa..3372ea5b853 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs
+++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs
@@ -9,11 +9,11 @@
 // 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
-//[min]~^^ ERROR `[u8; N]` is forbidden
+//~^ ERROR the type of const parameters must not depend on other generic parameters
+//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter
 
 pub struct SelfDependent<const N: [u8; N]>;
-//~^ ERROR: the type of const parameters must not depend on other generic parameters
-//[min]~^^ ERROR `[u8; N]` is forbidden
+//~^ ERROR the type of const parameters must not depend on other generic parameters
+//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter
 
 fn main() {}
diff --git a/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs b/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs
new file mode 100644
index 00000000000..83fe8c139f9
--- /dev/null
+++ b/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs
@@ -0,0 +1,8 @@
+#![feature(adt_const_params)]
+
+trait Trait<const N: usize> {
+    fn foo<const M: [u8; N]>() {}
+    //~^ ERROR the type of const parameters must not depend on other generic parameters
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr b/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr
new file mode 100644
index 00000000000..ed0a4b118d4
--- /dev/null
+++ b/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr
@@ -0,0 +1,9 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/const-param-type-depends-on-parent-param.rs:4:26
+   |
+LL |     fn foo<const M: [u8; N]>() {}
+   |                          ^ the type must not depend on the parameter `N`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr b/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr
index 72d7001fdf1..c074e2e897e 100644
--- a/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr
+++ b/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr
@@ -2,19 +2,19 @@ error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/default-const-param-cannot-reference-self.rs:1:34
    |
 LL | struct Struct<const N: usize = { Self; 10 }>;
-   |                                  ^^^^ `Self` in generic parameter default
+   |                                  ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/default-const-param-cannot-reference-self.rs:4:30
    |
 LL | enum Enum<const N: usize = { Self; 10 }> { }
-   |                              ^^^^ `Self` in generic parameter default
+   |                              ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/default-const-param-cannot-reference-self.rs:7:32
    |
 LL | union Union<const N: usize = { Self; 10 }> { not_empty: () }
-   |                                ^^^^ `Self` in generic parameter default
+   |                                ^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/const-generics/defaults/forward-declared.rs b/tests/ui/const-generics/defaults/forward-declared.rs
index ede3d873bdc..bd3abd4dcaa 100644
--- a/tests/ui/const-generics/defaults/forward-declared.rs
+++ b/tests/ui/const-generics/defaults/forward-declared.rs
@@ -1,13 +1,13 @@
 struct Foo<const N: usize = M, const M: usize = 10>;
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 
 enum Bar<const N: usize = M, const M: usize = 10> {}
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 
 struct Foo2<const N: usize = N>;
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 
 enum Bar2<const N: usize = N> {}
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 
 fn main() {}
diff --git a/tests/ui/const-generics/defaults/forward-declared.stderr b/tests/ui/const-generics/defaults/forward-declared.stderr
index 4856c7a1fd2..4331996bffc 100644
--- a/tests/ui/const-generics/defaults/forward-declared.stderr
+++ b/tests/ui/const-generics/defaults/forward-declared.stderr
@@ -1,26 +1,26 @@
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/forward-declared.rs:1:29
    |
 LL | struct Foo<const N: usize = M, const M: usize = 10>;
-   |                             ^ defaulted generic parameters cannot be forward declared
+   |                             ^ cannot reference `M` before it is declared
 
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/forward-declared.rs:4:27
    |
 LL | enum Bar<const N: usize = M, const M: usize = 10> {}
-   |                           ^ defaulted generic parameters cannot be forward declared
+   |                           ^ cannot reference `M` before it is declared
 
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/forward-declared.rs:7:30
    |
 LL | struct Foo2<const N: usize = N>;
-   |                              ^ defaulted generic parameters cannot be forward declared
+   |                              ^ cannot reference `N` before it is declared
 
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/forward-declared.rs:10:28
    |
 LL | enum Bar2<const N: usize = N> {}
-   |                            ^ defaulted generic parameters cannot be forward declared
+   |                            ^ cannot reference `N` before it is declared
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs
index 91c1c80e07c..2abf7f44e20 100644
--- a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs
+++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs
@@ -4,8 +4,8 @@
 use std::marker::PhantomData;
 
 struct UsesConst<const N: [u8; M], const M: usize>;
-//~^ ERROR: the type of const parameters must not depend on other generic parameters
+//~^ ERROR: const parameter types cannot reference parameters before they are declared
 struct UsesType<const N: [T; 2], T>(PhantomData<T>);
-//~^ ERROR: the type of const parameters must not depend on other generic parameters
+//~^ ERROR: const parameter types cannot reference parameters before they are declared
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr
index b0dbdff8413..5526668b0be 100644
--- a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr
+++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr
@@ -1,15 +1,14 @@
-error[E0770]: the type of const parameters must not depend on other generic parameters
+error: const parameter types cannot reference parameters before they are declared
   --> $DIR/forward_declared_type.rs:6:32
    |
 LL | struct UsesConst<const N: [u8; M], const M: usize>;
-   |                                ^ the type must not depend on the parameter `M`
+   |                                ^ const parameter type cannot reference `M` before it is declared
 
-error[E0770]: the type of const parameters must not depend on other generic parameters
+error: const parameter types cannot reference parameters before they are declared
   --> $DIR/forward_declared_type.rs:8:27
    |
 LL | struct UsesType<const N: [T; 2], T>(PhantomData<T>);
-   |                           ^ the type must not depend on the parameter `T`
+   |                           ^ const parameter type cannot reference `T` before it is declared
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr
index 29171c8006a..2d47797aef2 100644
--- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr
+++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr
@@ -16,7 +16,7 @@ LL |     type Assoc<const N: Self>;
    = note: the only supported types are integers, `bool`, and `char`
 
 error: anonymous constants referencing generics are not yet supported
-  --> $DIR/references-parent-generics.rs:14:21
+  --> $DIR/references-parent-generics.rs:15:21
    |
 LL |     let x: T::Assoc<3>;
    |                     ^
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr
index 64b41318814..68ce17317f6 100644
--- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr
+++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr
@@ -1,16 +1,9 @@
-error: `Self` is forbidden as the type of a const generic parameter
+error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/references-parent-generics.rs:7:25
    |
 LL |     type Assoc<const N: Self>;
-   |                         ^^^^
-   |
-   = note: the only supported types are integers, `bool`, and `char`
-
-error: anonymous constants referencing generics are not yet supported
-  --> $DIR/references-parent-generics.rs:14:21
-   |
-LL |     let x: T::Assoc<3>;
-   |                     ^
+   |                         ^^^^ the type must not depend on the parameter `Self`
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs
index 21994eb83b4..b91050d540c 100644
--- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs
+++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs
@@ -5,14 +5,15 @@
 
 trait Foo {
     type Assoc<const N: Self>;
-    //~^ ERROR `Self` is forbidden as the type of a const generic parameter
+    //[nofeat]~^ ERROR the type of const parameters must not depend on other generic parameters
+    //[feat]~^^ ERROR `Self` is forbidden as the type of a const generic parameter
 }
 
 fn foo<T: Foo>() {
     // We used to end up feeding the type of this anon const to be `T`, but the anon const
     // doesn't inherit the generics of `foo`, which led to index oob errors.
     let x: T::Assoc<3>;
-    //~^ ERROR anonymous constants referencing generics are not yet supported
+    //[feat]~^ ERROR anonymous constants referencing generics are not yet supported
 }
 
 fn main() {}
diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr
index 9f0b2efae96..dc28dea6851 100644
--- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr
+++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr
@@ -4,11 +4,11 @@ error: generic parameters with a default must be trailing
 LL | struct Bar<T = [u8; N], const N: usize>(T);
    |            ^
 
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21
    |
 LL | struct Bar<T = [u8; N], const N: usize>(T);
-   |                     ^ defaulted generic parameters cannot be forward declared
+   |                     ^ cannot reference `N` before it is declared
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
index 320c9c1c84d..3f0e5e96fc8 100644
--- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
+++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
@@ -13,11 +13,11 @@ LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
    = note: type parameters may not be used in const expressions
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21
    |
 LL | struct Bar<T = [u8; N], const N: usize>(T);
-   |                     ^ defaulted generic parameters cannot be forward declared
+   |                     ^ cannot reference `N` before it is declared
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
index 2794ff3eaa9..d212cc425a0 100644
--- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
+++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
@@ -6,7 +6,7 @@ struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
 //[min]~^ ERROR generic parameters may not be used in const operations
 
 struct Bar<T = [u8; N], const N: usize>(T);
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 //~| ERROR generic parameters with a default
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0128.stderr b/tests/ui/error-codes/E0128.stderr
index c1ccb4c9e74..22f1e200e29 100644
--- a/tests/ui/error-codes/E0128.stderr
+++ b/tests/ui/error-codes/E0128.stderr
@@ -1,8 +1,8 @@
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/E0128.rs:1:14
    |
 LL | struct Foo<T=U, U=()> {
-   |              ^ defaulted generic parameters cannot be forward declared
+   |              ^ cannot reference `U` before it is declared
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generics/generic-non-trailing-defaults.rs b/tests/ui/generics/generic-non-trailing-defaults.rs
index 16ea71d48c8..ef500c42068 100644
--- a/tests/ui/generics/generic-non-trailing-defaults.rs
+++ b/tests/ui/generics/generic-non-trailing-defaults.rs
@@ -5,6 +5,6 @@ struct Vec<A = Heap, T>(A, T);
 
 struct Foo<A, B = Vec<C>, C>(A, B, C);
 //~^ ERROR generic parameters with a default must be trailing
-//~| ERROR generic parameters with a default cannot use
+//~| ERROR generic parameter defaults cannot reference parameters before they are declared
 
 fn main() {}
diff --git a/tests/ui/generics/generic-non-trailing-defaults.stderr b/tests/ui/generics/generic-non-trailing-defaults.stderr
index 713ba091b86..d9057e932f5 100644
--- a/tests/ui/generics/generic-non-trailing-defaults.stderr
+++ b/tests/ui/generics/generic-non-trailing-defaults.stderr
@@ -10,11 +10,11 @@ error: generic parameters with a default must be trailing
 LL | struct Foo<A, B = Vec<C>, C>(A, B, C);
    |               ^
 
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/generic-non-trailing-defaults.rs:6:23
    |
 LL | struct Foo<A, B = Vec<C>, C>(A, B, C);
-   |                       ^ defaulted generic parameters cannot be forward declared
+   |                       ^ cannot reference `C` before it is declared
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/generics/generic-type-params-forward-mention.rs b/tests/ui/generics/generic-type-params-forward-mention.rs
index 000c47095d2..4a8f76d34aa 100644
--- a/tests/ui/generics/generic-type-params-forward-mention.rs
+++ b/tests/ui/generics/generic-type-params-forward-mention.rs
@@ -1,6 +1,6 @@
 // Ensure that we get an error and not an ICE for this problematic case.
 struct Foo<T = Option<U>, U = bool>(T, U);
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 fn main() {
     let x: Foo;
 }
diff --git a/tests/ui/generics/generic-type-params-forward-mention.stderr b/tests/ui/generics/generic-type-params-forward-mention.stderr
index d7a6faa1941..ecc2387b48b 100644
--- a/tests/ui/generics/generic-type-params-forward-mention.stderr
+++ b/tests/ui/generics/generic-type-params-forward-mention.stderr
@@ -1,8 +1,8 @@
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/generic-type-params-forward-mention.rs:2:23
    |
 LL | struct Foo<T = Option<U>, U = bool>(T, U);
-   |                       ^ defaulted generic parameters cannot be forward declared
+   |                       ^ cannot reference `U` before it is declared
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr b/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr
index f3a550801b9..f659a144def 100644
--- a/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr
+++ b/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr
@@ -2,37 +2,37 @@ error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:13:25
    |
 LL | struct Snobound<'a, P = Self> { x: Option<&'a P> }
-   |                         ^^^^ `Self` in generic parameter default
+   |                         ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:16:23
    |
 LL | enum Enobound<'a, P = Self> { A, B(Option<&'a P>) }
-   |                       ^^^^ `Self` in generic parameter default
+   |                       ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:19:24
    |
 LL | union Unobound<'a, P = Self> { x: i32, y: Option<&'a P> }
-   |                        ^^^^ `Self` in generic parameter default
+   |                        ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:25:31
    |
 LL | struct Ssized<'a, P: Sized = [Self]> { x: Option<&'a P> }
-   |                               ^^^^ `Self` in generic parameter default
+   |                               ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:28:29
    |
 LL | enum Esized<'a, P: Sized = [Self]> { A, B(Option<&'a P>) }
-   |                             ^^^^ `Self` in generic parameter default
+   |                             ^^^^
 
 error[E0735]: generic parameters cannot use `Self` in their defaults
   --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:31:30
    |
 LL | union Usized<'a, P: Sized = [Self]> { x: i32, y: Option<&'a P> }
-   |                              ^^^^ `Self` in generic parameter default
+   |                              ^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/issues/issue-18183.stderr b/tests/ui/issues/issue-18183.stderr
index 11015d75d97..07fa4cdc753 100644
--- a/tests/ui/issues/issue-18183.stderr
+++ b/tests/ui/issues/issue-18183.stderr
@@ -1,8 +1,8 @@
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/issue-18183.rs:1:20
    |
 LL | pub struct Foo<Bar=Bar>(Bar);
-   |                    ^^^ defaulted generic parameters cannot be forward declared
+   |                    ^^^ cannot reference `Bar` before it is declared
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-26812.rs b/tests/ui/issues/issue-26812.rs
index e0723e016b3..8eb030a8ec9 100644
--- a/tests/ui/issues/issue-26812.rs
+++ b/tests/ui/issues/issue-26812.rs
@@ -1,5 +1,5 @@
 fn avg<T=T::Item>(_: T) {}
-//~^ ERROR generic parameters with a default cannot use forward declared identifiers
+//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
 //~| ERROR defaults for type parameters
 //~| WARN previously accepted
 
diff --git a/tests/ui/issues/issue-26812.stderr b/tests/ui/issues/issue-26812.stderr
index 4a18b23fd8b..bb60d67e287 100644
--- a/tests/ui/issues/issue-26812.stderr
+++ b/tests/ui/issues/issue-26812.stderr
@@ -1,8 +1,8 @@
-error[E0128]: generic parameters with a default cannot use forward declared identifiers
+error[E0128]: generic parameter defaults cannot reference parameters before they are declared
   --> $DIR/issue-26812.rs:1:10
    |
 LL | fn avg<T=T::Item>(_: T) {}
-   |          ^^^^^^^ defaulted generic parameters cannot be forward declared
+   |          ^^^^^^^ cannot reference `T` before it is declared
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
   --> $DIR/issue-26812.rs:1:8