diff --git a/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs b/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs
new file mode 100644
index 0000000000000..97760cbf8fb58
--- /dev/null
+++ b/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs
@@ -0,0 +1,24 @@
+// check-pass
+// edition:2018
+#![feature(min_const_generics)]
+trait ValidTrait {}
+
+/// This has docs
+pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
+    loop {}
+}
+
+pub trait Trait<const N: usize> {}
+impl Trait<1> for u8 {}
+impl Trait<2> for u8 {}
+impl<const N: usize> Trait<N> for [u8; N] {}
+
+/// This also has docs
+pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
+    loop {}
+}
+
+/// Document all the functions
+pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N> {
+    loop {}
+}
diff --git a/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs b/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs
new file mode 100644
index 0000000000000..b8bd040f7a4b2
--- /dev/null
+++ b/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs
@@ -0,0 +1,18 @@
+// edition:2018
+#![feature(min_const_generics)]
+
+pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
+    [[0; N]; N].iter().copied()
+}
+
+pub struct ExternTy<const N: usize> {
+    pub inner: [u8; N],
+}
+
+pub type TyAlias<const N: usize> = ExternTy<N>;
+
+pub trait WTrait<const N: usize, const M: usize> {
+    fn hey<const P: usize>() -> usize {
+        N + M + P
+    }
+}
diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs
new file mode 100644
index 0000000000000..8dcba36600d26
--- /dev/null
+++ b/src/test/rustdoc/const-generics/const-generics-docs.rs
@@ -0,0 +1,130 @@
+// edition:2018
+// aux-build: extern_crate.rs
+#![feature(min_const_generics)]
+#![crate_name = "foo"]
+
+extern crate extern_crate;
+// @has foo/fn.extern_fn.html '//pre[@class="rust fn"]' \
+//      'pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]>'
+pub use extern_crate::extern_fn;
+// @has foo/struct.ExternTy.html '//pre[@class="rust struct"]' \
+//      'pub struct ExternTy<const N: usize> {'
+pub use extern_crate::ExternTy;
+// @has foo/type.TyAlias.html '//pre[@class="rust typedef"]' \
+//      'type TyAlias<const N: usize> = ExternTy<N>;'
+pub use extern_crate::TyAlias;
+// @has foo/trait.WTrait.html '//pre[@class="rust trait"]' \
+//      'pub trait WTrait<const N: usize, const M: usize>'
+// @has - '//*[@class="rust trait"]' 'fn hey<const P: usize>() -> usize'
+pub use extern_crate::WTrait;
+
+// @has foo/trait.Trait.html '//pre[@class="rust trait"]' \
+//      'pub trait Trait<const N: usize>'
+// @has - '//*[@id="impl-Trait%3C1_usize%3E-for-u8"]//code' 'impl Trait<1_usize> for u8'
+// @has - '//*[@id="impl-Trait%3C2_usize%3E-for-u8"]//code' 'impl Trait<2_usize> for u8'
+// @has - '//*[@id="impl-Trait%3C{1%20+%202}%3E-for-u8"]//code' 'impl Trait<{1 + 2}> for u8'
+// @has - '//*[@id="impl-Trait%3CN%3E-for-%5Bu8%3B%20N%5D"]//code' \
+//      'impl<const N: usize> Trait<N> for [u8; N]'
+pub trait Trait<const N: usize> {}
+impl Trait<1> for u8 {}
+impl Trait<2> for u8 {}
+impl Trait<{1 + 2}> for u8 {}
+impl<const N: usize> Trait<N> for [u8; N] {}
+
+// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
+//      'pub struct Foo<const N: usize> where u8: Trait<N>'
+pub struct Foo<const N: usize> where u8: Trait<N>;
+// @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
+pub struct Bar<T, const N: usize>([T; N]);
+
+// @has foo/struct.Foo.html '//h3[@id="impl"]/code' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
+impl<const M: usize> Foo<M> where u8: Trait<M> {
+    // @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
+    pub const FOO_ASSOC: usize = M + 13;
+
+    // @has - '//*[@id="method.hey"]' 'pub fn hey<const N: usize>(&self) -> Bar<u8, N>'
+    pub fn hey<const N: usize>(&self) -> Bar<u8, N> {
+        Bar([0; N])
+    }
+}
+
+// @has foo/struct.Bar.html '//h3[@id="impl"]/code' 'impl<const M: usize> Bar<u8, M>'
+impl<const M: usize> Bar<u8, M> {
+    // @has - '//*[@id="method.hey"]' \
+    //      'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'
+    pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N> {
+        Foo
+    }
+}
+
+// @has foo/fn.test.html '//pre[@class="rust fn"]' \
+//      'pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N>'
+pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
+    2u8
+}
+
+// @has foo/fn.a_sink.html '//pre[@class="rust fn"]' \
+//      'pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N>'
+pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N> {
+    v
+}
+
+// @has foo/fn.b_sink.html '//pre[@class="rust fn"]' \
+//      'pub async fn b_sink<const N: usize>(__arg0: impl Trait<N>)'
+// FIXME(const_generics): This should be `_` not `__arg0`.
+pub async fn b_sink<const N: usize>(_: impl Trait<N>) {}
+
+// @has foo/fn.concrete.html '//pre[@class="rust fn"]' \
+//      'pub fn concrete() -> [u8; 22]'
+pub fn concrete() -> [u8; 3 + std::mem::size_of::<u64>() << 1] {
+    Default::default()
+}
+
+// @has foo/type.Faz.html '//pre[@class="rust typedef"]' \
+//      'type Faz<const N: usize> = [u8; N];'
+pub type Faz<const N: usize> = [u8; N];
+// @has foo/type.Fiz.html '//pre[@class="rust typedef"]' \
+//      'type Fiz<const N: usize> = [[u8; N]; 48];'
+pub type Fiz<const N: usize> = [[u8; N]; 3 << 4];
+
+macro_rules! define_me {
+    ($t:tt<$q:tt>) => {
+        pub struct $t<const $q: usize>([u8; $q]);
+    }
+}
+
+// @has foo/struct.Foz.html '//pre[@class="rust struct"]' \
+//      'pub struct Foz<const N: usize>(_);'
+define_me!(Foz<N>);
+
+trait Q {
+    const ASSOC: usize;
+}
+
+impl<const N: usize> Q for [u8; N] {
+    const ASSOC: usize = N;
+}
+
+// @has foo/fn.q_user.html '//pre[@class="rust fn"]' \
+//      'pub fn q_user() -> [u8; 13]'
+pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {
+    [0; <[u8; 13] as Q>::ASSOC]
+}
+
+// @has foo/union.Union.html '//pre[@class="rust union"]' \
+//      'pub union Union<const N: usize>'
+pub union Union<const N: usize> {
+    // @has - //pre "pub arr: [u8; N]"
+    pub arr: [u8; N],
+    // @has - //pre "pub another_arr: [(); N]"
+    pub another_arr: [(); N],
+}
+
+// @has foo/enum.Enum.html '//pre[@class="rust enum"]' \
+//      'pub enum Enum<const N: usize>'
+pub enum Enum<const N: usize> {
+    // @has - //pre "Variant([u8; N])"
+    Variant([u8; N]),
+    // @has - //pre "EmptyVariant"
+    EmptyVariant,
+}
diff --git a/src/test/ui/const-generics/associated-type-bound-fail.full.stderr b/src/test/ui/const-generics/associated-type-bound-fail.full.stderr
new file mode 100644
index 0000000000000..8ccbe5dee0e44
--- /dev/null
+++ b/src/test/ui/const-generics/associated-type-bound-fail.full.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
+  --> $DIR/associated-type-bound-fail.rs:14:5
+   |
+LL |     type Assoc: Bar<N>;
+   |                 ------ required by this bound in `Foo::Assoc`
+...
+LL |     type Assoc = u16;
+   |     ^^^^^^^^^^^^^^^^^ the trait `Bar<N>` is not implemented for `u16`
+   |
+   = help: the following implementations were found:
+             <u16 as Bar<3_usize>>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/associated-type-bound-fail.min.stderr b/src/test/ui/const-generics/associated-type-bound-fail.min.stderr
new file mode 100644
index 0000000000000..8ccbe5dee0e44
--- /dev/null
+++ b/src/test/ui/const-generics/associated-type-bound-fail.min.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
+  --> $DIR/associated-type-bound-fail.rs:14:5
+   |
+LL |     type Assoc: Bar<N>;
+   |                 ------ required by this bound in `Foo::Assoc`
+...
+LL |     type Assoc = u16;
+   |     ^^^^^^^^^^^^^^^^^ the trait `Bar<N>` is not implemented for `u16`
+   |
+   = help: the following implementations were found:
+             <u16 as Bar<3_usize>>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/associated-type-bound-fail.rs b/src/test/ui/const-generics/associated-type-bound-fail.rs
new file mode 100644
index 0000000000000..3440b1356c242
--- /dev/null
+++ b/src/test/ui/const-generics/associated-type-bound-fail.rs
@@ -0,0 +1,17 @@
+// revisions: full min
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+trait Bar<const N: usize> {}
+
+trait Foo<const N: usize> {
+    type Assoc: Bar<N>;
+}
+
+impl Bar<3> for u16 {}
+impl<const N: usize> Foo<N> for i16 {
+    type Assoc = u16; //~ ERROR the trait bound `u16: Bar<N>`
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/associated-type-bound.rs b/src/test/ui/const-generics/associated-type-bound.rs
new file mode 100644
index 0000000000000..374a49194b178
--- /dev/null
+++ b/src/test/ui/const-generics/associated-type-bound.rs
@@ -0,0 +1,24 @@
+// run-pass
+// revisions: full min
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+trait Bar<const N: usize> {}
+
+trait Foo<const N: usize> {
+    type Assoc: Bar<N>;
+}
+
+impl<const N: usize> Bar<N> for u8 {}
+impl Bar<3> for u16 {}
+
+impl<const N: usize> Foo<N> for i8 {
+    type Assoc = u8;
+}
+
+impl Foo<3> for i16 {
+    type Assoc = u16;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/auxiliary/crayte.rs b/src/test/ui/const-generics/auxiliary/crayte.rs
new file mode 100644
index 0000000000000..725005971e1e9
--- /dev/null
+++ b/src/test/ui/const-generics/auxiliary/crayte.rs
@@ -0,0 +1,19 @@
+// edition:2018
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+pub trait Foo<const N: usize> {}
+struct Local;
+impl<const N: usize> Foo<N> for Local {}
+
+pub fn out_foo<const N: usize>() -> impl Foo<N> { Local }
+pub fn in_foo<const N: usize>(_: impl Foo<N>) {}
+
+pub async fn async_simple<const N: usize>(_: [u8; N]) {}
+pub async fn async_out_foo<const N: usize>() -> impl Foo<N> { Local }
+pub async fn async_in_foo<const N: usize>(_: impl Foo<N>) {}
+
+pub trait Bar<const N: usize> {
+    type Assoc: Foo<N>;
+}
diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
new file mode 100644
index 0000000000000..7dfe250b78e00
--- /dev/null
+++ b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -0,0 +1,203 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:14:23
+   |
+LL |     let _: [u8; foo::<T>()];
+   |                       ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:15:23
+   |
+LL |     let _: [u8; bar::<N>()];
+   |                       ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:25:23
+   |
+LL |     let _ = [0; bar::<N>()];
+   |                       ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:30:24
+   |
+LL |     let _: Foo<{ foo::<T>() }>;
+   |                        ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:31:24
+   |
+LL |     let _: Foo<{ bar::<N>() }>;
+   |                        ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:36:27
+   |
+LL |     let _ = Foo::<{ foo::<T>() }>;
+   |                           ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+
+error: generic parameters may not be used in const operations
+  --> $DIR/const-arg-in-const-arg.rs:37:27
+   |
+LL |     let _ = Foo::<{ bar::<N>() }>;
+   |                           ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:16:23
+   |
+LL |     let _: [u8; faz::<'a>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:17:23
+   |
+LL |     let _: [u8; baz::<'a>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:18:23
+   |
+LL |     let _: [u8; faz::<'b>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:19:23
+   |
+LL |     let _: [u8; baz::<'b>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:26:23
+   |
+LL |     let _ = [0; faz::<'a>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:27:23
+   |
+LL |     let _ = [0; baz::<'a>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:28:23
+   |
+LL |     let _ = [0; faz::<'b>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:29:23
+   |
+LL |     let _ = [0; baz::<'b>(&())];
+   |                       ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:32:24
+   |
+LL |     let _: Foo<{ faz::<'a>(&()) }>;
+   |                        ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:33:24
+   |
+LL |     let _: Foo<{ baz::<'a>(&()) }>;
+   |                        ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:34:24
+   |
+LL |     let _: Foo<{ faz::<'b>(&()) }>;
+   |                        ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:35:24
+   |
+LL |     let _: Foo<{ baz::<'b>(&()) }>;
+   |                        ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:38:27
+   |
+LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
+   |                           ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:39:27
+   |
+LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
+   |                           ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:40:27
+   |
+LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
+   |                           ^^
+   |
+   = 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[E0658]: a non-static lifetime is not allowed in a `const`
+  --> $DIR/const-arg-in-const-arg.rs:41:27
+   |
+LL |     let _ = Foo::<{ baz::<'b>(&()) }>;
+   |                           ^^
+   |
+   = 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: aborting due to 23 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.rs b/src/test/ui/const-generics/const-arg-in-const-arg.rs
new file mode 100644
index 0000000000000..9927538ef50c6
--- /dev/null
+++ b/src/test/ui/const-generics/const-arg-in-const-arg.rs
@@ -0,0 +1,44 @@
+// revisions: min
+// FIXME(const_generics): This test currently causes an ICE because
+// we don't yet correctly deal with lifetimes, reenable this test once
+// this is fixed.
+#![cfg_attr(min, feature(min_const_generics))]
+
+const fn foo<T>() -> usize { std::mem::size_of::<T>() }
+const fn bar<const N: usize>() -> usize { N }
+const fn faz<'a>(_: &'a ()) -> usize { 13 }
+const fn baz<'a>(_: &'a ()) -> usize where &'a (): Sized { 13 }
+
+struct Foo<const N: usize>;
+fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
+    let _: [u8; foo::<T>()]; //~ ERROR generic parameters may not
+    let _: [u8; bar::<N>()]; //~ ERROR generic parameters may not
+    let _: [u8; faz::<'a>(&())]; //~ ERROR a non-static lifetime
+    let _: [u8; baz::<'a>(&())]; //~ ERROR a non-static lifetime
+    let _: [u8; faz::<'b>(&())]; //~ ERROR a non-static lifetime
+    let _: [u8; baz::<'b>(&())]; //~ ERROR a non-static lifetime
+
+    // NOTE: This can be a future compat warning instead of an error,
+    // so we stop compilation before emitting this error in this test.
+    let _ = [0; foo::<T>()];
+
+    let _ = [0; bar::<N>()]; //~ ERROR generic parameters may not
+    let _ = [0; faz::<'a>(&())]; //~ ERROR a non-static lifetime
+    let _ = [0; baz::<'a>(&())]; //~ ERROR a non-static lifetime
+    let _ = [0; faz::<'b>(&())]; //~ ERROR a non-static lifetime
+    let _ = [0; baz::<'b>(&())]; //~ ERROR a non-static lifetime
+    let _: Foo<{ foo::<T>() }>; //~ ERROR generic parameters may not
+    let _: Foo<{ bar::<N>() }>; //~ ERROR generic parameters may not
+    let _: Foo<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime
+    let _: Foo<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime
+    let _: Foo<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime
+    let _: Foo<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime
+    let _ = Foo::<{ foo::<T>() }>; //~ ERROR generic parameters may not
+    let _ = Foo::<{ bar::<N>() }>; //~ ERROR generic parameters may not
+    let _ = Foo::<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime
+    let _ = Foo::<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime
+    let _ = Foo::<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime
+    let _ = Foo::<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const-param-hygiene.rs b/src/test/ui/const-generics/const-param-hygiene.rs
new file mode 100644
index 0000000000000..c8cefc36732b2
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-hygiene.rs
@@ -0,0 +1,22 @@
+// run-pass
+// revisions: full min
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+macro_rules! bar {
+    ($($t:tt)*) => { impl<const N: usize> $($t)* };
+}
+
+macro_rules! baz {
+    ($t:tt) => { fn test<const M: usize>(&self) -> usize { $t } };
+}
+
+struct Foo<const N: usize>;
+
+bar!(Foo<N> { baz!{ M } });
+
+fn main() {
+    assert_eq!(Foo::<7>.test::<3>(), 3);
+}
diff --git a/src/test/ui/const-generics/const-param-in-async.rs b/src/test/ui/const-generics/const-param-in-async.rs
new file mode 100644
index 0000000000000..e8601985287bd
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-in-async.rs
@@ -0,0 +1,35 @@
+// edition:2018
+// check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+async fn foo<const N: usize>(arg: [u8; N]) -> usize { arg.len() }
+
+async fn bar<const N: usize>() -> [u8; N] {
+    [0; N]
+}
+
+trait Trait<const N: usize> {
+    fn fynn(&self) -> usize;
+}
+impl<const N: usize> Trait<N> for [u8; N] {
+    fn fynn(&self) -> usize {
+        N
+    }
+}
+async fn baz<const N: usize>() -> impl Trait<N> {
+    [0; N]
+}
+
+async fn biz<const N: usize>(v: impl Trait<N>) -> usize {
+    v.fynn()
+}
+
+async fn user<const N: usize>() {
+    let _ = foo::<N>(bar().await).await;
+    let _ = biz(baz::<N>().await).await;
+}
+
+fn main() { }
diff --git a/src/test/ui/const-generics/cross_crate_complex.rs b/src/test/ui/const-generics/cross_crate_complex.rs
new file mode 100644
index 0000000000000..30749b8bc6d75
--- /dev/null
+++ b/src/test/ui/const-generics/cross_crate_complex.rs
@@ -0,0 +1,28 @@
+// aux-build:crayte.rs
+// edition:2018
+// run-pass
+// revisions: full min
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+extern crate crayte;
+
+use crayte::*;
+
+async fn foo() {
+    in_foo(out_foo::<3>());
+    async_simple([0; 17]).await;
+    async_in_foo(async_out_foo::<4>().await).await;
+}
+
+struct Faz<const N: usize>;
+
+impl<const N: usize> Foo<N> for Faz<N> {}
+impl<const N: usize> Bar<N> for Faz<N> {
+    type Assoc = Faz<N>;
+}
+
+fn main() {
+    let _ = foo;
+}
diff --git a/src/test/ui/const-generics/exhaustive-value.full.stderr b/src/test/ui/const-generics/exhaustive-value.full.stderr
new file mode 100644
index 0000000000000..fdea1fb0c3ead
--- /dev/null
+++ b/src/test/ui/const-generics/exhaustive-value.full.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `(): Foo<N>` is not satisfied
+  --> $DIR/exhaustive-value.rs:267:5
+   |
+LL |     fn test() {}
+   |     --------- required by `Foo::test`
+...
+LL |     <() as Foo<N>>::test()
+   |     ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Foo<0_u8>>
+             <() as Foo<100_u8>>
+             <() as Foo<101_u8>>
+             <() as Foo<102_u8>>
+           and 252 others
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/exhaustive-value.min.stderr b/src/test/ui/const-generics/exhaustive-value.min.stderr
new file mode 100644
index 0000000000000..fdea1fb0c3ead
--- /dev/null
+++ b/src/test/ui/const-generics/exhaustive-value.min.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `(): Foo<N>` is not satisfied
+  --> $DIR/exhaustive-value.rs:267:5
+   |
+LL |     fn test() {}
+   |     --------- required by `Foo::test`
+...
+LL |     <() as Foo<N>>::test()
+   |     ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Foo<0_u8>>
+             <() as Foo<100_u8>>
+             <() as Foo<101_u8>>
+             <() as Foo<102_u8>>
+           and 252 others
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/exhaustive-value.rs b/src/test/ui/const-generics/exhaustive-value.rs
new file mode 100644
index 0000000000000..fce036b0da624
--- /dev/null
+++ b/src/test/ui/const-generics/exhaustive-value.rs
@@ -0,0 +1,272 @@
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+trait Foo<const N: u8> {
+    fn test() {}
+}
+impl Foo<0> for () {}
+impl Foo<1> for () {}
+impl Foo<2> for () {}
+impl Foo<3> for () {}
+impl Foo<4> for () {}
+impl Foo<5> for () {}
+impl Foo<6> for () {}
+impl Foo<7> for () {}
+impl Foo<8> for () {}
+impl Foo<9> for () {}
+impl Foo<10> for () {}
+impl Foo<11> for () {}
+impl Foo<12> for () {}
+impl Foo<13> for () {}
+impl Foo<14> for () {}
+impl Foo<15> for () {}
+impl Foo<16> for () {}
+impl Foo<17> for () {}
+impl Foo<18> for () {}
+impl Foo<19> for () {}
+impl Foo<20> for () {}
+impl Foo<21> for () {}
+impl Foo<22> for () {}
+impl Foo<23> for () {}
+impl Foo<24> for () {}
+impl Foo<25> for () {}
+impl Foo<26> for () {}
+impl Foo<27> for () {}
+impl Foo<28> for () {}
+impl Foo<29> for () {}
+impl Foo<30> for () {}
+impl Foo<31> for () {}
+impl Foo<32> for () {}
+impl Foo<33> for () {}
+impl Foo<34> for () {}
+impl Foo<35> for () {}
+impl Foo<36> for () {}
+impl Foo<37> for () {}
+impl Foo<38> for () {}
+impl Foo<39> for () {}
+impl Foo<40> for () {}
+impl Foo<41> for () {}
+impl Foo<42> for () {}
+impl Foo<43> for () {}
+impl Foo<44> for () {}
+impl Foo<45> for () {}
+impl Foo<46> for () {}
+impl Foo<47> for () {}
+impl Foo<48> for () {}
+impl Foo<49> for () {}
+impl Foo<50> for () {}
+impl Foo<51> for () {}
+impl Foo<52> for () {}
+impl Foo<53> for () {}
+impl Foo<54> for () {}
+impl Foo<55> for () {}
+impl Foo<56> for () {}
+impl Foo<57> for () {}
+impl Foo<58> for () {}
+impl Foo<59> for () {}
+impl Foo<60> for () {}
+impl Foo<61> for () {}
+impl Foo<62> for () {}
+impl Foo<63> for () {}
+impl Foo<64> for () {}
+impl Foo<65> for () {}
+impl Foo<66> for () {}
+impl Foo<67> for () {}
+impl Foo<68> for () {}
+impl Foo<69> for () {}
+impl Foo<70> for () {}
+impl Foo<71> for () {}
+impl Foo<72> for () {}
+impl Foo<73> for () {}
+impl Foo<74> for () {}
+impl Foo<75> for () {}
+impl Foo<76> for () {}
+impl Foo<77> for () {}
+impl Foo<78> for () {}
+impl Foo<79> for () {}
+impl Foo<80> for () {}
+impl Foo<81> for () {}
+impl Foo<82> for () {}
+impl Foo<83> for () {}
+impl Foo<84> for () {}
+impl Foo<85> for () {}
+impl Foo<86> for () {}
+impl Foo<87> for () {}
+impl Foo<88> for () {}
+impl Foo<89> for () {}
+impl Foo<90> for () {}
+impl Foo<91> for () {}
+impl Foo<92> for () {}
+impl Foo<93> for () {}
+impl Foo<94> for () {}
+impl Foo<95> for () {}
+impl Foo<96> for () {}
+impl Foo<97> for () {}
+impl Foo<98> for () {}
+impl Foo<99> for () {}
+impl Foo<100> for () {}
+impl Foo<101> for () {}
+impl Foo<102> for () {}
+impl Foo<103> for () {}
+impl Foo<104> for () {}
+impl Foo<105> for () {}
+impl Foo<106> for () {}
+impl Foo<107> for () {}
+impl Foo<108> for () {}
+impl Foo<109> for () {}
+impl Foo<110> for () {}
+impl Foo<111> for () {}
+impl Foo<112> for () {}
+impl Foo<113> for () {}
+impl Foo<114> for () {}
+impl Foo<115> for () {}
+impl Foo<116> for () {}
+impl Foo<117> for () {}
+impl Foo<118> for () {}
+impl Foo<119> for () {}
+impl Foo<120> for () {}
+impl Foo<121> for () {}
+impl Foo<122> for () {}
+impl Foo<123> for () {}
+impl Foo<124> for () {}
+impl Foo<125> for () {}
+impl Foo<126> for () {}
+impl Foo<127> for () {}
+impl Foo<128> for () {}
+impl Foo<129> for () {}
+impl Foo<130> for () {}
+impl Foo<131> for () {}
+impl Foo<132> for () {}
+impl Foo<133> for () {}
+impl Foo<134> for () {}
+impl Foo<135> for () {}
+impl Foo<136> for () {}
+impl Foo<137> for () {}
+impl Foo<138> for () {}
+impl Foo<139> for () {}
+impl Foo<140> for () {}
+impl Foo<141> for () {}
+impl Foo<142> for () {}
+impl Foo<143> for () {}
+impl Foo<144> for () {}
+impl Foo<145> for () {}
+impl Foo<146> for () {}
+impl Foo<147> for () {}
+impl Foo<148> for () {}
+impl Foo<149> for () {}
+impl Foo<150> for () {}
+impl Foo<151> for () {}
+impl Foo<152> for () {}
+impl Foo<153> for () {}
+impl Foo<154> for () {}
+impl Foo<155> for () {}
+impl Foo<156> for () {}
+impl Foo<157> for () {}
+impl Foo<158> for () {}
+impl Foo<159> for () {}
+impl Foo<160> for () {}
+impl Foo<161> for () {}
+impl Foo<162> for () {}
+impl Foo<163> for () {}
+impl Foo<164> for () {}
+impl Foo<165> for () {}
+impl Foo<166> for () {}
+impl Foo<167> for () {}
+impl Foo<168> for () {}
+impl Foo<169> for () {}
+impl Foo<170> for () {}
+impl Foo<171> for () {}
+impl Foo<172> for () {}
+impl Foo<173> for () {}
+impl Foo<174> for () {}
+impl Foo<175> for () {}
+impl Foo<176> for () {}
+impl Foo<177> for () {}
+impl Foo<178> for () {}
+impl Foo<179> for () {}
+impl Foo<180> for () {}
+impl Foo<181> for () {}
+impl Foo<182> for () {}
+impl Foo<183> for () {}
+impl Foo<184> for () {}
+impl Foo<185> for () {}
+impl Foo<186> for () {}
+impl Foo<187> for () {}
+impl Foo<188> for () {}
+impl Foo<189> for () {}
+impl Foo<190> for () {}
+impl Foo<191> for () {}
+impl Foo<192> for () {}
+impl Foo<193> for () {}
+impl Foo<194> for () {}
+impl Foo<195> for () {}
+impl Foo<196> for () {}
+impl Foo<197> for () {}
+impl Foo<198> for () {}
+impl Foo<199> for () {}
+impl Foo<200> for () {}
+impl Foo<201> for () {}
+impl Foo<202> for () {}
+impl Foo<203> for () {}
+impl Foo<204> for () {}
+impl Foo<205> for () {}
+impl Foo<206> for () {}
+impl Foo<207> for () {}
+impl Foo<208> for () {}
+impl Foo<209> for () {}
+impl Foo<210> for () {}
+impl Foo<211> for () {}
+impl Foo<212> for () {}
+impl Foo<213> for () {}
+impl Foo<214> for () {}
+impl Foo<215> for () {}
+impl Foo<216> for () {}
+impl Foo<217> for () {}
+impl Foo<218> for () {}
+impl Foo<219> for () {}
+impl Foo<220> for () {}
+impl Foo<221> for () {}
+impl Foo<222> for () {}
+impl Foo<223> for () {}
+impl Foo<224> for () {}
+impl Foo<225> for () {}
+impl Foo<226> for () {}
+impl Foo<227> for () {}
+impl Foo<228> for () {}
+impl Foo<229> for () {}
+impl Foo<230> for () {}
+impl Foo<231> for () {}
+impl Foo<232> for () {}
+impl Foo<233> for () {}
+impl Foo<234> for () {}
+impl Foo<235> for () {}
+impl Foo<236> for () {}
+impl Foo<237> for () {}
+impl Foo<238> for () {}
+impl Foo<239> for () {}
+impl Foo<240> for () {}
+impl Foo<241> for () {}
+impl Foo<242> for () {}
+impl Foo<243> for () {}
+impl Foo<244> for () {}
+impl Foo<245> for () {}
+impl Foo<246> for () {}
+impl Foo<247> for () {}
+impl Foo<248> for () {}
+impl Foo<249> for () {}
+impl Foo<250> for () {}
+impl Foo<251> for () {}
+impl Foo<252> for () {}
+impl Foo<253> for () {}
+impl Foo<254> for () {}
+impl Foo<255> for () {}
+
+fn foo<const N: u8>() {
+    <() as Foo<N>>::test() //~ ERROR the trait bound `(): Foo<N>`
+}
+
+fn main() {
+    foo::<7>();
+}
diff --git a/src/test/ui/const-generics/generic-param-mismatch.full.stderr b/src/test/ui/const-generics/generic-param-mismatch.full.stderr
new file mode 100644
index 0000000000000..6befa9d1f6994
--- /dev/null
+++ b/src/test/ui/const-generics/generic-param-mismatch.full.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/generic-param-mismatch.rs:7:5
+   |
+LL | fn test<const N: usize, const M: usize>() -> [u8; M] {
+   |                                              ------- expected `[u8; M]` because of return type
+LL |     [0; N]
+   |     ^^^^^^ expected `M`, found `N`
+   |
+   = note: expected array `[u8; M]`
+              found array `[u8; N]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic-param-mismatch.min.stderr b/src/test/ui/const-generics/generic-param-mismatch.min.stderr
new file mode 100644
index 0000000000000..6befa9d1f6994
--- /dev/null
+++ b/src/test/ui/const-generics/generic-param-mismatch.min.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/generic-param-mismatch.rs:7:5
+   |
+LL | fn test<const N: usize, const M: usize>() -> [u8; M] {
+   |                                              ------- expected `[u8; M]` because of return type
+LL |     [0; N]
+   |     ^^^^^^ expected `M`, found `N`
+   |
+   = note: expected array `[u8; M]`
+              found array `[u8; N]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic-param-mismatch.rs b/src/test/ui/const-generics/generic-param-mismatch.rs
new file mode 100644
index 0000000000000..e409094eb734c
--- /dev/null
+++ b/src/test/ui/const-generics/generic-param-mismatch.rs
@@ -0,0 +1,10 @@
+// revisions: full min
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+fn test<const N: usize, const M: usize>() -> [u8; M] {
+    [0; N] //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/macro_rules-braces.full.stderr b/src/test/ui/const-generics/macro_rules-braces.full.stderr
new file mode 100644
index 0000000000000..f6e9aabd90774
--- /dev/null
+++ b/src/test/ui/const-generics/macro_rules-braces.full.stderr
@@ -0,0 +1,61 @@
+error: expressions must be enclosed in braces to be used as const generic arguments
+  --> $DIR/macro_rules-braces.rs:34:17
+   |
+LL |     let _: baz!(N);
+   |                 ^
+   |
+help: enclose the `const` expression in braces
+   |
+LL |     let _: baz!({ N });
+   |                 ^   ^
+
+error: constant expression depends on a generic parameter
+  --> $DIR/macro_rules-braces.rs:10:13
+   |
+LL |             [u8; $x]
+   |             ^^^^^^^^
+...
+LL |     let _: foo!({{ N }});
+   |            ------------- in this macro invocation
+   |
+   = note: this may fail depending on what value the parameter takes
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: constant expression depends on a generic parameter
+  --> $DIR/macro_rules-braces.rs:15:13
+   |
+LL |             [u8; { $x }]
+   |             ^^^^^^^^^^^^
+...
+LL |     let _: bar!({ N });
+   |            ----------- in this macro invocation
+   |
+   = note: this may fail depending on what value the parameter takes
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: constant expression depends on a generic parameter
+  --> $DIR/macro_rules-braces.rs:20:13
+   |
+LL |             Foo<$x>
+   |             ^^^^^^^
+...
+LL |     let _: baz!({{ N }});
+   |            ------------- in this macro invocation
+   |
+   = note: this may fail depending on what value the parameter takes
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: constant expression depends on a generic parameter
+  --> $DIR/macro_rules-braces.rs:25:13
+   |
+LL |             Foo<{ $x }>
+   |             ^^^^^^^^^^^
+...
+LL |     let _: biz!({ N });
+   |            ----------- in this macro invocation
+   |
+   = note: this may fail depending on what value the parameter takes
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/const-generics/macro_rules-braces.min.stderr b/src/test/ui/const-generics/macro_rules-braces.min.stderr
new file mode 100644
index 0000000000000..1fe18e3fc0231
--- /dev/null
+++ b/src/test/ui/const-generics/macro_rules-braces.min.stderr
@@ -0,0 +1,45 @@
+error: expressions must be enclosed in braces to be used as const generic arguments
+  --> $DIR/macro_rules-braces.rs:34:17
+   |
+LL |     let _: baz!(N);
+   |                 ^
+   |
+help: enclose the `const` expression in braces
+   |
+LL |     let _: baz!({ N });
+   |                 ^   ^
+
+error: generic parameters may not be used in const operations
+  --> $DIR/macro_rules-braces.rs:31:20
+   |
+LL |     let _: foo!({{ N }});
+   |                    ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: generic parameters may not be used in const operations
+  --> $DIR/macro_rules-braces.rs:33:19
+   |
+LL |     let _: bar!({ N });
+   |                   ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: generic parameters may not be used in const operations
+  --> $DIR/macro_rules-braces.rs:36:20
+   |
+LL |     let _: baz!({{ N }});
+   |                    ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: generic parameters may not be used in const operations
+  --> $DIR/macro_rules-braces.rs:38:19
+   |
+LL |     let _: biz!({ N });
+   |                   ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/const-generics/macro_rules-braces.rs b/src/test/ui/const-generics/macro_rules-braces.rs
new file mode 100644
index 0000000000000..c3e2c8ba20359
--- /dev/null
+++ b/src/test/ui/const-generics/macro_rules-braces.rs
@@ -0,0 +1,43 @@
+// revisions: full min
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+fn test<const N: usize>() {
+    struct Foo<const M: usize>;
+    macro_rules! foo {
+        ($x:expr) => {
+            [u8; $x] //[full]~ ERROR constant expression depends
+        }
+    }
+    macro_rules! bar {
+        ($x:expr) => {
+            [u8; { $x }] //[full]~ ERROR constant expression depends
+        }
+    }
+    macro_rules! baz {
+        ( $x:expr) => {
+            Foo<$x> //[full]~ ERROR constant expression depends
+        }
+    }
+    macro_rules! biz {
+        ($x:expr) => {
+            Foo<{ $x }> //[full]~ ERROR constant expression depends
+        };
+    }
+
+    let _: foo!(N);
+    let _: foo!({ N });
+    let _: foo!({{ N }}); //[min]~ ERROR generic parameters may not
+    let _: bar!(N);
+    let _: bar!({ N }); //[min]~ ERROR generic parameters may not
+    let _: baz!(N); //~ ERROR expressions must be enclosed in braces
+    let _: baz!({ N });
+    let _: baz!({{ N }}); //[min]~ ERROR generic parameters may not
+    let _: biz!(N);
+    let _: biz!({ N }); //[min]~ ERROR generic parameters may not
+}
+
+fn main() {
+    test::<3>();
+}
diff --git a/src/test/ui/const-generics/where-clauses.rs b/src/test/ui/const-generics/where-clauses.rs
new file mode 100644
index 0000000000000..cdcaf25094240
--- /dev/null
+++ b/src/test/ui/const-generics/where-clauses.rs
@@ -0,0 +1,35 @@
+// check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+trait Bar<const N: usize> { fn bar() {} }
+trait Foo<const N: usize>: Bar<N> {}
+
+fn test<T, const N: usize>() where T: Foo<N> {
+    <T as Bar<N>>::bar();
+}
+
+struct Faz<const N: usize>;
+
+impl<const N: usize> Faz<N> {
+    fn test<T>() where T: Foo<N> {
+        <T as Bar<N>>::bar()
+    }
+}
+
+trait Fiz<const N: usize> {
+    fn fiz<T>() where T: Foo<N> {
+        <T as Bar<N>>::bar();
+    }
+}
+
+impl<const N: usize> Bar<N> for u8 {}
+impl<const N: usize> Foo<N> for u8 {}
+impl<const N: usize> Fiz<N> for u8 {}
+fn main() {
+    test::<u8, 13>();
+    Faz::<3>::test::<u8>();
+    <u8 as Fiz<13>>::fiz::<u8>();
+}