about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src/late.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_resolve/src/late.rs')
-rw-r--r--compiler/rustc_resolve/src/late.rs42
1 files changed, 29 insertions, 13 deletions
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);
                     }
                 }
             }