+++ /dev/null
-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);
-}
+++ /dev/null
-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 = Foo::ID;
- | ^^^^^^^
-help: disambiguate the associated constant for candidate #2
- |
-LL | const X: i32 = Bar::ID;
- | ^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0034`.
+++ /dev/null
-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);
-}
+++ /dev/null
-error[E0277]: the trait bound `i32: Foo` is not satisfied
- --> $DIR/associated-const-array-len.rs:5:16
- |
-LL | const ID: usize;
- | ---------------- required by `Foo::ID`
-...
-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`.
+++ /dev/null
-#![deny(dead_code)]
-
-struct MyFoo;
-
-impl MyFoo {
- const BAR: u32 = 1;
- //~^ ERROR associated constant is never used: `BAR`
-}
-
-fn main() {
- let _: MyFoo = MyFoo;
-}
+++ /dev/null
-error: associated constant is never used: `BAR`
- --> $DIR/associated-const-dead-code.rs:6:5
- |
-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
-
+++ /dev/null
-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() {}
+++ /dev/null
-error[E0326]: implemented const `FROM` has an incompatible type for trait
- --> $DIR/associated-const-generic-obligations.rs:14:17
- |
-LL | const FROM: Self::Out;
- | --------- type in trait
-...
-LL | const FROM: &'static str = "foo";
- | ^^^^^^^^^^^^ expected associated type, found `&str`
- |
- = 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`.
+++ /dev/null
-trait Foo {
- const NAME: &'static str;
-}
-
-
-impl<'a> Foo for &'a () {
- const NAME: &'a str = "unit";
- //~^ ERROR mismatched types [E0308]
-}
-
-fn main() {}
+++ /dev/null
-error[E0308]: mismatched types
- --> $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 on the impl at 6:6...
- --> $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`.
+++ /dev/null
-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() {}
+++ /dev/null
-error[E0326]: implemented const `BAR` has an incompatible type for trait
- --> $DIR/associated-const-impl-wrong-type.rs:8:16
- |
-LL | const BAR: u32;
- | --- type in trait
-...
-LL | const BAR: i32 = -1;
- | ^^^ expected `u32`, found `i32`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0326`.
+++ /dev/null
-// #29924
-
-#![feature(const_fn, associated_consts)]
-
-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() {}
+++ /dev/null
-error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/associated-const-in-trait.rs:9:6
- |
-LL | trait Trait {
- | ----- this trait cannot be made into an object...
-LL | const N: usize;
- | - ...because it contains this associated `const`
-...
-LL | impl dyn Trait {
- | ^^^^^^^^^ the trait `Trait` cannot be made into an object
- |
- = help: consider moving `N` to another trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0038`.
+++ /dev/null
-trait Foo {
- const ID: i32;
-}
-
-const X: i32 = <i32>::ID;
-//~^ ERROR no associated item named `ID` found
-
-fn main() {
- assert_eq!(1, X);
-}
+++ /dev/null
-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`.
+++ /dev/null
-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
-}
+++ /dev/null
-error[E0624]: associated constant `ID` is private
- --> $DIR/associated-const-private-impl.rs:13:30
- |
-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`.
+++ /dev/null
-// 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() {}
+++ /dev/null
-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() {
-}
+++ /dev/null
-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`.
+++ /dev/null
-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() {
-}
+++ /dev/null
-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
-
+++ /dev/null
-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 the trait bound `A: Foo` is not satisfied [E0277]
-}
-
-fn main() {
-}
+++ /dev/null
-error[E0277]: the trait bound `A: Foo` is not satisfied
- --> $DIR/associated-const-type-parameter-arrays.rs:16:23
- |
-LL | const Y: usize;
- | --------------- required by `Foo::Y`
-...
-LL | let _array: [u32; <A as Foo>::Y];
- | ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
- |
-help: consider further restricting this bound
- |
-LL | pub fn test<A: Foo + Foo, B: Foo>() {
- | ^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-// build-fail
-//~^ ERROR cycle detected when normalizing `<() as Tr>::A`
-
-// 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 () {}
-
-fn main() {
- // This triggers the cycle error
- assert_eq!(<() as Tr>::A, 0);
-}
+++ /dev/null
-error[E0391]: cycle detected when normalizing `<() as Tr>::A`
- |
-note: ...which requires simplifying constant for the type system `Tr::A`...
- --> $DIR/defaults-cyclic-fail.rs:6:5
- |
-LL | const A: u8 = Self::B;
- | ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires simplifying constant for the type system `Tr::A`...
- --> $DIR/defaults-cyclic-fail.rs:6:5
- |
-LL | const A: u8 = Self::B;
- | ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const-evaluating + checking `Tr::A`...
- --> $DIR/defaults-cyclic-fail.rs:6:5
- |
-LL | const A: u8 = Self::B;
- | ^^^^^^^^^^^^^^^^^^^^^^
- = note: ...which requires normalizing `<() as Tr>::B`...
-note: ...which requires simplifying constant for the type system `Tr::B`...
- --> $DIR/defaults-cyclic-fail.rs:8:5
- |
-LL | const B: u8 = Self::A;
- | ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires simplifying constant for the type system `Tr::B`...
- --> $DIR/defaults-cyclic-fail.rs:8:5
- |
-LL | const B: u8 = Self::A;
- | ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const-evaluating + checking `Tr::B`...
- --> $DIR/defaults-cyclic-fail.rs:8:5
- |
-LL | const B: u8 = Self::A;
- | ^^^^^^^^^^^^^^^^^^^^^^
- = note: ...which again requires normalizing `<() as Tr>::A`, completing the cycle
-note: cycle used when const-evaluating + checking `main::promoted[2]`
- --> $DIR/defaults-cyclic-fail.rs:14:1
- |
-LL | fn main() {
- | ^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0391`.
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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 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
- //~| ERROR erroneous constant used
-
- 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);
-}
+++ /dev/null
-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 compute `u8::MAX + 1_u8`, which would 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 (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: erroneous constant used
- --> $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 (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0080`.
+++ /dev/null
-// 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);
-}
+++ /dev/null
-trait A {
- const C: usize;
-
- fn f() -> ([u8; A::C], [u8; A::C]);
- //~^ ERROR: type annotations needed
- //~| ERROR: type annotations needed
-}
-
-fn main() {}
+++ /dev/null
-error[E0283]: type annotations needed
- --> $DIR/issue-63496.rs:4:21
- |
-LL | const C: usize;
- | --------------- required by `A::C`
-LL |
-LL | fn f() -> ([u8; A::C], [u8; A::C]);
- | ^^^^
- | |
- | cannot infer type
- | help: use the fully qualified path to an implementation: `<Type as A>::C`
- |
- = note: cannot satisfy `_: A`
- = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
-
-error[E0283]: type annotations needed
- --> $DIR/issue-63496.rs:4:33
- |
-LL | const C: usize;
- | --------------- required by `A::C`
-LL |
-LL | fn f() -> ([u8; A::C], [u8; A::C]);
- | ^^^^
- | |
- | cannot infer type
- | help: use the fully qualified path to an implementation: `<Type as A>::C`
- |
- = note: cannot satisfy `_: A`
- = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0283`.
+++ /dev/null
-error: this arithmetic operation will overflow
- --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29: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:31: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:34: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:36: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:39: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:41: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:44: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:46: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
-
+++ /dev/null
-error: this arithmetic operation will overflow
- --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29: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:31: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:34: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:36: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:39: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:41: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:44: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:46: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
-
+++ /dev/null
-error: this arithmetic operation will overflow
- --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29: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:31: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:34: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:36: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:39: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:41: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:44: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:46: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
-
+++ /dev/null
-// 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"]
-
-use std::i32;
-
-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
-}
--- /dev/null
+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);
+}
--- /dev/null
+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 = Foo::ID;
+ | ^^^^^^^
+help: disambiguate the associated constant for candidate #2
+ |
+LL | const X: i32 = Bar::ID;
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.
--- /dev/null
+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);
+}
--- /dev/null
+error[E0277]: the trait bound `i32: Foo` is not satisfied
+ --> $DIR/associated-const-array-len.rs:5:16
+ |
+LL | const ID: usize;
+ | ---------------- required by `Foo::ID`
+...
+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`.
--- /dev/null
+#![deny(dead_code)]
+
+struct MyFoo;
+
+impl MyFoo {
+ const BAR: u32 = 1;
+ //~^ ERROR associated constant is never used: `BAR`
+}
+
+fn main() {
+ let _: MyFoo = MyFoo;
+}
--- /dev/null
+error: associated constant is never used: `BAR`
+ --> $DIR/associated-const-dead-code.rs:6:5
+ |
+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
+
--- /dev/null
+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() {}
--- /dev/null
+error[E0326]: implemented const `FROM` has an incompatible type for trait
+ --> $DIR/associated-const-generic-obligations.rs:14:17
+ |
+LL | const FROM: Self::Out;
+ | --------- type in trait
+...
+LL | const FROM: &'static str = "foo";
+ | ^^^^^^^^^^^^ expected associated type, found `&str`
+ |
+ = 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`.
--- /dev/null
+trait Foo {
+ const NAME: &'static str;
+}
+
+
+impl<'a> Foo for &'a () {
+ const NAME: &'a str = "unit";
+ //~^ ERROR mismatched types [E0308]
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $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 on the impl at 6:6...
+ --> $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`.
--- /dev/null
+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() {}
--- /dev/null
+error[E0326]: implemented const `BAR` has an incompatible type for trait
+ --> $DIR/associated-const-impl-wrong-type.rs:8:16
+ |
+LL | const BAR: u32;
+ | --- type in trait
+...
+LL | const BAR: i32 = -1;
+ | ^^^ expected `u32`, found `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0326`.
--- /dev/null
+// #29924
+
+#![feature(const_fn, associated_consts)]
+
+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() {}
--- /dev/null
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/associated-const-in-trait.rs:9:6
+ |
+LL | trait Trait {
+ | ----- this trait cannot be made into an object...
+LL | const N: usize;
+ | - ...because it contains this associated `const`
+...
+LL | impl dyn Trait {
+ | ^^^^^^^^^ the trait `Trait` cannot be made into an object
+ |
+ = help: consider moving `N` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
--- /dev/null
+trait Foo {
+ const ID: i32;
+}
+
+const X: i32 = <i32>::ID;
+//~^ ERROR no associated item named `ID` found
+
+fn main() {
+ assert_eq!(1, X);
+}
--- /dev/null
+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`.
--- /dev/null
+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
+}
--- /dev/null
+error[E0624]: associated constant `ID` is private
+ --> $DIR/associated-const-private-impl.rs:13:30
+ |
+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`.
--- /dev/null
+// 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() {}
--- /dev/null
+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() {
+}
--- /dev/null
+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`.
--- /dev/null
+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() {
+}
--- /dev/null
+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
+
--- /dev/null
+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 the trait bound `A: Foo` is not satisfied [E0277]
+}
+
+fn main() {
+}
--- /dev/null
+error[E0277]: the trait bound `A: Foo` is not satisfied
+ --> $DIR/associated-const-type-parameter-arrays.rs:16:23
+ |
+LL | const Y: usize;
+ | --------------- required by `Foo::Y`
+...
+LL | let _array: [u32; <A as Foo>::Y];
+ | ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
+ |
+help: consider further restricting this bound
+ |
+LL | pub fn test<A: Foo + Foo, B: Foo>() {
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// build-fail
+//~^ ERROR cycle detected when normalizing `<() as Tr>::A`
+
+// 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 () {}
+
+fn main() {
+ // This triggers the cycle error
+ assert_eq!(<() as Tr>::A, 0);
+}
--- /dev/null
+error[E0391]: cycle detected when normalizing `<() as Tr>::A`
+ |
+note: ...which requires simplifying constant for the type system `Tr::A`...
+ --> $DIR/defaults-cyclic-fail.rs:6:5
+ |
+LL | const A: u8 = Self::B;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires simplifying constant for the type system `Tr::A`...
+ --> $DIR/defaults-cyclic-fail.rs:6:5
+ |
+LL | const A: u8 = Self::B;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `Tr::A`...
+ --> $DIR/defaults-cyclic-fail.rs:6:5
+ |
+LL | const A: u8 = Self::B;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which requires normalizing `<() as Tr>::B`...
+note: ...which requires simplifying constant for the type system `Tr::B`...
+ --> $DIR/defaults-cyclic-fail.rs:8:5
+ |
+LL | const B: u8 = Self::A;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires simplifying constant for the type system `Tr::B`...
+ --> $DIR/defaults-cyclic-fail.rs:8:5
+ |
+LL | const B: u8 = Self::A;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `Tr::B`...
+ --> $DIR/defaults-cyclic-fail.rs:8:5
+ |
+LL | const B: u8 = Self::A;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which again requires normalizing `<() as Tr>::A`, completing the cycle
+note: cycle used when const-evaluating + checking `main::promoted[2]`
+ --> $DIR/defaults-cyclic-fail.rs:14:1
+ |
+LL | fn main() {
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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 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
+ //~| ERROR erroneous constant used
+
+ 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);
+}
--- /dev/null
+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 compute `u8::MAX + 1_u8`, which would 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 (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: erroneous constant used
+ --> $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 (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
--- /dev/null
+// 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);
+}
--- /dev/null
+trait A {
+ const C: usize;
+
+ fn f() -> ([u8; A::C], [u8; A::C]);
+ //~^ ERROR: type annotations needed
+ //~| ERROR: type annotations needed
+}
+
+fn main() {}
--- /dev/null
+error[E0283]: type annotations needed
+ --> $DIR/issue-63496.rs:4:21
+ |
+LL | const C: usize;
+ | --------------- required by `A::C`
+LL |
+LL | fn f() -> ([u8; A::C], [u8; A::C]);
+ | ^^^^
+ | |
+ | cannot infer type
+ | help: use the fully qualified path to an implementation: `<Type as A>::C`
+ |
+ = note: cannot satisfy `_: A`
+ = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-63496.rs:4:33
+ |
+LL | const C: usize;
+ | --------------- required by `A::C`
+LL |
+LL | fn f() -> ([u8; A::C], [u8; A::C]);
+ | ^^^^
+ | |
+ | cannot infer type
+ | help: use the fully qualified path to an implementation: `<Type as A>::C`
+ |
+ = note: cannot satisfy `_: A`
+ = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
--- /dev/null
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29: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:31: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:34: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:36: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:39: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:41: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:44: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:46: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
+
--- /dev/null
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29: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:31: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:34: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:36: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:39: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:41: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:44: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:46: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
+
--- /dev/null
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29: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:31: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:34: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:36: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:39: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:41: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:44: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:46: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
+
--- /dev/null
+// 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"]
+
+use std::i32;
+
+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
+}