diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 180ccb15977dd..35ae05c477626 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -415,6 +415,7 @@ E0743: include_str!("./error_codes/E0743.md"),
 E0744: include_str!("./error_codes/E0744.md"),
 E0745: include_str!("./error_codes/E0745.md"),
 E0746: include_str!("./error_codes/E0746.md"),
+E0747: include_str!("./error_codes/E0747.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/src/librustc_error_codes/error_codes/E0747.md b/src/librustc_error_codes/error_codes/E0747.md
new file mode 100644
index 0000000000000..f337d11ebb6b4
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0747.md
@@ -0,0 +1,58 @@
+Any constant item, static item, array length expression, or enum
+discriminant cannot refer to type parameters.
+
+Erroneous code example:
+
+```compile_fail,E0747
+use std::mem::size_of;
+
+fn foo<T>() {
+    let _ = [0; size_of::<T>()];
+}
+```
+
+A workaround for array length expressions is to use [`vec!`] instead, which
+does support type parameters in it's length expression, though this does
+perform dynamic memory allocation. Example:
+
+```
+use std::mem::size_of;
+
+fn foo<T>() {
+    let _ = vec![0; size_of::<T>()];
+}
+```
+
+While enum discriminants cannot refer to regular type parameters, they can still
+refer to the `Self` type parameter. Example:
+
+```
+#[repr(u8)]
+enum Alpha {
+    V1 = 41,
+    V2 = Self::V1 as u8 + 1,
+}
+```
+
+Note that associated constants do not have this limitation and can refer to
+type parameters. Example:
+
+```
+use std::mem::size_of;
+
+trait Foo {
+    const X: i32;
+}
+
+struct Bar<T>(T);
+
+impl<T> Foo for Bar<T> {
+    const X: i32 = size_of::<T>();
+}
+```
+
+This is currently a limitation with the compiler. These restrictions may be
+relaxed in the future, see [issue 43408] for more information.
+
+[`vec!`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
+[issue 43408]: https://github.com/rust-lang/rust/issues/43408
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index a433ae8ed676a..31cea2bb1f7b4 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -360,6 +360,17 @@ impl<'a> Resolver<'a> {
                 err.span_label(span, "non-constant value");
                 err
             }
+            ResolutionError::GenericParamsInConst(source) => {
+                let mut err = struct_span_err!(
+                    self.session,
+                    span,
+                    E0747,
+                    "type parameters cannot appear within {}",
+                    source.descr()
+                );
+                err.span_label(span, "type parameter");
+                err
+            }
             ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
                 let res = binding.res();
                 let shadows_what = res.descr();
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index defca4944bcd8..8413a18833abc 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -78,6 +78,39 @@ enum PatBoundCtx {
     Or,
 }
 
+/// Denotes the location/usage of an anonymous constant.
+#[derive(Copy, Clone, PartialEq, Debug)]
+crate enum AnonConstUsage {
+    /// Constant item, e.g., `const _: u8 = X;`.
+    Constant,
+    /// Static item, e.g., `static _: u8 = X;`.
+    Static,
+    /// An array length expression, e.g., `[...; X]`.
+    ArrayLength,
+    /// An enum discriminant value, e.g., `enum Enum { V = X, }`.
+    EnumDiscriminant,
+    /// An associated constant in an impl or trait, e.g., `impl A { const _: u8 = X; }`.
+    AssocConstant,
+    /// A const generic argument, e.g., `Struct<{X}>`.
+    GenericArg,
+    /// A typeof expression, which is an unimplemented feature.
+    Typeof,
+}
+
+impl AnonConstUsage {
+    crate fn descr(self) -> &'static str {
+        match self {
+            AnonConstUsage::Constant => "a constant",
+            AnonConstUsage::Static => "a static",
+            AnonConstUsage::ArrayLength => "an array length expression",
+            AnonConstUsage::EnumDiscriminant => "an enum discriminant",
+            AnonConstUsage::AssocConstant => "an associated constant",
+            AnonConstUsage::GenericArg => "a const generic argument",
+            AnonConstUsage::Typeof => "a typeof expression",
+        }
+    }
+}
+
 /// Does this the item (from the item rib scope) allow generic parameters?
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 crate enum HasGenericParams {
@@ -105,8 +138,8 @@ crate enum RibKind<'a> {
     /// We passed through an item scope. Disallow upvars.
     ItemRibKind(HasGenericParams),
 
-    /// We're in a constant item. Can't refer to dynamic stuff.
-    ConstantItemRibKind,
+    /// We're in a constant. Depending on it's usage, it may be able to refer to type parameters.
+    ConstantRibKind(AnonConstUsage),
 
     /// We passed through a module.
     ModuleRibKind(Module<'a>),
@@ -125,7 +158,7 @@ impl RibKind<'_> {
     // variables.
     crate fn contains_params(&self) -> bool {
         match self {
-            NormalRibKind | FnItemRibKind | ConstantItemRibKind | ModuleRibKind(_)
+            NormalRibKind | FnItemRibKind | ConstantRibKind(_) | ModuleRibKind(_)
             | MacroDefinition(_) => false,
             AssocItemRibKind | ItemRibKind(_) | ForwardTyParamBanRibKind => true,
         }
@@ -381,10 +414,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
         self.resolve_block(block);
     }
     fn visit_anon_const(&mut self, constant: &'tcx AnonConst) {
-        debug!("visit_anon_const {:?}", constant);
-        self.with_constant_rib(|this| {
-            visit::walk_anon_const(this, constant);
-        });
+        // All constants should be handled by their parents, so that the applicable `AnonConstUsage`
+        // of the constant can be assigned.
+        bug!("unhandled constant: {:?}", constant);
+    }
+    fn visit_variant(&mut self, variant: &'tcx Variant) {
+        self.visit_variant_data(&variant.data);
+        if let Some(ref disr) = variant.disr_expr {
+            self.with_constant_rib(AnonConstUsage::EnumDiscriminant, |this| {
+                visit::walk_anon_const(this, disr);
+            });
+        }
     }
     fn visit_expr(&mut self, expr: &'tcx Expr) {
         self.resolve_expr(expr, None);
@@ -407,6 +447,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
         match ty.kind {
             TyKind::Path(ref qself, ref path) => {
                 self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
+                visit::walk_ty(self, ty);
             }
             TyKind::ImplicitSelf => {
                 let self_ty = Ident::with_dummy_span(kw::SelfUpper);
@@ -414,10 +455,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                     .resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
                     .map_or(Res::Err, |d| d.res());
                 self.r.record_partial_res(ty.id, PartialRes::new(res));
+                visit::walk_ty(self, ty);
             }
-            _ => (),
-        }
-        visit::walk_ty(self, ty);
+            TyKind::Array(ref element_ty, ref count) => {
+                self.visit_ty(element_ty);
+                self.with_constant_rib(AnonConstUsage::ArrayLength, |this| {
+                    visit::walk_anon_const(this, count);
+                });
+            }
+            TyKind::Typeof(ref constant) => {
+                self.with_constant_rib(AnonConstUsage::Typeof, |this| {
+                    visit::walk_anon_const(this, constant);
+                });
+            }
+            _ => visit::walk_ty(self, ty),
+        };
     }
     fn visit_poly_trait_ref(&mut self, tref: &'tcx PolyTraitRef, m: &'tcx TraitBoundModifier) {
         self.smart_resolve_path(
@@ -560,9 +612,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                         };
 
                         if !check_ns(TypeNS) && check_ns(ValueNS) {
-                            // This must be equivalent to `visit_anon_const`, but we cannot call it
-                            // directly due to visitor lifetimes so we have to copy-paste some code.
-                            self.with_constant_rib(|this| {
+                            self.with_constant_rib(AnonConstUsage::GenericArg, |this| {
                                 this.smart_resolve_path(
                                     ty.id,
                                     qself.as_ref(),
@@ -584,7 +634,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 self.visit_ty(ty);
             }
             GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
-            GenericArg::Const(ct) => self.visit_anon_const(ct),
+            GenericArg::Const(ct) => {
+                self.with_constant_rib(AnonConstUsage::GenericArg, |this| {
+                    visit::walk_anon_const(this, ct);
+                });
+            }
         }
     }
 }
@@ -829,9 +883,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                                 // ConstRibKind for an actual constant
                                                 // expression in a provided default.
                                                 if let Some(ref expr) = *default {
-                                                    this.with_constant_rib(|this| {
-                                                        this.visit_expr(expr);
-                                                    });
+                                                    this.with_constant_rib(
+                                                        AnonConstUsage::AssocConstant,
+                                                        |this| {
+                                                            this.visit_expr(expr);
+                                                        },
+                                                    );
                                                 }
                                             }
                                             AssocItemKind::Fn(_, _) => {
@@ -873,7 +930,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 debug!("resolve_item ItemKind::Const");
                 self.with_item_rib(HasGenericParams::No, |this| {
                     this.visit_ty(ty);
-                    this.with_constant_rib(|this| {
+                    let usage = if let ItemKind::Static(..) = item.kind {
+                        AnonConstUsage::Static
+                    } else {
+                        AnonConstUsage::Constant
+                    };
+                    this.with_constant_rib(usage, |this| {
                         this.visit_expr(expr);
                     });
                 });
@@ -971,10 +1033,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
     }
 
-    fn with_constant_rib(&mut self, f: impl FnOnce(&mut Self)) {
+    fn with_constant_rib(&mut self, usage: AnonConstUsage, f: impl FnOnce(&mut Self)) {
         debug!("with_constant_rib");
-        self.with_rib(ValueNS, ConstantItemRibKind, |this| {
-            this.with_label_rib(ConstantItemRibKind, f);
+        self.with_rib(ValueNS, ConstantRibKind(usage), |this| {
+            this.with_rib(TypeNS, ConstantRibKind(usage), |this| {
+                this.with_label_rib(ConstantRibKind(usage), f);
+            });
         });
     }
 
@@ -1106,7 +1170,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                                                 |this| {
                                         use crate::ResolutionError::*;
                                         match impl_item.kind {
-                                            AssocItemKind::Const(..) => {
+                                            AssocItemKind::Const(ref ty, ref expr) => {
                                                 debug!(
                                                     "resolve_implementation AssocItemKind::Const",
                                                 );
@@ -1119,9 +1183,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                                     |n, s| ConstNotMemberOfTrait(n, s),
                                                 );
 
-                                                this.with_constant_rib(|this| {
-                                                    visit::walk_impl_item(this, impl_item)
-                                                });
+                                                this.visit_ty(ty);
+
+                                                // Only impose the restrictions of ConstRibKind for
+                                                // the actual constant expression.
+                                                if let Some(expr) = expr.as_deref() {
+                                                    this.with_constant_rib(AnonConstUsage::AssocConstant, |this| {
+                                                        this.visit_expr(expr)
+                                                    });
+                                                }
                                             }
                                             AssocItemKind::Fn(..) => {
                                                 // If this is a trait impl, ensure the method
@@ -2019,6 +2089,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     }
                 });
             }
+            ExprKind::Repeat(ref element, ref count) => {
+                self.visit_expr(element);
+                self.with_constant_rib(AnonConstUsage::ArrayLength, |this| {
+                    visit::walk_anon_const(this, count);
+                });
+            }
             _ => {
                 visit::walk_expr(self, expr);
             }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 60a0049f5da37..743f6d34db7b8 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1,3 +1,4 @@
+// ignore-tidy-filelength
 //! This crate is responsible for the part of name resolution that doesn't require type checker.
 //!
 //! Module structure of the crate is built here.
@@ -58,7 +59,7 @@ use std::{cmp, fmt, iter, ptr};
 use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding};
 use diagnostics::{ImportSuggestion, Suggestion};
 use imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver, NameResolution};
-use late::{HasGenericParams, PathSource, Rib, RibKind::*};
+use late::{AnonConstUsage, HasGenericParams, PathSource, Rib, RibKind::*};
 use macros::{LegacyBinding, LegacyScope};
 
 use rustc_error_codes::*;
@@ -203,6 +204,8 @@ enum ResolutionError<'a> {
     CannotCaptureDynamicEnvironmentInFnItem,
     /// Error E0435: attempt to use a non-constant value in a constant.
     AttemptToUseNonConstantValueInConstant,
+    /// Error E0747: type parameters cannot appear within `{}`.
+    GenericParamsInConst(AnonConstUsage),
     /// Error E0530: `X` bindings cannot shadow `Y`s.
     BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
     /// Error E0128: type parameters with a default cannot use forward-declared identifiers.
@@ -2327,12 +2330,12 @@ impl<'a> Resolver<'a> {
                             if record_used {
                                 // We don't immediately trigger a resolve error, because
                                 // we want certain other resolution errors (namely those
-                                // emitted for `ConstantItemRibKind` below) to take
+                                // emitted for `ConstantRibKind` below) to take
                                 // precedence.
                                 res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
                             }
                         }
-                        ConstantItemRibKind => {
+                        ConstantRibKind(_) => {
                             // Still doesn't deal with upvars
                             if record_used {
                                 self.report_error(span, AttemptToUseNonConstantValueInConstant);
@@ -2353,11 +2356,57 @@ impl<'a> Resolver<'a> {
                         | AssocItemRibKind
                         | ModuleRibKind(..)
                         | MacroDefinition(..)
-                        | ForwardTyParamBanRibKind
-                        | ConstantItemRibKind => {
+                        | ForwardTyParamBanRibKind => {
                             // Nothing to do. Continue.
                             continue;
                         }
+                        ConstantRibKind(usage) => {
+                            if self.session.features_untracked().const_generics {
+                                // With const generics/lazy normalization any constants can depend
+                                // on generic parameters, including type parameters.
+                                continue;
+                            };
+                            match usage {
+                                AnonConstUsage::AssocConstant
+                                | AnonConstUsage::GenericArg
+                                | AnonConstUsage::Typeof => {
+                                    // Allowed to use any type parameters.
+                                    continue
+                                },
+                                // Enum discriminants can use `Self` to refer to other variants in
+                                // the same enum, but can refer to any other type parameters.
+                                AnonConstUsage::EnumDiscriminant
+                                // In most cases array lengths can't refer to type parameters but
+                                // previously some usages involving `Self` did compile. Example:
+                                //
+                                // impl Foo {
+                                //     const A: usize = 32;
+                                //
+                                //     pub fn bar() {
+                                //         let _ = [0; Self::A];
+                                //     }
+                                // }
+                                //
+                                // Though if `Foo` had a type parameter,
+                                // e.g. `impl<T> Foo<T> { ... }` then is wouldn't compile with a
+                                // confusing error message.
+                                | AnonConstUsage::ArrayLength => {
+                                    if let Res::SelfTy(..) = res {
+                                        continue
+                                    }
+                                }
+                                // can't use any type parameters including `Self`.
+                                AnonConstUsage::Constant | AnonConstUsage::Static => {}
+                            }
+
+                            if record_used {
+                                self.report_error(
+                                    span,
+                                    ResolutionError::GenericParamsInConst(usage),
+                                );
+                            }
+                            return Res::Err;
+                        }
                         // This was an attempt to use a type parameter outside its scope.
                         ItemRibKind(has_generic_params) => has_generic_params,
                         FnItemRibKind => HasGenericParams::Yes,
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs
index f1f82caf7d40b..3b752bd2fe481 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs
@@ -14,7 +14,7 @@ impl Foo for Def {
 
 pub fn test<A: Foo, B: Foo>() {
     let _array = [4; <A as Foo>::Y];
-    //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
+    //~^ ERROR type parameters cannot appear within an array length expression [E0747]
 }
 
 fn main() {
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
index c258892057bf2..721b3e6028280 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
@@ -1,14 +1,9 @@
-error[E0277]: the trait bound `A: Foo` is not satisfied
-  --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/associated-const-type-parameter-arrays-2.rs:16:23
    |
-LL |     const Y: usize;
-   |     --------------- required by `Foo::Y`
-...
-LL | pub fn test<A: Foo, B: Foo>() {
-   |             -- help: consider further restricting this bound: `A: Foo +`
 LL |     let _array = [4; <A as Foo>::Y];
-   |                      ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
+   |                       ^ type parameter
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays.rs b/src/test/ui/associated-const/associated-const-type-parameter-arrays.rs
index d51821059fc13..64ec2075427c4 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays.rs
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays.rs
@@ -14,7 +14,7 @@ impl Foo for Def {
 
 pub fn test<A: Foo, B: Foo>() {
     let _array: [u32; <A as Foo>::Y];
-    //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
+    //~^ ERROR type parameters cannot appear within an array length expression [E0747]
 }
 
 fn main() {
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
index f6c8e99e27a81..33423c35b79ac 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
@@ -1,14 +1,9 @@
-error[E0277]: the trait bound `A: Foo` is not satisfied
-  --> $DIR/associated-const-type-parameter-arrays.rs:16:23
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/associated-const-type-parameter-arrays.rs:16:24
    |
-LL |     const Y: usize;
-   |     --------------- required by `Foo::Y`
-...
-LL | pub fn test<A: Foo, B: Foo>() {
-   |             -- help: consider further restricting this bound: `A: Foo +`
 LL |     let _array: [u32; <A as Foo>::Y];
-   |                       ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
+   |                        ^ type parameter
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/consts/const-type-parameter-self.rs b/src/test/ui/consts/const-type-parameter-self.rs
new file mode 100644
index 0000000000000..96275e9fe8504
--- /dev/null
+++ b/src/test/ui/consts/const-type-parameter-self.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+struct Foo;
+
+impl Foo {
+    const A: usize = 37;
+
+    fn bar() -> [u8; Self::A]{
+        [0; Self::A]
+    }
+}
+
+fn main() {
+    let _: [u8; 37] = Foo::bar();
+}
diff --git a/src/test/ui/consts/const-type-parameter.rs b/src/test/ui/consts/const-type-parameter.rs
new file mode 100644
index 0000000000000..e9cf5a3c75860
--- /dev/null
+++ b/src/test/ui/consts/const-type-parameter.rs
@@ -0,0 +1,32 @@
+use std::mem::size_of;
+
+trait Bar {
+    const A: usize;
+}
+
+fn foo<T: Bar>() {
+    const A: usize = size_of::<T>();
+    //~^ can't use generic parameters from outer function [E0401]
+    const B: usize = T::A;
+    //~^ can't use generic parameters from outer function [E0401]
+    static C: usize = size_of::<T>();
+    //~^ can't use generic parameters from outer function [E0401]
+    static D: usize = T::A;
+    //~^ can't use generic parameters from outer function [E0401]
+
+    let _ = [0; size_of::<T>()];
+    //~^ ERROR type parameters cannot appear within an array length expression [E0747]
+    let _ = [0; T::A];
+    //~^ ERROR type parameters cannot appear within an array length expression [E0747]
+}
+
+#[repr(usize)]
+enum Enum<T: Bar> {
+    //~^ ERROR parameter `T` is never used [E0392]
+    V1 = size_of::<T>(),
+    //~^ ERROR type parameters cannot appear within an enum discriminant [E0747]
+    V2 = T::A,
+    //~^ ERROR type parameters cannot appear within an enum discriminant [E0747]
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/const-type-parameter.stderr b/src/test/ui/consts/const-type-parameter.stderr
new file mode 100644
index 0000000000000..2bb90dcb91f66
--- /dev/null
+++ b/src/test/ui/consts/const-type-parameter.stderr
@@ -0,0 +1,71 @@
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/const-type-parameter.rs:8:32
+   |
+LL | fn foo<T: Bar>() {
+   |        - type parameter from outer function
+LL |     const A: usize = size_of::<T>();
+   |                                ^ use of generic parameter from outer function
+
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/const-type-parameter.rs:10:22
+   |
+LL | fn foo<T: Bar>() {
+   |        - type parameter from outer function
+...
+LL |     const B: usize = T::A;
+   |                      ^^^^ use of generic parameter from outer function
+
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/const-type-parameter.rs:12:33
+   |
+LL | fn foo<T: Bar>() {
+   |        - type parameter from outer function
+...
+LL |     static C: usize = size_of::<T>();
+   |                                 ^ use of generic parameter from outer function
+
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/const-type-parameter.rs:14:23
+   |
+LL | fn foo<T: Bar>() {
+   |        - type parameter from outer function
+...
+LL |     static D: usize = T::A;
+   |                       ^^^^ use of generic parameter from outer function
+
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/const-type-parameter.rs:17:27
+   |
+LL |     let _ = [0; size_of::<T>()];
+   |                           ^ type parameter
+
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/const-type-parameter.rs:19:17
+   |
+LL |     let _ = [0; T::A];
+   |                 ^^^^ type parameter
+
+error[E0747]: type parameters cannot appear within an enum discriminant
+  --> $DIR/const-type-parameter.rs:26:20
+   |
+LL |     V1 = size_of::<T>(),
+   |                    ^ type parameter
+
+error[E0747]: type parameters cannot appear within an enum discriminant
+  --> $DIR/const-type-parameter.rs:28:10
+   |
+LL |     V2 = T::A,
+   |          ^^^^ type parameter
+
+error[E0392]: parameter `T` is never used
+  --> $DIR/const-type-parameter.rs:24:11
+   |
+LL | enum Enum<T: Bar> {
+   |           ^ unused parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0392, E0401, E0747.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/src/test/ui/consts/issue-67945.rs b/src/test/ui/consts/issue-67945.rs
new file mode 100644
index 0000000000000..04f53bb12e8e8
--- /dev/null
+++ b/src/test/ui/consts/issue-67945.rs
@@ -0,0 +1,50 @@
+#![feature(type_ascription)]
+
+use std::marker::PhantomData;
+use std::mem::{self, MaybeUninit};
+
+struct Bug1<S> {
+    //~^ ERROR parameter `S` is never used [E0392]
+    A: [(); {
+        let x: S = MaybeUninit::uninit();
+        //~^ ERROR type parameters cannot appear within an array length expression [E0747]
+        let b = &*(&x as *const _ as *const S);
+        //~^ ERROR type parameters cannot appear within an array length expression [E0747]
+        0
+    }],
+}
+
+struct Bug2<S> {
+    //~^ ERROR parameter `S` is never used [E0392]
+    A: [(); {
+        let x: Option<S> = None;
+        //~^ ERROR type parameters cannot appear within an array length expression [E0747]
+        0
+    }],
+}
+
+struct Bug3<S> {
+    //~^ ERROR parameter `S` is never used [E0392]
+    A: [(); {
+        let x: Option<Box<S>> = None;
+        //~^ ERROR type parameters cannot appear within an array length expression [E0747]
+        0
+    }],
+}
+
+enum Bug4<S> {
+    //~^ ERROR parameter `S` is never used [E0392]
+    Var = {
+        let x: S = 0;
+        //~^ ERROR type parameters cannot appear within an enum discriminant [E0747]
+        0
+    },
+}
+
+enum Bug5<S> {
+    //~^ ERROR parameter `S` is never used [E0392]
+    Var = 0: S,
+    //~^ ERROR type parameters cannot appear within an enum discriminant [E0747]
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-67945.stderr b/src/test/ui/consts/issue-67945.stderr
new file mode 100644
index 0000000000000..f5700dc5c266b
--- /dev/null
+++ b/src/test/ui/consts/issue-67945.stderr
@@ -0,0 +1,80 @@
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/issue-67945.rs:9:16
+   |
+LL |         let x: S = MaybeUninit::uninit();
+   |                ^ type parameter
+
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/issue-67945.rs:11:45
+   |
+LL |         let b = &*(&x as *const _ as *const S);
+   |                                             ^ type parameter
+
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/issue-67945.rs:20:23
+   |
+LL |         let x: Option<S> = None;
+   |                       ^ type parameter
+
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/issue-67945.rs:29:27
+   |
+LL |         let x: Option<Box<S>> = None;
+   |                           ^ type parameter
+
+error[E0747]: type parameters cannot appear within an enum discriminant
+  --> $DIR/issue-67945.rs:38:16
+   |
+LL |         let x: S = 0;
+   |                ^ type parameter
+
+error[E0747]: type parameters cannot appear within an enum discriminant
+  --> $DIR/issue-67945.rs:46:14
+   |
+LL |     Var = 0: S,
+   |              ^ type parameter
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945.rs:6:13
+   |
+LL | struct Bug1<S> {
+   |             ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945.rs:17:13
+   |
+LL | struct Bug2<S> {
+   |             ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945.rs:26:13
+   |
+LL | struct Bug3<S> {
+   |             ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945.rs:35:11
+   |
+LL | enum Bug4<S> {
+   |           ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945.rs:44:11
+   |
+LL | enum Bug5<S> {
+   |           ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0392, E0747.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/src/test/ui/issues/issue-39211.rs b/src/test/ui/issues/issue-39211.rs
index db101ae248cb6..c5507fb90d5ba 100644
--- a/src/test/ui/issues/issue-39211.rs
+++ b/src/test/ui/issues/issue-39211.rs
@@ -8,7 +8,8 @@ trait Mat {
 }
 
 fn m<M: Mat>() {
-    let a = [3; M::Row::DIM]; //~ ERROR associated type `Row` not found for `M`
+    let a = [3; M::Row::DIM];
+    //~^ ERROR type parameters cannot appear within an array length expression [E0747]
 }
 fn main() {
 }
diff --git a/src/test/ui/issues/issue-39211.stderr b/src/test/ui/issues/issue-39211.stderr
index c14c663e5a1a9..16f67d943ad94 100644
--- a/src/test/ui/issues/issue-39211.stderr
+++ b/src/test/ui/issues/issue-39211.stderr
@@ -1,9 +1,9 @@
-error[E0220]: associated type `Row` not found for `M`
-  --> $DIR/issue-39211.rs:11:20
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/issue-39211.rs:11:17
    |
 LL |     let a = [3; M::Row::DIM];
-   |                    ^^^ associated type `Row` not found
+   |                 ^^^^^^^^^^^ type parameter
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0220`.
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/issues/issue-39559.rs b/src/test/ui/issues/issue-39559.rs
index 3a75956af5280..2621a691e5563 100644
--- a/src/test/ui/issues/issue-39559.rs
+++ b/src/test/ui/issues/issue-39559.rs
@@ -12,7 +12,7 @@ impl Dim for Dim3 {
 
 pub struct Vector<T, D: Dim> {
     entries: [T; D::dim()],
-    //~^ ERROR no function or associated item named `dim` found
+    //~^ ERROR type parameters cannot appear within an array length expression [E0747]
     _dummy: D,
 }
 
diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr
index 0554b232c248b..e72b5d7a3f6c5 100644
--- a/src/test/ui/issues/issue-39559.stderr
+++ b/src/test/ui/issues/issue-39559.stderr
@@ -1,15 +1,9 @@
-error[E0599]: no function or associated item named `dim` found for type parameter `D` in the current scope
-  --> $DIR/issue-39559.rs:14:21
+error[E0747]: type parameters cannot appear within an array length expression
+  --> $DIR/issue-39559.rs:14:18
    |
 LL |     entries: [T; D::dim()],
-   |                     ^^^ function or associated item not found in `D`
-   |
-   = help: items from traits can only be used if the type parameter is bounded by the trait
-help: the following trait defines an item `dim`, perhaps you need to restrict type parameter `D` with it:
-   |
-LL | pub struct Vector<T, D: Dim + Dim> {
-   |                      ^^^^^^^^
+   |                  ^^^^^^ type parameter
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0599`.
+For more information about this error, try `rustc --explain E0747`.