about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/ui/associated-const/defaults-cyclic-fail.rs17
-rw-r--r--src/test/ui/associated-const/defaults-cyclic-fail.stderr21
-rw-r--r--src/test/ui/associated-const/defaults-cyclic-pass.rs35
-rw-r--r--src/test/ui/associated-const/defaults-not-assumed-fail.rs44
-rw-r--r--src/test/ui/associated-const/defaults-not-assumed-fail.stderr23
-rw-r--r--src/test/ui/associated-const/defaults-not-assumed-pass.rs42
6 files changed, 182 insertions, 0 deletions
diff --git a/src/test/ui/associated-const/defaults-cyclic-fail.rs b/src/test/ui/associated-const/defaults-cyclic-fail.rs
new file mode 100644
index 00000000000..0f54d67574d
--- /dev/null
+++ b/src/test/ui/associated-const/defaults-cyclic-fail.rs
@@ -0,0 +1,17 @@
+// compile-fail
+
+// Cyclic assoc. const defaults don't error unless *used*
+trait Tr {
+    const A: u8 = Self::B;
+    //~^ ERROR cycle detected when const-evaluating `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/src/test/ui/associated-const/defaults-cyclic-fail.stderr b/src/test/ui/associated-const/defaults-cyclic-fail.stderr
new file mode 100644
index 00000000000..4e595199091
--- /dev/null
+++ b/src/test/ui/associated-const/defaults-cyclic-fail.stderr
@@ -0,0 +1,21 @@
+error[E0391]: cycle detected when const-evaluating `Tr::A`
+  --> $DIR/defaults-cyclic-fail.rs:5:19
+   |
+LL |     const A: u8 = Self::B;
+   |                   ^^^^^^^
+   |
+note: ...which requires const-evaluating `Tr::B`...
+  --> $DIR/defaults-cyclic-fail.rs:8:19
+   |
+LL |     const B: u8 = Self::A;
+   |                   ^^^^^^^
+   = note: ...which again requires const-evaluating `Tr::A`, completing the cycle
+note: cycle used when processing `main`
+  --> $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/src/test/ui/associated-const/defaults-cyclic-pass.rs b/src/test/ui/associated-const/defaults-cyclic-pass.rs
new file mode 100644
index 00000000000..1de733cfc37
--- /dev/null
+++ b/src/test/ui/associated-const/defaults-cyclic-pass.rs
@@ -0,0 +1,35 @@
+// 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
+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/src/test/ui/associated-const/defaults-not-assumed-fail.rs b/src/test/ui/associated-const/defaults-not-assumed-fail.rs
new file mode 100644
index 00000000000..27435ef34a0
--- /dev/null
+++ b/src/test/ui/associated-const/defaults-not-assumed-fail.rs
@@ -0,0 +1,44 @@
+// compile-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 any use of this value will cause an error
+}
+
+// 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
+    //~^ ERROR evaluation of constant expression failed
+
+    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/src/test/ui/associated-const/defaults-not-assumed-fail.stderr b/src/test/ui/associated-const/defaults-not-assumed-fail.stderr
new file mode 100644
index 00000000000..aac1765c4b2
--- /dev/null
+++ b/src/test/ui/associated-const/defaults-not-assumed-fail.stderr
@@ -0,0 +1,23 @@
+error: any use of this value will cause an error
+  --> $DIR/defaults-not-assumed-fail.rs:8:19
+   |
+LL |     const B: u8 = Self::A + 1;
+   |     --------------^^^^^^^^^^^-
+   |                   |
+   |                   attempt to add with overflow
+   |
+   = note: #[deny(const_err)] on by default
+
+error[E0080]: evaluation of constant expression failed
+  --> $DIR/defaults-not-assumed-fail.rs:33:5
+   |
+LL |     assert_eq!(<() as Tr>::B, 0);    // causes the error above
+   |     ^^^^^^^^^^^-------------^^^^^
+   |                |
+   |                referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/associated-const/defaults-not-assumed-pass.rs b/src/test/ui/associated-const/defaults-not-assumed-pass.rs
new file mode 100644
index 00000000000..c08e05c8a30
--- /dev/null
+++ b/src/test/ui/associated-const/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);
+}