From de447eb9f20cbc2a330d6093a4ac8b5eb730b193 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 14 Jun 2019 00:03:32 +0200 Subject: [PATCH] Add tests for assoc. const defaults --- .../associated-const/defaults-cyclic-fail.rs | 17 +++++++ .../defaults-cyclic-fail.stderr | 21 +++++++++ .../associated-const/defaults-cyclic-pass.rs | 35 +++++++++++++++ .../defaults-not-assumed-fail.rs | 44 +++++++++++++++++++ .../defaults-not-assumed-fail.stderr | 23 ++++++++++ .../defaults-not-assumed-pass.rs | 42 ++++++++++++++++++ 6 files changed, 182 insertions(+) create mode 100644 src/test/ui/associated-const/defaults-cyclic-fail.rs create mode 100644 src/test/ui/associated-const/defaults-cyclic-fail.stderr create mode 100644 src/test/ui/associated-const/defaults-cyclic-pass.rs create mode 100644 src/test/ui/associated-const/defaults-not-assumed-fail.rs create mode 100644 src/test/ui/associated-const/defaults-not-assumed-fail.stderr create mode 100644 src/test/ui/associated-const/defaults-not-assumed-pass.rs 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 000000000000..0f54d67574d3 --- /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 000000000000..4e5951990913 --- /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 000000000000..1de733cfc37a --- /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!(::A, 42); + assert_eq!(::B, 42); + + assert_eq!(::A, 0); + assert_eq!(::B, 0); + + assert_eq!(::A, 100); + assert_eq!(::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 000000000000..27435ef34a0e --- /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!(::A, 254); + assert_eq!(::B, 255); + + assert_eq!(::A, 255); + assert_eq!(::B, 0); + + assert_eq!(::A, 254); + assert_eq!(::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 000000000000..aac1765c4b2d --- /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 000000000000..c08e05c8a307 --- /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!(::A, 254); + assert_eq!(::B, 255); + + assert_eq!(::A, 255); + assert_eq!(::B, 0); + + assert_eq!(::A, 254); + assert_eq!(::B, 0); +}