summaryrefslogtreecommitdiffstats
path: root/tests/ui/associated-consts
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/associated-consts')
-rw-r--r--tests/ui/associated-consts/assoc-const-eq-missing.rs26
-rw-r--r--tests/ui/associated-consts/assoc-const-eq-missing.stderr21
-rw-r--r--tests/ui/associated-consts/assoc-const-ty-mismatch.rs31
-rw-r--r--tests/ui/associated-consts/assoc-const-ty-mismatch.stderr26
-rw-r--r--tests/ui/associated-consts/assoc-const.rs22
-rw-r--r--tests/ui/associated-consts/associated-const-ambiguity-report.rs21
-rw-r--r--tests/ui/associated-consts/associated-const-ambiguity-report.stderr28
-rw-r--r--tests/ui/associated-consts/associated-const-array-len.rs10
-rw-r--r--tests/ui/associated-consts/associated-const-array-len.stderr9
-rw-r--r--tests/ui/associated-consts/associated-const-const-eval.rs20
-rw-r--r--tests/ui/associated-consts/associated-const-cross-crate-const-eval.rs28
-rw-r--r--tests/ui/associated-consts/associated-const-cross-crate-defaults.rs22
-rw-r--r--tests/ui/associated-consts/associated-const-cross-crate.rs17
-rw-r--r--tests/ui/associated-consts/associated-const-dead-code.rs12
-rw-r--r--tests/ui/associated-consts/associated-const-dead-code.stderr14
-rw-r--r--tests/ui/associated-consts/associated-const-generic-obligations.rs18
-rw-r--r--tests/ui/associated-consts/associated-const-generic-obligations.stderr17
-rw-r--r--tests/ui/associated-consts/associated-const-impl-wrong-lifetime.rs11
-rw-r--r--tests/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr18
-rw-r--r--tests/ui/associated-consts/associated-const-impl-wrong-type.rs12
-rw-r--r--tests/ui/associated-consts/associated-const-impl-wrong-type.stderr15
-rw-r--r--tests/ui/associated-consts/associated-const-in-global-const.rs13
-rw-r--r--tests/ui/associated-consts/associated-const-in-trait.rs12
-rw-r--r--tests/ui/associated-consts/associated-const-in-trait.stderr18
-rw-r--r--tests/ui/associated-consts/associated-const-inherent-impl.rs11
-rw-r--r--tests/ui/associated-consts/associated-const-marks-live-code.rs15
-rw-r--r--tests/ui/associated-consts/associated-const-match-patterns.rs68
-rw-r--r--tests/ui/associated-consts/associated-const-no-item.rs10
-rw-r--r--tests/ui/associated-consts/associated-const-no-item.stderr16
-rw-r--r--tests/ui/associated-consts/associated-const-outer-ty-refs.rs10
-rw-r--r--tests/ui/associated-consts/associated-const-overwrite-default.rs13
-rw-r--r--tests/ui/associated-consts/associated-const-private-impl.rs15
-rw-r--r--tests/ui/associated-consts/associated-const-private-impl.stderr12
-rw-r--r--tests/ui/associated-consts/associated-const-public-impl.rs16
-rw-r--r--tests/ui/associated-consts/associated-const-range-match-patterns.rs40
-rw-r--r--tests/ui/associated-consts/associated-const-resolution-order.rs25
-rw-r--r--tests/ui/associated-consts/associated-const-self-type.rs13
-rw-r--r--tests/ui/associated-consts/associated-const-trait-bound.rs21
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arms.rs29
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arms.stderr15
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs21
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr10
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays.rs20
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr11
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameters.rs44
-rw-r--r--tests/ui/associated-consts/associated-const-ufcs-infer-trait.rs13
-rw-r--r--tests/ui/associated-consts/associated-const-use-default.rs11
-rw-r--r--tests/ui/associated-consts/associated-const-use-impl-of-same-trait.rs25
-rw-r--r--tests/ui/associated-consts/associated-const.rs13
-rw-r--r--tests/ui/associated-consts/auxiliary/associated-const-cc-lib.rs34
-rw-r--r--tests/ui/associated-consts/auxiliary/empty-struct.rs9
-rw-r--r--tests/ui/associated-consts/defaults-cyclic-fail.rs17
-rw-r--r--tests/ui/associated-consts/defaults-cyclic-fail.stderr21
-rw-r--r--tests/ui/associated-consts/defaults-cyclic-pass.rs36
-rw-r--r--tests/ui/associated-consts/defaults-not-assumed-fail.rs44
-rw-r--r--tests/ui/associated-consts/defaults-not-assumed-fail.stderr39
-rw-r--r--tests/ui/associated-consts/defaults-not-assumed-pass.rs42
-rw-r--r--tests/ui/associated-consts/issue-102335-const.rs12
-rw-r--r--tests/ui/associated-consts/issue-102335-const.stderr9
-rw-r--r--tests/ui/associated-consts/issue-105330.rs21
-rw-r--r--tests/ui/associated-consts/issue-105330.stderr113
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs15
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr32
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs17
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr32
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs15
-rw-r--r--tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr32
-rw-r--r--tests/ui/associated-consts/issue-47814.rs14
-rw-r--r--tests/ui/associated-consts/issue-47814.stderr14
-rw-r--r--tests/ui/associated-consts/issue-58022.rs19
-rw-r--r--tests/ui/associated-consts/issue-58022.stderr19
-rw-r--r--tests/ui/associated-consts/issue-63496.rs9
-rw-r--r--tests/ui/associated-consts/issue-63496.stderr21
-rw-r--r--tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.noopt.stderr54
-rw-r--r--tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt.stderr54
-rw-r--r--tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr54
-rw-r--r--tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs46
-rw-r--r--tests/ui/associated-consts/issue-88599-ref-self.rs24
-rw-r--r--tests/ui/associated-consts/issue-93775.rs29
-rw-r--r--tests/ui/associated-consts/issue-93835.rs12
-rw-r--r--tests/ui/associated-consts/issue-93835.stderr40
-rw-r--r--tests/ui/associated-consts/mismatched_impl_ty_1.rs18
-rw-r--r--tests/ui/associated-consts/mismatched_impl_ty_2.rs11
-rw-r--r--tests/ui/associated-consts/mismatched_impl_ty_3.rs11
-rw-r--r--tests/ui/associated-consts/shadowed-const.rs23
-rw-r--r--tests/ui/associated-consts/shadowed-const.stderr8
86 files changed, 1958 insertions, 0 deletions
diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.rs b/tests/ui/associated-consts/assoc-const-eq-missing.rs
new file mode 100644
index 000000000..5e029a12d
--- /dev/null
+++ b/tests/ui/associated-consts/assoc-const-eq-missing.rs
@@ -0,0 +1,26 @@
+#![feature(associated_const_equality)]
+#![allow(unused)]
+
+pub trait Foo {
+ const N: usize;
+}
+
+pub struct Bar;
+
+impl Foo for Bar {
+ const N: usize = 3;
+}
+
+
+fn foo1<F: Foo<Z=3>>() {}
+//~^ ERROR associated type
+fn foo2<F: Foo<Z=usize>>() {}
+//~^ ERROR associated type
+fn foo3<F: Foo<Z=5>>() {}
+//~^ ERROR associated type
+
+fn main() {
+ foo1::<Bar>();
+ foo2::<Bar>();
+ foo3::<Bar>();
+}
diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.stderr b/tests/ui/associated-consts/assoc-const-eq-missing.stderr
new file mode 100644
index 000000000..b4bd6456c
--- /dev/null
+++ b/tests/ui/associated-consts/assoc-const-eq-missing.stderr
@@ -0,0 +1,21 @@
+error[E0220]: associated type `Z` not found for `Foo`
+ --> $DIR/assoc-const-eq-missing.rs:15:16
+ |
+LL | fn foo1<F: Foo<Z=3>>() {}
+ | ^ associated type `Z` not found
+
+error[E0220]: associated type `Z` not found for `Foo`
+ --> $DIR/assoc-const-eq-missing.rs:17:16
+ |
+LL | fn foo2<F: Foo<Z=usize>>() {}
+ | ^ associated type `Z` not found
+
+error[E0220]: associated type `Z` not found for `Foo`
+ --> $DIR/assoc-const-eq-missing.rs:19:16
+ |
+LL | fn foo3<F: Foo<Z=5>>() {}
+ | ^ associated type `Z` not found
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.rs b/tests/ui/associated-consts/assoc-const-ty-mismatch.rs
new file mode 100644
index 000000000..c5d78469e
--- /dev/null
+++ b/tests/ui/associated-consts/assoc-const-ty-mismatch.rs
@@ -0,0 +1,31 @@
+#![feature(associated_const_equality)]
+#![allow(unused)]
+
+pub trait Foo {
+ const N: usize;
+}
+
+pub trait FooTy {
+ type T;
+}
+
+pub struct Bar;
+
+impl Foo for Bar {
+ const N: usize = 3;
+}
+
+impl FooTy for Bar {
+ type T = usize;
+}
+
+
+fn foo<F: Foo<N=usize>>() {}
+//~^ ERROR expected associated constant bound, found type
+fn foo2<F: FooTy<T=3usize>>() {}
+//~^ ERROR expected associated type bound, found constant
+
+fn main() {
+ foo::<Bar>();
+ foo2::<Bar>();
+}
diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.stderr b/tests/ui/associated-consts/assoc-const-ty-mismatch.stderr
new file mode 100644
index 000000000..11198729e
--- /dev/null
+++ b/tests/ui/associated-consts/assoc-const-ty-mismatch.stderr
@@ -0,0 +1,26 @@
+error: expected associated constant bound, found type
+ --> $DIR/assoc-const-ty-mismatch.rs:23:15
+ |
+LL | fn foo<F: Foo<N=usize>>() {}
+ | ^^^^^^^
+ |
+note: associated constant defined here
+ --> $DIR/assoc-const-ty-mismatch.rs:5:3
+ |
+LL | const N: usize;
+ | ^^^^^^^^^^^^^^
+
+error: expected associated type bound, found constant
+ --> $DIR/assoc-const-ty-mismatch.rs:25:18
+ |
+LL | fn foo2<F: FooTy<T=3usize>>() {}
+ | ^^^^^^^^
+ |
+note: associated type defined here
+ --> $DIR/assoc-const-ty-mismatch.rs:9:3
+ |
+LL | type T;
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/associated-consts/assoc-const.rs b/tests/ui/associated-consts/assoc-const.rs
new file mode 100644
index 000000000..9c7884c80
--- /dev/null
+++ b/tests/ui/associated-consts/assoc-const.rs
@@ -0,0 +1,22 @@
+// run-pass
+#![feature(associated_const_equality)]
+#![allow(unused)]
+
+pub trait Foo {
+ const N: usize;
+}
+
+pub struct Bar;
+
+impl Foo for Bar {
+ const N: usize = 3;
+}
+
+const TEST:usize = 3;
+
+
+fn foo<F: Foo<N=3usize>>() {}
+
+fn main() {
+ foo::<Bar>()
+}
diff --git a/tests/ui/associated-consts/associated-const-ambiguity-report.rs b/tests/ui/associated-consts/associated-const-ambiguity-report.rs
new file mode 100644
index 000000000..927d2c69e
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-ambiguity-report.rs
@@ -0,0 +1,21 @@
+trait Foo {
+ const ID: i32;
+}
+
+trait Bar {
+ const ID: i32;
+}
+
+impl Foo for i32 {
+ const ID: i32 = 1;
+}
+
+impl Bar for i32 {
+ const ID: i32 = 3;
+}
+
+const X: i32 = <i32>::ID; //~ ERROR E0034
+
+fn main() {
+ assert_eq!(1, X);
+}
diff --git a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr
new file mode 100644
index 000000000..5435f2232
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr
@@ -0,0 +1,28 @@
+error[E0034]: multiple applicable items in scope
+ --> $DIR/associated-const-ambiguity-report.rs:17:23
+ |
+LL | const X: i32 = <i32>::ID;
+ | ^^ multiple `ID` found
+ |
+note: candidate #1 is defined in an impl of the trait `Foo` for the type `i32`
+ --> $DIR/associated-const-ambiguity-report.rs:10:5
+ |
+LL | const ID: i32 = 1;
+ | ^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32`
+ --> $DIR/associated-const-ambiguity-report.rs:14:5
+ |
+LL | const ID: i32 = 3;
+ | ^^^^^^^^^^^^^
+help: disambiguate the associated constant for candidate #1
+ |
+LL | const X: i32 = <i32 as Foo>::ID;
+ | ~~~~~~~~~~~~~~
+help: disambiguate the associated constant for candidate #2
+ |
+LL | const X: i32 = <i32 as Bar>::ID;
+ | ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/associated-consts/associated-const-array-len.rs b/tests/ui/associated-consts/associated-const-array-len.rs
new file mode 100644
index 000000000..17d782427
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-array-len.rs
@@ -0,0 +1,10 @@
+trait Foo {
+ const ID: usize;
+}
+
+const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
+//~^ ERROR the trait bound `i32: Foo` is not satisfied
+
+fn main() {
+ assert_eq!(1, X);
+}
diff --git a/tests/ui/associated-consts/associated-const-array-len.stderr b/tests/ui/associated-consts/associated-const-array-len.stderr
new file mode 100644
index 000000000..86c62e7b7
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-array-len.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `i32: Foo` is not satisfied
+ --> $DIR/associated-const-array-len.rs:5:16
+ |
+LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
+ | ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-consts/associated-const-const-eval.rs b/tests/ui/associated-consts/associated-const-const-eval.rs
new file mode 100644
index 000000000..5a34bb97c
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-const-eval.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+trait Foo {
+ const NUM: usize;
+}
+
+impl Foo for i32 {
+ const NUM: usize = 1;
+}
+
+const FOO: usize = <i32 as Foo>::NUM;
+
+fn main() {
+ assert_eq!(1, FOO);
+
+ match 1 {
+ <i32 as Foo>::NUM => {},
+ _ => assert!(false)
+ }
+}
diff --git a/tests/ui/associated-consts/associated-const-cross-crate-const-eval.rs b/tests/ui/associated-consts/associated-const-cross-crate-const-eval.rs
new file mode 100644
index 000000000..611639b84
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-cross-crate-const-eval.rs
@@ -0,0 +1,28 @@
+// run-pass
+// aux-build:associated-const-cc-lib.rs
+
+
+extern crate associated_const_cc_lib as foolib;
+
+pub struct LocalFoo;
+
+impl foolib::Foo for LocalFoo {
+ const BAR: usize = 1;
+}
+
+const FOO_1: usize = <foolib::FooNoDefault as foolib::Foo>::BAR;
+const FOO_2: usize = <LocalFoo as foolib::Foo>::BAR;
+const FOO_3: usize = foolib::InherentBar::BAR;
+
+fn main() {
+ assert_eq!(0, FOO_1);
+ assert_eq!(1, FOO_2);
+ assert_eq!(3, FOO_3);
+
+ match 0 {
+ <foolib::FooNoDefault as foolib::Foo>::BAR => {},
+ <LocalFoo as foolib::Foo>::BAR => assert!(false),
+ foolib::InherentBar::BAR => assert!(false),
+ _ => assert!(false)
+ }
+}
diff --git a/tests/ui/associated-consts/associated-const-cross-crate-defaults.rs b/tests/ui/associated-consts/associated-const-cross-crate-defaults.rs
new file mode 100644
index 000000000..92d9cffec
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-cross-crate-defaults.rs
@@ -0,0 +1,22 @@
+// run-pass
+// aux-build:associated-const-cc-lib.rs
+
+
+extern crate associated_const_cc_lib as foolib;
+
+pub struct LocalFooUseDefault;
+
+impl foolib::FooDefault for LocalFooUseDefault {}
+
+pub struct LocalFooOverwriteDefault;
+
+impl foolib::FooDefault for LocalFooOverwriteDefault {
+ const BAR: usize = 4;
+}
+
+fn main() {
+ assert_eq!(1, <foolib::FooUseDefault as foolib::FooDefault>::BAR);
+ assert_eq!(2, <foolib::FooOverwriteDefault as foolib::FooDefault>::BAR);
+ assert_eq!(1, <LocalFooUseDefault as foolib::FooDefault>::BAR);
+ assert_eq!(4, <LocalFooOverwriteDefault as foolib::FooDefault>::BAR);
+}
diff --git a/tests/ui/associated-consts/associated-const-cross-crate.rs b/tests/ui/associated-consts/associated-const-cross-crate.rs
new file mode 100644
index 000000000..ecdc112e0
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-cross-crate.rs
@@ -0,0 +1,17 @@
+// run-pass
+// aux-build:associated-const-cc-lib.rs
+
+
+extern crate associated_const_cc_lib as foolib;
+
+pub struct LocalFoo;
+
+impl foolib::Foo for LocalFoo {
+ const BAR: usize = 1;
+}
+
+fn main() {
+ assert_eq!(0, <foolib::FooNoDefault as foolib::Foo>::BAR);
+ assert_eq!(1, <LocalFoo as foolib::Foo>::BAR);
+ assert_eq!(3, foolib::InherentBar::BAR);
+}
diff --git a/tests/ui/associated-consts/associated-const-dead-code.rs b/tests/ui/associated-consts/associated-const-dead-code.rs
new file mode 100644
index 000000000..f7b676418
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-dead-code.rs
@@ -0,0 +1,12 @@
+#![deny(dead_code)]
+
+struct MyFoo;
+
+impl MyFoo {
+ const BAR: u32 = 1;
+ //~^ ERROR associated constant `BAR` is never used
+}
+
+fn main() {
+ let _: MyFoo = MyFoo;
+}
diff --git a/tests/ui/associated-consts/associated-const-dead-code.stderr b/tests/ui/associated-consts/associated-const-dead-code.stderr
new file mode 100644
index 000000000..cc701cc4b
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-dead-code.stderr
@@ -0,0 +1,14 @@
+error: associated constant `BAR` is never used
+ --> $DIR/associated-const-dead-code.rs:6:11
+ |
+LL | const BAR: u32 = 1;
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/associated-const-dead-code.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-consts/associated-const-generic-obligations.rs b/tests/ui/associated-consts/associated-const-generic-obligations.rs
new file mode 100644
index 000000000..498e315b5
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-generic-obligations.rs
@@ -0,0 +1,18 @@
+trait Foo {
+ type Out: Sized;
+}
+
+impl Foo for String {
+ type Out = String;
+}
+
+trait Bar: Foo {
+ const FROM: Self::Out;
+}
+
+impl<T: Foo> Bar for T {
+ const FROM: &'static str = "foo";
+ //~^ ERROR implemented const `FROM` has an incompatible type for trait [E0326]
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-generic-obligations.stderr b/tests/ui/associated-consts/associated-const-generic-obligations.stderr
new file mode 100644
index 000000000..f45fa0ad5
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-generic-obligations.stderr
@@ -0,0 +1,17 @@
+error[E0326]: implemented const `FROM` has an incompatible type for trait
+ --> $DIR/associated-const-generic-obligations.rs:14:17
+ |
+LL | const FROM: &'static str = "foo";
+ | ^^^^^^^^^^^^ expected associated type, found `&str`
+ |
+note: type in trait
+ --> $DIR/associated-const-generic-obligations.rs:10:17
+ |
+LL | const FROM: Self::Out;
+ | ^^^^^^^^^
+ = note: expected associated type `<T as Foo>::Out`
+ found reference `&'static str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0326`.
diff --git a/tests/ui/associated-consts/associated-const-impl-wrong-lifetime.rs b/tests/ui/associated-consts/associated-const-impl-wrong-lifetime.rs
new file mode 100644
index 000000000..63bac9613
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-impl-wrong-lifetime.rs
@@ -0,0 +1,11 @@
+trait Foo {
+ const NAME: &'static str;
+}
+
+
+impl<'a> Foo for &'a () {
+ const NAME: &'a str = "unit";
+ //~^ ERROR const not compatible with trait
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr b/tests/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr
new file mode 100644
index 000000000..742b81535
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr
@@ -0,0 +1,18 @@
+error[E0308]: const not compatible with trait
+ --> $DIR/associated-const-impl-wrong-lifetime.rs:7:5
+ |
+LL | const NAME: &'a str = "unit";
+ | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+ |
+ = note: expected reference `&'static str`
+ found reference `&'a str`
+note: the lifetime `'a` as defined here...
+ --> $DIR/associated-const-impl-wrong-lifetime.rs:6:6
+ |
+LL | impl<'a> Foo for &'a () {
+ | ^^
+ = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-consts/associated-const-impl-wrong-type.rs b/tests/ui/associated-consts/associated-const-impl-wrong-type.rs
new file mode 100644
index 000000000..1aad749c1
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-impl-wrong-type.rs
@@ -0,0 +1,12 @@
+trait Foo {
+ const BAR: u32;
+}
+
+struct SignedBar;
+
+impl Foo for SignedBar {
+ const BAR: i32 = -1;
+ //~^ ERROR implemented const `BAR` has an incompatible type for trait [E0326]
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr b/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr
new file mode 100644
index 000000000..f3616035f
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr
@@ -0,0 +1,15 @@
+error[E0326]: implemented const `BAR` has an incompatible type for trait
+ --> $DIR/associated-const-impl-wrong-type.rs:8:16
+ |
+LL | const BAR: i32 = -1;
+ | ^^^ expected `u32`, found `i32`
+ |
+note: type in trait
+ --> $DIR/associated-const-impl-wrong-type.rs:2:16
+ |
+LL | const BAR: u32;
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0326`.
diff --git a/tests/ui/associated-consts/associated-const-in-global-const.rs b/tests/ui/associated-consts/associated-const-in-global-const.rs
new file mode 100644
index 000000000..18d7a1215
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-in-global-const.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+struct Foo;
+
+impl Foo {
+ const BAR: f32 = 1.5;
+}
+
+const FOOBAR: f32 = <Foo>::BAR;
+
+fn main() {
+ assert_eq!(1.5f32, FOOBAR);
+}
diff --git a/tests/ui/associated-consts/associated-const-in-trait.rs b/tests/ui/associated-consts/associated-const-in-trait.rs
new file mode 100644
index 000000000..cf5d5d859
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-in-trait.rs
@@ -0,0 +1,12 @@
+// #29924
+
+trait Trait {
+ const N: usize;
+}
+
+impl dyn Trait {
+ //~^ ERROR the trait `Trait` cannot be made into an object [E0038]
+ const fn n() -> usize { Self::N }
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr
new file mode 100644
index 000000000..60bbe385c
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-in-trait.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/associated-const-in-trait.rs:7:6
+ |
+LL | impl dyn Trait {
+ | ^^^^^^^^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/associated-const-in-trait.rs:4:11
+ |
+LL | trait Trait {
+ | ----- this trait cannot be made into an object...
+LL | const N: usize;
+ | ^ ...because it contains this associated `const`
+ = help: consider moving `N` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/associated-consts/associated-const-inherent-impl.rs b/tests/ui/associated-consts/associated-const-inherent-impl.rs
new file mode 100644
index 000000000..c6d956dff
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-inherent-impl.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+struct Foo;
+
+impl Foo {
+ const ID: i32 = 1;
+}
+
+fn main() {
+ assert_eq!(1, Foo::ID);
+}
diff --git a/tests/ui/associated-consts/associated-const-marks-live-code.rs b/tests/ui/associated-consts/associated-const-marks-live-code.rs
new file mode 100644
index 000000000..68eb4e25d
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-marks-live-code.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![deny(dead_code)]
+
+const GLOBAL_BAR: u32 = 1;
+
+struct Foo;
+
+impl Foo {
+ const BAR: u32 = GLOBAL_BAR;
+}
+
+pub fn main() {
+ let _: u32 = Foo::BAR;
+}
diff --git a/tests/ui/associated-consts/associated-const-match-patterns.rs b/tests/ui/associated-consts/associated-const-match-patterns.rs
new file mode 100644
index 000000000..62c1cb983
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-match-patterns.rs
@@ -0,0 +1,68 @@
+// run-pass
+// aux-build:empty-struct.rs
+
+
+extern crate empty_struct;
+use empty_struct::XEmpty2 as XFoo;
+
+struct Foo;
+
+#[derive(PartialEq, Eq)]
+enum Bar {
+ Var1,
+ Var2,
+}
+
+// Use inherent and trait impls to test UFCS syntax.
+impl Foo {
+ const MYBAR: Bar = Bar::Var2;
+}
+
+trait HasBar {
+ const THEBAR: Bar;
+}
+
+impl HasBar for Foo {
+ const THEBAR: Bar = Bar::Var1;
+}
+
+impl HasBar for XFoo {
+ const THEBAR: Bar = Bar::Var1;
+}
+
+fn main() {
+ // Inherent impl
+ assert!(match Bar::Var2 {
+ Foo::MYBAR => true,
+ _ => false,
+ });
+ assert!(match Bar::Var2 {
+ <Foo>::MYBAR => true,
+ _ => false,
+ });
+ // Trait impl
+ assert!(match Bar::Var1 {
+ Foo::THEBAR => true,
+ _ => false,
+ });
+ assert!(match Bar::Var1 {
+ <Foo>::THEBAR => true,
+ _ => false,
+ });
+ assert!(match Bar::Var1 {
+ <Foo as HasBar>::THEBAR => true,
+ _ => false,
+ });
+ assert!(match Bar::Var1 {
+ XFoo::THEBAR => true,
+ _ => false,
+ });
+ assert!(match Bar::Var1 {
+ <XFoo>::THEBAR => true,
+ _ => false,
+ });
+ assert!(match Bar::Var1 {
+ <XFoo as HasBar>::THEBAR => true,
+ _ => false,
+ });
+}
diff --git a/tests/ui/associated-consts/associated-const-no-item.rs b/tests/ui/associated-consts/associated-const-no-item.rs
new file mode 100644
index 000000000..024d14e21
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-no-item.rs
@@ -0,0 +1,10 @@
+trait Foo {
+ const ID: i32;
+}
+
+const X: i32 = <i32>::ID;
+//~^ ERROR no associated item named `ID` found
+
+fn main() {
+ assert_eq!(1, X);
+}
diff --git a/tests/ui/associated-consts/associated-const-no-item.stderr b/tests/ui/associated-consts/associated-const-no-item.stderr
new file mode 100644
index 000000000..fe27da5ac
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-no-item.stderr
@@ -0,0 +1,16 @@
+error[E0599]: no associated item named `ID` found for type `i32` in the current scope
+ --> $DIR/associated-const-no-item.rs:5:23
+ |
+LL | const X: i32 = <i32>::ID;
+ | ^^ associated item not found in `i32`
+ |
+ = help: items from traits can only be used if the trait is implemented and in scope
+note: `Foo` defines an item `ID`, perhaps you need to implement it
+ --> $DIR/associated-const-no-item.rs:1:1
+ |
+LL | trait Foo {
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/associated-consts/associated-const-outer-ty-refs.rs b/tests/ui/associated-consts/associated-const-outer-ty-refs.rs
new file mode 100644
index 000000000..f32ca0ccc
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-outer-ty-refs.rs
@@ -0,0 +1,10 @@
+// run-pass
+trait Lattice {
+ const BOTTOM: Self;
+}
+
+impl<T> Lattice for Option<T> {
+ const BOTTOM: Option<T> = None;
+}
+
+fn main(){}
diff --git a/tests/ui/associated-consts/associated-const-overwrite-default.rs b/tests/ui/associated-consts/associated-const-overwrite-default.rs
new file mode 100644
index 000000000..445135aef
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-overwrite-default.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+trait Foo {
+ const ID: i32 = 2;
+}
+
+impl Foo for i32 {
+ const ID: i32 = 1;
+}
+
+fn main() {
+ assert_eq!(1, <i32 as Foo>::ID);
+}
diff --git a/tests/ui/associated-consts/associated-const-private-impl.rs b/tests/ui/associated-consts/associated-const-private-impl.rs
new file mode 100644
index 000000000..3ee3134ac
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-private-impl.rs
@@ -0,0 +1,15 @@
+mod bar1 {
+ pub use self::bar2::Foo;
+ mod bar2 {
+ pub struct Foo;
+
+ impl Foo {
+ const ID: i32 = 1;
+ }
+ }
+}
+
+fn main() {
+ assert_eq!(1, bar1::Foo::ID);
+ //~^ERROR associated constant `ID` is private
+}
diff --git a/tests/ui/associated-consts/associated-const-private-impl.stderr b/tests/ui/associated-consts/associated-const-private-impl.stderr
new file mode 100644
index 000000000..a3fa3002e
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-private-impl.stderr
@@ -0,0 +1,12 @@
+error[E0624]: associated constant `ID` is private
+ --> $DIR/associated-const-private-impl.rs:13:30
+ |
+LL | const ID: i32 = 1;
+ | ------------- private associated constant defined here
+...
+LL | assert_eq!(1, bar1::Foo::ID);
+ | ^^ private associated constant
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0624`.
diff --git a/tests/ui/associated-consts/associated-const-public-impl.rs b/tests/ui/associated-consts/associated-const-public-impl.rs
new file mode 100644
index 000000000..787bee0ff
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-public-impl.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+mod bar1 {
+ pub use self::bar2::Foo;
+ mod bar2 {
+ pub struct Foo;
+
+ impl Foo {
+ pub const ID: i32 = 1;
+ }
+ }
+}
+
+fn main() {
+ assert_eq!(1, bar1::Foo::ID);
+}
diff --git a/tests/ui/associated-consts/associated-const-range-match-patterns.rs b/tests/ui/associated-consts/associated-const-range-match-patterns.rs
new file mode 100644
index 000000000..5276869a7
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-range-match-patterns.rs
@@ -0,0 +1,40 @@
+// run-pass
+#![allow(dead_code, unreachable_patterns)]
+#![allow(ellipsis_inclusive_range_patterns)]
+
+struct Foo;
+
+trait HasNum {
+ const NUM: isize;
+}
+impl HasNum for Foo {
+ const NUM: isize = 1;
+}
+
+fn main() {
+ assert!(match 2 {
+ Foo::NUM ... 3 => true,
+ _ => false,
+ });
+ assert!(match 0 {
+ -1 ... <Foo as HasNum>::NUM => true,
+ _ => false,
+ });
+ assert!(match 1 {
+ <Foo as HasNum>::NUM ... <Foo>::NUM => true,
+ _ => false,
+ });
+
+ assert!(match 2 {
+ Foo::NUM ..= 3 => true,
+ _ => false,
+ });
+ assert!(match 0 {
+ -1 ..= <Foo as HasNum>::NUM => true,
+ _ => false,
+ });
+ assert!(match 1 {
+ <Foo as HasNum>::NUM ..= <Foo>::NUM => true,
+ _ => false,
+ });
+}
diff --git a/tests/ui/associated-consts/associated-const-resolution-order.rs b/tests/ui/associated-consts/associated-const-resolution-order.rs
new file mode 100644
index 000000000..d2ccd30a6
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-resolution-order.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+struct MyType;
+
+impl MyType {
+ const IMPL_IS_INHERENT: bool = true;
+}
+
+trait MyTrait {
+ const IMPL_IS_INHERENT: bool;
+ const IMPL_IS_ON_TRAIT: bool;
+}
+
+impl MyTrait for MyType {
+ const IMPL_IS_INHERENT: bool = false;
+ const IMPL_IS_ON_TRAIT: bool = true;
+}
+
+fn main() {
+ // Check that the inherent impl is used before the trait, but that the trait
+ // can still be accessed.
+ assert!(<MyType>::IMPL_IS_INHERENT);
+ assert!(!<MyType as MyTrait>::IMPL_IS_INHERENT);
+ assert!(<MyType>::IMPL_IS_ON_TRAIT);
+}
diff --git a/tests/ui/associated-consts/associated-const-self-type.rs b/tests/ui/associated-consts/associated-const-self-type.rs
new file mode 100644
index 000000000..36e1e4ecc
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-self-type.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+trait MyInt {
+ const ONE: Self;
+}
+
+impl MyInt for i32 {
+ const ONE: i32 = 1;
+}
+
+fn main() {
+ assert_eq!(1, <i32>::ONE);
+}
diff --git a/tests/ui/associated-consts/associated-const-trait-bound.rs b/tests/ui/associated-consts/associated-const-trait-bound.rs
new file mode 100644
index 000000000..403cdbd7f
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-trait-bound.rs
@@ -0,0 +1,21 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+trait ConstDefault {
+ const DEFAULT: Self;
+}
+
+trait Foo: Sized {}
+
+trait FooExt: Foo {
+ type T: ConstDefault;
+}
+
+trait Bar<F: FooExt> {
+ const T: F::T;
+}
+
+impl<F: FooExt> Bar<F> for () {
+ const T: F::T = <F::T as ConstDefault>::DEFAULT;
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs b/tests/ui/associated-consts/associated-const-type-parameter-arms.rs
new file mode 100644
index 000000000..3f260d84e
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arms.rs
@@ -0,0 +1,29 @@
+pub enum EFoo { A, B, C, D }
+
+pub trait Foo {
+ const X: EFoo;
+}
+
+struct Abc;
+
+impl Foo for Abc {
+ const X: EFoo = EFoo::B;
+}
+
+struct Def;
+impl Foo for Def {
+ const X: EFoo = EFoo::D;
+}
+
+pub fn test<A: Foo, B: Foo>(arg: EFoo) {
+ match arg {
+ A::X => println!("A::X"),
+ //~^ error: associated consts cannot be referenced in patterns [E0158]
+ B::X => println!("B::X"),
+ //~^ error: associated consts cannot be referenced in patterns [E0158]
+ _ => (),
+ }
+}
+
+fn main() {
+}
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr
new file mode 100644
index 000000000..1ccf9febd
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr
@@ -0,0 +1,15 @@
+error[E0158]: associated consts cannot be referenced in patterns
+ --> $DIR/associated-const-type-parameter-arms.rs:20:9
+ |
+LL | A::X => println!("A::X"),
+ | ^^^^
+
+error[E0158]: associated consts cannot be referenced in patterns
+ --> $DIR/associated-const-type-parameter-arms.rs:22:9
+ |
+LL | B::X => println!("B::X"),
+ | ^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0158`.
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs
new file mode 100644
index 000000000..8fe79b97d
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs
@@ -0,0 +1,21 @@
+pub trait Foo {
+ const Y: usize;
+}
+
+struct Abc;
+impl Foo for Abc {
+ const Y: usize = 8;
+}
+
+struct Def;
+impl Foo for Def {
+ const Y: usize = 33;
+}
+
+pub fn test<A: Foo, B: Foo>() {
+ let _array = [4; <A as Foo>::Y];
+ //~^ ERROR constant expression depends on a generic parameter
+}
+
+fn main() {
+}
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr
new file mode 100644
index 000000000..0bc019b2d
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+ --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22
+ |
+LL | let _array = [4; <A as Foo>::Y];
+ | ^^^^^^^^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays.rs b/tests/ui/associated-consts/associated-const-type-parameter-arrays.rs
new file mode 100644
index 000000000..5152d7840
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays.rs
@@ -0,0 +1,20 @@
+pub trait Foo {
+ const Y: usize;
+}
+
+struct Abc;
+impl Foo for Abc {
+ const Y: usize = 8;
+}
+
+struct Def;
+impl Foo for Def {
+ const Y: usize = 33;
+}
+
+pub fn test<A: Foo, B: Foo>() {
+ let _array: [u32; <A as Foo>::Y];
+ //~^ ERROR generic parameters may not be used
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr
new file mode 100644
index 000000000..46a54a12d
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/associated-const-type-parameter-arrays.rs:16:24
+ |
+LL | let _array: [u32; <A as Foo>::Y];
+ | ^ cannot perform const operation using `A`
+ |
+ = note: type parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-consts/associated-const-type-parameters.rs b/tests/ui/associated-consts/associated-const-type-parameters.rs
new file mode 100644
index 000000000..e7ead1045
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameters.rs
@@ -0,0 +1,44 @@
+// run-pass
+
+trait Foo {
+ const X: i32;
+ fn get_x() -> i32 {
+ Self::X
+ }
+}
+
+struct Abc;
+impl Foo for Abc {
+ const X: i32 = 11;
+}
+
+struct Def;
+impl Foo for Def {
+ const X: i32 = 97;
+}
+
+struct Proxy<T>(#[allow(unused_tuple_struct_fields)] T);
+
+impl<T: Foo> Foo for Proxy<T> {
+ const X: i32 = T::X;
+}
+
+fn sub<A: Foo, B: Foo>() -> i32 {
+ A::X - B::X
+}
+
+trait Bar: Foo {
+ const Y: i32 = Self::X;
+}
+
+fn main() {
+ assert_eq!(11, Abc::X);
+ assert_eq!(97, Def::X);
+ assert_eq!(11, Abc::get_x());
+ assert_eq!(97, Def::get_x());
+ assert_eq!(-86, sub::<Abc, Def>());
+ assert_eq!(86, sub::<Def, Abc>());
+ assert_eq!(-86, sub::<Proxy<Abc>, Def>());
+ assert_eq!(-86, sub::<Abc, Proxy<Def>>());
+ assert_eq!(86, sub::<Proxy<Def>, Proxy<Abc>>());
+}
diff --git a/tests/ui/associated-consts/associated-const-ufcs-infer-trait.rs b/tests/ui/associated-consts/associated-const-ufcs-infer-trait.rs
new file mode 100644
index 000000000..ca44c9f45
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-ufcs-infer-trait.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+trait Foo {
+ const ID: i32;
+}
+
+impl Foo for i32 {
+ const ID: i32 = 1;
+}
+
+fn main() {
+ assert_eq!(1, <i32>::ID);
+}
diff --git a/tests/ui/associated-consts/associated-const-use-default.rs b/tests/ui/associated-consts/associated-const-use-default.rs
new file mode 100644
index 000000000..adf36b1ff
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-use-default.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+trait Foo {
+ const ID: i32 = 1;
+}
+
+impl Foo for i32 {}
+
+fn main() {
+ assert_eq!(1, <i32 as Foo>::ID);
+}
diff --git a/tests/ui/associated-consts/associated-const-use-impl-of-same-trait.rs b/tests/ui/associated-consts/associated-const-use-impl-of-same-trait.rs
new file mode 100644
index 000000000..8f01bae4f
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-use-impl-of-same-trait.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+// The main purpose of this test is to ensure that different impls of the same
+// trait can refer to each other without setting off the static recursion check
+// (as long as there's no actual recursion).
+
+trait Foo {
+ const BAR: u32;
+}
+
+struct IsFoo1;
+
+impl Foo for IsFoo1 {
+ const BAR: u32 = 1;
+}
+
+struct IsFoo2;
+
+impl Foo for IsFoo2 {
+ const BAR: u32 = <IsFoo1 as Foo>::BAR;
+}
+
+fn main() {
+ assert_eq!(<IsFoo1>::BAR, <IsFoo2 as Foo>::BAR);
+}
diff --git a/tests/ui/associated-consts/associated-const.rs b/tests/ui/associated-consts/associated-const.rs
new file mode 100644
index 000000000..e4b1c29f3
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+trait Foo {
+ const ID: i32;
+}
+
+impl Foo for i32 {
+ const ID: i32 = 1;
+}
+
+fn main() {
+ assert_eq!(1, <i32 as Foo>::ID);
+}
diff --git a/tests/ui/associated-consts/auxiliary/associated-const-cc-lib.rs b/tests/ui/associated-consts/auxiliary/associated-const-cc-lib.rs
new file mode 100644
index 000000000..4fcefe32c
--- /dev/null
+++ b/tests/ui/associated-consts/auxiliary/associated-const-cc-lib.rs
@@ -0,0 +1,34 @@
+#![crate_type="lib"]
+
+// These items are for testing that associated consts work cross-crate.
+pub trait Foo {
+ const BAR: usize;
+}
+
+pub struct FooNoDefault;
+
+impl Foo for FooNoDefault {
+ const BAR: usize = 0;
+}
+
+// These test that defaults and default resolution work cross-crate.
+pub trait FooDefault {
+ const BAR: usize = 1;
+}
+
+pub struct FooOverwriteDefault;
+
+impl FooDefault for FooOverwriteDefault {
+ const BAR: usize = 2;
+}
+
+pub struct FooUseDefault;
+
+impl FooDefault for FooUseDefault {}
+
+// Test inherent impls.
+pub struct InherentBar;
+
+impl InherentBar {
+ pub const BAR: usize = 3;
+}
diff --git a/tests/ui/associated-consts/auxiliary/empty-struct.rs b/tests/ui/associated-consts/auxiliary/empty-struct.rs
new file mode 100644
index 000000000..93275e714
--- /dev/null
+++ b/tests/ui/associated-consts/auxiliary/empty-struct.rs
@@ -0,0 +1,9 @@
+pub struct XEmpty1 {}
+pub struct XEmpty2;
+pub struct XEmpty7();
+
+pub enum XE {
+ XEmpty3 {},
+ XEmpty4,
+ XEmpty6(),
+}
diff --git a/tests/ui/associated-consts/defaults-cyclic-fail.rs b/tests/ui/associated-consts/defaults-cyclic-fail.rs
new file mode 100644
index 000000000..a1c6840a0
--- /dev/null
+++ b/tests/ui/associated-consts/defaults-cyclic-fail.rs
@@ -0,0 +1,17 @@
+// build-fail
+
+// Cyclic assoc. const defaults don't error unless *used*
+trait Tr {
+ const A: u8 = Self::B;
+ //~^ cycle detected when const-evaluating + checking `Tr::A`
+
+ const B: u8 = Self::A;
+}
+
+// This impl is *allowed* unless its assoc. consts are used
+impl Tr for () {}
+
+fn main() {
+ // This triggers the cycle error
+ assert_eq!(<() as Tr>::A, 0);
+}
diff --git a/tests/ui/associated-consts/defaults-cyclic-fail.stderr b/tests/ui/associated-consts/defaults-cyclic-fail.stderr
new file mode 100644
index 000000000..a1483911b
--- /dev/null
+++ b/tests/ui/associated-consts/defaults-cyclic-fail.stderr
@@ -0,0 +1,21 @@
+error[E0391]: cycle detected when const-evaluating + checking `Tr::A`
+ --> $DIR/defaults-cyclic-fail.rs:5:19
+ |
+LL | const A: u8 = Self::B;
+ | ^^^^^^^
+ |
+note: ...which requires const-evaluating + checking `Tr::B`...
+ --> $DIR/defaults-cyclic-fail.rs:8:19
+ |
+LL | const B: u8 = Self::A;
+ | ^^^^^^^
+ = note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle
+note: cycle used when const-evaluating + checking `main::promoted[1]`
+ --> $DIR/defaults-cyclic-fail.rs:16:16
+ |
+LL | assert_eq!(<() as Tr>::A, 0);
+ | ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-consts/defaults-cyclic-pass.rs b/tests/ui/associated-consts/defaults-cyclic-pass.rs
new file mode 100644
index 000000000..82105f25f
--- /dev/null
+++ b/tests/ui/associated-consts/defaults-cyclic-pass.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+// Cyclic assoc. const defaults don't error unless *used*
+trait Tr {
+ const A: u8 = Self::B;
+ const B: u8 = Self::A;
+}
+
+// This impl is *allowed* unless its assoc. consts are used, matching the
+// behavior without defaults.
+impl Tr for () {}
+
+// Overriding either constant breaks the cycle
+impl Tr for u8 {
+ const A: u8 = 42;
+}
+
+impl Tr for u16 {
+ const B: u8 = 0;
+}
+
+impl Tr for u32 {
+ const A: u8 = 100;
+ const B: u8 = 123;
+}
+
+fn main() {
+ assert_eq!(<u8 as Tr>::A, 42);
+ assert_eq!(<u8 as Tr>::B, 42);
+
+ assert_eq!(<u16 as Tr>::A, 0);
+ assert_eq!(<u16 as Tr>::B, 0);
+
+ assert_eq!(<u32 as Tr>::A, 100);
+ assert_eq!(<u32 as Tr>::B, 123);
+}
diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.rs b/tests/ui/associated-consts/defaults-not-assumed-fail.rs
new file mode 100644
index 000000000..495dfb338
--- /dev/null
+++ b/tests/ui/associated-consts/defaults-not-assumed-fail.rs
@@ -0,0 +1,44 @@
+// build-fail
+
+trait Tr {
+ const A: u8 = 255;
+
+ // This should not be a constant evaluation error (overflow). The value of
+ // `Self::A` must not be assumed to hold inside the trait.
+ const B: u8 = Self::A + 1;
+ //~^ ERROR evaluation of `<() as Tr>::B` failed
+}
+
+// An impl that doesn't override any constant will NOT cause a const eval error
+// just because it's defined, but only if the bad constant is used anywhere.
+// This matches the behavior without defaults.
+impl Tr for () {}
+
+// An impl that overrides either constant with a suitable value will be fine.
+impl Tr for u8 {
+ const A: u8 = 254;
+}
+
+impl Tr for u16 {
+ const B: u8 = 0;
+}
+
+impl Tr for u32 {
+ const A: u8 = 254;
+ const B: u8 = 0;
+}
+
+fn main() {
+ assert_eq!(<() as Tr>::A, 255);
+ assert_eq!(<() as Tr>::B, 0); // causes the error above
+ //~^ constant
+
+ assert_eq!(<u8 as Tr>::A, 254);
+ assert_eq!(<u8 as Tr>::B, 255);
+
+ assert_eq!(<u16 as Tr>::A, 255);
+ assert_eq!(<u16 as Tr>::B, 0);
+
+ assert_eq!(<u32 as Tr>::A, 254);
+ assert_eq!(<u32 as Tr>::B, 0);
+}
diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr
new file mode 100644
index 000000000..fb7159e40
--- /dev/null
+++ b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr
@@ -0,0 +1,39 @@
+error[E0080]: evaluation of `<() as Tr>::B` failed
+ --> $DIR/defaults-not-assumed-fail.rs:8:19
+ |
+LL | const B: u8 = Self::A + 1;
+ | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
+
+note: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:33:16
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:33:5
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:33:5
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:33:5
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/associated-consts/defaults-not-assumed-pass.rs b/tests/ui/associated-consts/defaults-not-assumed-pass.rs
new file mode 100644
index 000000000..c08e05c8a
--- /dev/null
+++ b/tests/ui/associated-consts/defaults-not-assumed-pass.rs
@@ -0,0 +1,42 @@
+// run-pass
+
+trait Tr {
+ const A: u8 = 255;
+
+ // This should not be a constant evaluation error (overflow). The value of
+ // `Self::A` must not be assumed to hold inside the trait.
+ const B: u8 = Self::A + 1;
+}
+
+// An impl that doesn't override any constant will NOT cause a const eval error
+// just because it's defined, but only if the bad constant is used anywhere.
+// This matches the behavior without defaults.
+impl Tr for () {}
+
+// An impl that overrides either constant with a suitable value will be fine.
+impl Tr for u8 {
+ const A: u8 = 254;
+}
+
+impl Tr for u16 {
+ const B: u8 = 0;
+}
+
+impl Tr for u32 {
+ const A: u8 = 254;
+ const B: u8 = 0;
+}
+
+fn main() {
+ assert_eq!(<() as Tr>::A, 255);
+ //assert_eq!(<() as Tr>::B, 0); // using this is an error
+
+ assert_eq!(<u8 as Tr>::A, 254);
+ assert_eq!(<u8 as Tr>::B, 255);
+
+ assert_eq!(<u16 as Tr>::A, 255);
+ assert_eq!(<u16 as Tr>::B, 0);
+
+ assert_eq!(<u32 as Tr>::A, 254);
+ assert_eq!(<u32 as Tr>::B, 0);
+}
diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/associated-consts/issue-102335-const.rs
new file mode 100644
index 000000000..f60cb92da
--- /dev/null
+++ b/tests/ui/associated-consts/issue-102335-const.rs
@@ -0,0 +1,12 @@
+#![feature(associated_const_equality)]
+
+trait T {
+ type A: S<C<X = 0i32> = 34>;
+ //~^ ERROR associated type bindings are not allowed here
+}
+
+trait S {
+ const C: i32;
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/associated-consts/issue-102335-const.stderr
new file mode 100644
index 000000000..531d15c59
--- /dev/null
+++ b/tests/ui/associated-consts/issue-102335-const.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-102335-const.rs:4:17
+ |
+LL | type A: S<C<X = 0i32> = 34>;
+ | ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs
new file mode 100644
index 000000000..86e45f10b
--- /dev/null
+++ b/tests/ui/associated-consts/issue-105330.rs
@@ -0,0 +1,21 @@
+pub trait TraitWAssocConst {
+ const A: usize;
+}
+pub struct Demo {}
+
+impl TraitWAssocConst for impl Demo { //~ ERROR E0404
+ //~^ ERROR E0562
+ pubconst A: str = 32; //~ ERROR expected one of
+}
+
+fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
+ foo::<Demo>()(); //~ ERROR E0271
+ //~^ ERROR E0618
+ //~| ERROR E0277
+}
+
+fn main<A: TraitWAssocConst<A=32>>() { //~ ERROR E0131
+ //~^ ERROR E0658
+ foo::<Demo>(); //~ ERROR E0277
+ //~^ ERROR E0271
+}
diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr
new file mode 100644
index 000000000..30c380152
--- /dev/null
+++ b/tests/ui/associated-consts/issue-105330.stderr
@@ -0,0 +1,113 @@
+error: expected one of `!` or `::`, found `A`
+ --> $DIR/issue-105330.rs:8:14
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | - while parsing this item list starting here
+LL |
+LL | pubconst A: str = 32;
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error[E0404]: expected trait, found struct `Demo`
+ --> $DIR/issue-105330.rs:6:32
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | ^^^^ not a trait
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-105330.rs:17:29
+ |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+ | ^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
+ --> $DIR/issue-105330.rs:6:27
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | ^^^^^^^^^
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+ --> $DIR/issue-105330.rs:12:11
+ |
+LL | foo::<Demo>()();
+ | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:11
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+ --> $DIR/issue-105330.rs:12:11
+ |
+LL | foo::<Demo>()();
+ | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
+ |
+ = note: expected constant `32`
+ found constant `<Demo as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^ required by this bound in `foo`
+
+error[E0618]: expected function, found `()`
+ --> $DIR/issue-105330.rs:12:5
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ----------------------------------- `foo::<Demo>` defined here returns `()`
+LL | foo::<Demo>()();
+ | ^^^^^^^^^^^^^--
+ | |
+ | call expression requires function
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+ --> $DIR/issue-105330.rs:19:11
+ |
+LL | foo::<Demo>();
+ | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:11
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+ --> $DIR/issue-105330.rs:19:11
+ |
+LL | foo::<Demo>();
+ | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
+ |
+ = note: expected constant `32`
+ found constant `<Demo as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^ required by this bound in `foo`
+
+error[E0131]: `main` function is not allowed to have generic parameters
+ --> $DIR/issue-105330.rs:17:8
+ |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658.
+For more information about an error, try `rustc --explain E0131`.
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs
new file mode 100644
index 000000000..0315938a7
--- /dev/null
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs
@@ -0,0 +1,15 @@
+// Check for recursion involving references to impl-associated const.
+
+trait Foo {
+ const BAR: u32;
+}
+
+const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
+
+struct GlobalImplRef;
+
+impl GlobalImplRef {
+ const BAR: u32 = IMPL_REF_BAR; //~ ERROR E0391
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
new file mode 100644
index 000000000..be5781761
--- /dev/null
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
@@ -0,0 +1,32 @@
+error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`
+ --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:22
+ |
+LL | const BAR: u32 = IMPL_REF_BAR;
+ | ^^^^^^^^^^^^
+ |
+note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
+ |
+LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:27
+ |
+LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
+ | ^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
+ |
+LL | const BAR: u32 = IMPL_REF_BAR;
+ | ^^^^^^^^^^^^^^
+note: ...which requires caching mir of `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR` for CTFE...
+ --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
+ |
+LL | const BAR: u32 = IMPL_REF_BAR;
+ | ^^^^^^^^^^^^^^
+ = note: ...which again requires elaborating drops for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`, completing the cycle
+ = note: cycle used when running analysis passes on this crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs
new file mode 100644
index 000000000..4e89f6862
--- /dev/null
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs
@@ -0,0 +1,17 @@
+// Check for recursion involving references to trait-associated const default.
+
+trait Foo {
+ const BAR: u32;
+}
+
+trait FooDefault {
+ const BAR: u32 = DEFAULT_REF_BAR; //~ ERROR E0391
+}
+
+const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
+
+struct GlobalDefaultRef;
+
+impl FooDefault for GlobalDefaultRef {}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
new file mode 100644
index 000000000..8347b260b
--- /dev/null
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
@@ -0,0 +1,32 @@
+error[E0391]: cycle detected when elaborating drops for `FooDefault::BAR`
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:22
+ |
+LL | const BAR: u32 = DEFAULT_REF_BAR;
+ | ^^^^^^^^^^^^^^^
+ |
+note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
+ |
+LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:30
+ |
+LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `FooDefault::BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
+ |
+LL | const BAR: u32 = DEFAULT_REF_BAR;
+ | ^^^^^^^^^^^^^^
+note: ...which requires caching mir of `FooDefault::BAR` for CTFE...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
+ |
+LL | const BAR: u32 = DEFAULT_REF_BAR;
+ | ^^^^^^^^^^^^^^
+ = note: ...which again requires elaborating drops for `FooDefault::BAR`, completing the cycle
+ = note: cycle used when running analysis passes on this crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs
new file mode 100644
index 000000000..68b653ff3
--- /dev/null
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs
@@ -0,0 +1,15 @@
+// Check for recursion involving references to trait-associated const.
+
+trait Foo {
+ const BAR: u32;
+}
+
+const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
+
+struct GlobalTraitRef;
+
+impl Foo for GlobalTraitRef {
+ const BAR: u32 = TRAIT_REF_BAR; //~ ERROR E0391
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
new file mode 100644
index 000000000..3955a3120
--- /dev/null
+++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
@@ -0,0 +1,32 @@
+error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:22
+ |
+LL | const BAR: u32 = TRAIT_REF_BAR;
+ | ^^^^^^^^^^^^^
+ |
+note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
+ |
+LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:28
+ |
+LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
+ |
+LL | const BAR: u32 = TRAIT_REF_BAR;
+ | ^^^^^^^^^^^^^^
+note: ...which requires caching mir of `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR` for CTFE...
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
+ |
+LL | const BAR: u32 = TRAIT_REF_BAR;
+ | ^^^^^^^^^^^^^^
+ = note: ...which again requires elaborating drops for `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`, completing the cycle
+ = note: cycle used when running analysis passes on this crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-consts/issue-47814.rs b/tests/ui/associated-consts/issue-47814.rs
new file mode 100644
index 000000000..a28b1c001
--- /dev/null
+++ b/tests/ui/associated-consts/issue-47814.rs
@@ -0,0 +1,14 @@
+struct ArpIPv4<'a> {
+ s: &'a u8
+}
+
+impl<'a> ArpIPv4<'a> {
+ const LENGTH: usize = 20;
+
+ pub fn to_buffer() -> [u8; Self::LENGTH] {
+ //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants
+ unimplemented!()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-47814.stderr b/tests/ui/associated-consts/issue-47814.stderr
new file mode 100644
index 000000000..2e4ddb811
--- /dev/null
+++ b/tests/ui/associated-consts/issue-47814.stderr
@@ -0,0 +1,14 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/issue-47814.rs:8:32
+ |
+LL | pub fn to_buffer() -> [u8; Self::LENGTH] {
+ | ^^^^
+ |
+note: not a concrete type
+ --> $DIR/issue-47814.rs:5:10
+ |
+LL | impl<'a> ArpIPv4<'a> {
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-consts/issue-58022.rs b/tests/ui/associated-consts/issue-58022.rs
new file mode 100644
index 000000000..2a8a1eaa6
--- /dev/null
+++ b/tests/ui/associated-consts/issue-58022.rs
@@ -0,0 +1,19 @@
+pub trait Foo: Sized {
+ const SIZE: usize;
+
+ fn new(slice: &[u8; Foo::SIZE]) -> Self;
+ //~^ ERROR: E0790
+}
+
+pub struct Bar<T: ?Sized>(T);
+
+impl Bar<[u8]> {
+ const SIZE: usize = 32;
+
+ fn new(slice: &[u8; Self::SIZE]) -> Self {
+ Foo(Box::new(*slice))
+ //~^ ERROR: expected function, tuple struct or tuple variant, found trait `Foo`
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-58022.stderr b/tests/ui/associated-consts/issue-58022.stderr
new file mode 100644
index 000000000..56d85c066
--- /dev/null
+++ b/tests/ui/associated-consts/issue-58022.stderr
@@ -0,0 +1,19 @@
+error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
+ --> $DIR/issue-58022.rs:4:25
+ |
+LL | const SIZE: usize;
+ | ------------------ `Foo::SIZE` defined here
+LL |
+LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
+ | ^^^^^^^^^ cannot refer to the associated constant of trait
+
+error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
+ --> $DIR/issue-58022.rs:14:9
+ |
+LL | Foo(Box::new(*slice))
+ | ^^^ not a function, tuple struct or tuple variant
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0423, E0790.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/tests/ui/associated-consts/issue-63496.rs b/tests/ui/associated-consts/issue-63496.rs
new file mode 100644
index 000000000..67ef4e74c
--- /dev/null
+++ b/tests/ui/associated-consts/issue-63496.rs
@@ -0,0 +1,9 @@
+trait A {
+ const C: usize;
+
+ fn f() -> ([u8; A::C], [u8; A::C]);
+ //~^ ERROR: E0790
+ //~| ERROR: E0790
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-63496.stderr b/tests/ui/associated-consts/issue-63496.stderr
new file mode 100644
index 000000000..f2a4e01ad
--- /dev/null
+++ b/tests/ui/associated-consts/issue-63496.stderr
@@ -0,0 +1,21 @@
+error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
+ --> $DIR/issue-63496.rs:4:21
+ |
+LL | const C: usize;
+ | --------------- `A::C` defined here
+LL |
+LL | fn f() -> ([u8; A::C], [u8; A::C]);
+ | ^^^^ cannot refer to the associated constant of trait
+
+error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
+ --> $DIR/issue-63496.rs:4:33
+ |
+LL | const C: usize;
+ | --------------- `A::C` defined here
+LL |
+LL | fn f() -> ([u8; A::C], [u8; A::C]);
+ | ^^^^ cannot refer to the associated constant of trait
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0790`.
diff --git a/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.noopt.stderr b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.noopt.stderr
new file mode 100644
index 000000000..0c3581900
--- /dev/null
+++ b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.noopt.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:27:22
+ |
+LL | const NEG: i32 = -i32::MIN + T::NEG;
+ | ^^^^^^^^^ attempt to negate `i32::MIN`, which would overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:35
+ |
+LL | const NEG_REV: i32 = T::NEG + (-i32::MIN);
+ | ^^^^^^^^^^^ attempt to negate `i32::MIN`, which would overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:32:22
+ |
+LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:36
+ |
+LL | const ADD_REV: i32 = T::ADD + (i32::MAX+1);
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:37:22
+ |
+LL | const DIV: i32 = (1/0) + T::DIV;
+ | ^^^^^ attempt to divide `1_i32` by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:35
+ |
+LL | const DIV_REV: i32 = T::DIV + (1/0);
+ | ^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:42:22
+ |
+LL | const OOB: i32 = [1][1] + T::OOB;
+ | ^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:35
+ |
+LL | const OOB_REV: i32 = T::OOB + [1][1];
+ | ^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt.stderr b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt.stderr
new file mode 100644
index 000000000..0c3581900
--- /dev/null
+++ b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:27:22
+ |
+LL | const NEG: i32 = -i32::MIN + T::NEG;
+ | ^^^^^^^^^ attempt to negate `i32::MIN`, which would overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:35
+ |
+LL | const NEG_REV: i32 = T::NEG + (-i32::MIN);
+ | ^^^^^^^^^^^ attempt to negate `i32::MIN`, which would overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:32:22
+ |
+LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:36
+ |
+LL | const ADD_REV: i32 = T::ADD + (i32::MAX+1);
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:37:22
+ |
+LL | const DIV: i32 = (1/0) + T::DIV;
+ | ^^^^^ attempt to divide `1_i32` by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:35
+ |
+LL | const DIV_REV: i32 = T::DIV + (1/0);
+ | ^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:42:22
+ |
+LL | const OOB: i32 = [1][1] + T::OOB;
+ | ^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:35
+ |
+LL | const OOB_REV: i32 = T::OOB + [1][1];
+ | ^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr
new file mode 100644
index 000000000..0c3581900
--- /dev/null
+++ b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:27:22
+ |
+LL | const NEG: i32 = -i32::MIN + T::NEG;
+ | ^^^^^^^^^ attempt to negate `i32::MIN`, which would overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:35
+ |
+LL | const NEG_REV: i32 = T::NEG + (-i32::MIN);
+ | ^^^^^^^^^^^ attempt to negate `i32::MIN`, which would overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:32:22
+ |
+LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:36
+ |
+LL | const ADD_REV: i32 = T::ADD + (i32::MAX+1);
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:37:22
+ |
+LL | const DIV: i32 = (1/0) + T::DIV;
+ | ^^^^^ attempt to divide `1_i32` by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:35
+ |
+LL | const DIV_REV: i32 = T::DIV + (1/0);
+ | ^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:42:22
+ |
+LL | const OOB: i32 = [1][1] + T::OOB;
+ | ^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:35
+ |
+LL | const OOB_REV: i32 = T::OOB + [1][1];
+ | ^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs
new file mode 100644
index 000000000..d4af6e864
--- /dev/null
+++ b/tests/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs
@@ -0,0 +1,46 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
+#![crate_type="lib"]
+
+pub trait Foo {
+ const NEG: i32;
+ const NEG_REV: i32;
+
+ const ADD: i32;
+ const ADD_REV: i32;
+
+ const DIV: i32;
+ const DIV_REV: i32;
+
+ const OOB: i32;
+ const OOB_REV: i32;
+}
+
+// These constants cannot be evaluated already (they depend on `T::N`), so they can just be linted
+// like normal run-time code. But codegen works a bit different in const context, so this test
+// makes sure that we still catch overflow. Also make sure we emit the same lints if we reverse the
+// operands (so that the generic operand comes first).
+impl<T: Foo> Foo for Vec<T> {
+ const NEG: i32 = -i32::MIN + T::NEG;
+ //~^ ERROR arithmetic operation will overflow
+ const NEG_REV: i32 = T::NEG + (-i32::MIN);
+ //~^ ERROR arithmetic operation will overflow
+
+ const ADD: i32 = (i32::MAX+1) + T::ADD;
+ //~^ ERROR arithmetic operation will overflow
+ const ADD_REV: i32 = T::ADD + (i32::MAX+1);
+ //~^ ERROR arithmetic operation will overflow
+
+ const DIV: i32 = (1/0) + T::DIV;
+ //~^ ERROR operation will panic
+ const DIV_REV: i32 = T::DIV + (1/0);
+ //~^ ERROR operation will panic
+
+ const OOB: i32 = [1][1] + T::OOB;
+ //~^ ERROR operation will panic
+ const OOB_REV: i32 = T::OOB + [1][1];
+ //~^ ERROR operation will panic
+}
diff --git a/tests/ui/associated-consts/issue-88599-ref-self.rs b/tests/ui/associated-consts/issue-88599-ref-self.rs
new file mode 100644
index 000000000..f1144db44
--- /dev/null
+++ b/tests/ui/associated-consts/issue-88599-ref-self.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait First {
+ const CONST: usize;
+}
+pub trait Second {}
+
+impl<'a> First for dyn Second
+where
+ &'a Self: First,
+{
+ const CONST: usize = <&Self>::CONST;
+}
+
+trait Third: First
+where
+ [u8; Self::CONST]:
+{
+ const VAL: [u8; Self::CONST] = [0; Self::CONST];
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-93775.rs b/tests/ui/associated-consts/issue-93775.rs
new file mode 100644
index 000000000..7a007b732
--- /dev/null
+++ b/tests/ui/associated-consts/issue-93775.rs
@@ -0,0 +1,29 @@
+// build-pass
+// ignore-tidy-linelength
+
+// Regression for #93775, needs build-pass to test it.
+
+#![recursion_limit = "1000"]
+
+use std::marker::PhantomData;
+
+struct Z;
+struct S<T>(PhantomData<T>);
+
+type Nested = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<Z>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
+
+trait AsNum {
+ const NUM: u32;
+}
+
+impl AsNum for Z {
+ const NUM: u32 = 0;
+}
+
+impl<T: AsNum> AsNum for S<T> {
+ const NUM: u32 = T::NUM + 1;
+}
+
+fn main() {
+ let _ = Nested::NUM;
+}
diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs
new file mode 100644
index 000000000..b2a437fcb
--- /dev/null
+++ b/tests/ui/associated-consts/issue-93835.rs
@@ -0,0 +1,12 @@
+#![feature(type_ascription)]
+
+fn e() {
+ type_ascribe!(p, a<p:p<e=6>>);
+ //~^ ERROR cannot find type `a` in this scope
+ //~| ERROR cannot find value
+ //~| ERROR associated const equality
+ //~| ERROR cannot find trait `p` in this scope
+ //~| ERROR associated type bounds
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr
new file mode 100644
index 000000000..be0573a13
--- /dev/null
+++ b/tests/ui/associated-consts/issue-93835.stderr
@@ -0,0 +1,40 @@
+error[E0425]: cannot find value `p` in this scope
+ --> $DIR/issue-93835.rs:4:19
+ |
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^ not found in this scope
+
+error[E0412]: cannot find type `a` in this scope
+ --> $DIR/issue-93835.rs:4:22
+ |
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^ not found in this scope
+
+error[E0405]: cannot find trait `p` in this scope
+ --> $DIR/issue-93835.rs:4:26
+ |
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^ not found in this scope
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-93835.rs:4:28
+ |
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0658]: associated type bounds are unstable
+ --> $DIR/issue-93835.rs:4:24
+ |
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^^^^^^^^
+ |
+ = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
+ = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0405, E0412, E0425, E0658.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/tests/ui/associated-consts/mismatched_impl_ty_1.rs b/tests/ui/associated-consts/mismatched_impl_ty_1.rs
new file mode 100644
index 000000000..4dc6c2e47
--- /dev/null
+++ b/tests/ui/associated-consts/mismatched_impl_ty_1.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+ type ArrayType;
+ const SIZE: usize;
+ const ARRAY: Self::ArrayType;
+}
+impl MyTrait for () {
+ type ArrayType = [u8; Self::SIZE];
+ const SIZE: usize = 4;
+ const ARRAY: [u8; Self::SIZE] = [1, 2, 3, 4];
+}
+
+fn main() {
+ let _ = <() as MyTrait>::ARRAY;
+}
diff --git a/tests/ui/associated-consts/mismatched_impl_ty_2.rs b/tests/ui/associated-consts/mismatched_impl_ty_2.rs
new file mode 100644
index 000000000..539becfdc
--- /dev/null
+++ b/tests/ui/associated-consts/mismatched_impl_ty_2.rs
@@ -0,0 +1,11 @@
+// run-pass
+trait Trait {
+ const ASSOC: fn(&'static u32);
+}
+impl Trait for () {
+ const ASSOC: for<'a> fn(&'a u32) = |_| ();
+}
+
+fn main() {
+ let _ = <() as Trait>::ASSOC;
+}
diff --git a/tests/ui/associated-consts/mismatched_impl_ty_3.rs b/tests/ui/associated-consts/mismatched_impl_ty_3.rs
new file mode 100644
index 000000000..17bcc8fe5
--- /dev/null
+++ b/tests/ui/associated-consts/mismatched_impl_ty_3.rs
@@ -0,0 +1,11 @@
+// run-pass
+trait Trait {
+ const ASSOC: for<'a, 'b> fn(&'a u32, &'b u32);
+}
+impl Trait for () {
+ const ASSOC: for<'a> fn(&'a u32, &'a u32) = |_, _| ();
+}
+
+fn main() {
+ let _ = <() as Trait>::ASSOC;
+}
diff --git a/tests/ui/associated-consts/shadowed-const.rs b/tests/ui/associated-consts/shadowed-const.rs
new file mode 100644
index 000000000..cfdb391d3
--- /dev/null
+++ b/tests/ui/associated-consts/shadowed-const.rs
@@ -0,0 +1,23 @@
+// Checking that none of these ICE, which was introduced in
+// https://github.com/rust-lang/rust/issues/93553
+trait Foo {
+ type Bar;
+}
+
+trait Baz: Foo {
+ const Bar: Self::Bar;
+}
+
+trait Baz2: Foo {
+ const Bar: u32;
+
+ fn foo() -> Self::Bar;
+}
+
+trait Baz3 {
+ const BAR: usize;
+ const QUX: Self::BAR;
+ //~^ ERROR found associated const
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/shadowed-const.stderr b/tests/ui/associated-consts/shadowed-const.stderr
new file mode 100644
index 000000000..fe21d2aec
--- /dev/null
+++ b/tests/ui/associated-consts/shadowed-const.stderr
@@ -0,0 +1,8 @@
+error: found associated const `BAR` when type was expected
+ --> $DIR/shadowed-const.rs:19:14
+ |
+LL | const QUX: Self::BAR;
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+