From 4310ba2c985c161260bbdfef5d92ceea552e9055 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 16 Mar 2019 00:03:51 +0000 Subject: [PATCH] Added test suite. --- src/test/run-pass/issues/issue-25700-2.rs | 2 +- .../auxiliary/fn-aux.rs | 177 +++++ .../auxiliary/fn-dyn-aux.rs | 182 +++++ .../bad-bounds-on-assoc-in-trait.rs | 60 ++ .../bad-bounds-on-assoc-in-trait.stderr | 85 +++ .../bounds-on-assoc-in-trait.rs | 51 ++ .../ui/associated-type-bounds/duplicate.rs | 161 +++++ .../associated-type-bounds/duplicate.stderr | 627 ++++++++++++++++++ .../dyn-existential-type.rs | 67 ++ .../ui/associated-type-bounds/dyn-lcsit.rs | 69 ++ .../dyn-rpit-and-let.rs | 73 ++ .../entails-sized-object-safety.rs | 26 + .../ui/associated-type-bounds/enum-bounds.rs | 122 ++++ .../existential-type.rs | 67 ++ src/test/ui/associated-type-bounds/fn-apit.rs | 58 ++ src/test/ui/associated-type-bounds/fn-aux.rs | 12 + .../ui/associated-type-bounds/fn-dyn-apit.rs | 60 ++ .../ui/associated-type-bounds/fn-inline.rs | 62 ++ .../ui/associated-type-bounds/fn-where.rs | 78 +++ .../ui/associated-type-bounds/fn-wrap-apit.rs | 64 ++ .../implied-region-constraints.rs | 47 ++ .../implied-region-constraints.stderr | 25 + .../ui/associated-type-bounds/inside-adt.rs | 36 + .../associated-type-bounds/inside-adt.stderr | 79 +++ src/test/ui/associated-type-bounds/lcsit.rs | 78 +++ .../nested-lifetime-bounds.rs | 25 + .../nested-lifetime-bounds.stderr | 9 + src/test/ui/associated-type-bounds/rpit.rs | 64 ++ .../associated-type-bounds/struct-bounds.rs | 115 ++++ .../ui/associated-type-bounds/trait-params.rs | 116 ++++ .../ui/associated-type-bounds/type-alias.rs | 19 + .../associated-type-bounds/type-alias.stderr | 97 +++ .../ui/associated-type-bounds/union-bounds.rs | 123 ++++ .../feature-gate-associated_type_bounds.rs | 71 ++ ...feature-gate-associated_type_bounds.stderr | 132 ++++ src/test/ui/type/type-alias-bounds.stderr | 10 - 36 files changed, 3138 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs create mode 100644 src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs create mode 100644 src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs create mode 100644 src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr create mode 100644 src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs create mode 100644 src/test/ui/associated-type-bounds/duplicate.rs create mode 100644 src/test/ui/associated-type-bounds/duplicate.stderr create mode 100644 src/test/ui/associated-type-bounds/dyn-existential-type.rs create mode 100644 src/test/ui/associated-type-bounds/dyn-lcsit.rs create mode 100644 src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs create mode 100644 src/test/ui/associated-type-bounds/entails-sized-object-safety.rs create mode 100644 src/test/ui/associated-type-bounds/enum-bounds.rs create mode 100644 src/test/ui/associated-type-bounds/existential-type.rs create mode 100644 src/test/ui/associated-type-bounds/fn-apit.rs create mode 100644 src/test/ui/associated-type-bounds/fn-aux.rs create mode 100644 src/test/ui/associated-type-bounds/fn-dyn-apit.rs create mode 100644 src/test/ui/associated-type-bounds/fn-inline.rs create mode 100644 src/test/ui/associated-type-bounds/fn-where.rs create mode 100644 src/test/ui/associated-type-bounds/fn-wrap-apit.rs create mode 100644 src/test/ui/associated-type-bounds/implied-region-constraints.rs create mode 100644 src/test/ui/associated-type-bounds/implied-region-constraints.stderr create mode 100644 src/test/ui/associated-type-bounds/inside-adt.rs create mode 100644 src/test/ui/associated-type-bounds/inside-adt.stderr create mode 100644 src/test/ui/associated-type-bounds/lcsit.rs create mode 100644 src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs create mode 100644 src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr create mode 100644 src/test/ui/associated-type-bounds/rpit.rs create mode 100644 src/test/ui/associated-type-bounds/struct-bounds.rs create mode 100644 src/test/ui/associated-type-bounds/trait-params.rs create mode 100644 src/test/ui/associated-type-bounds/type-alias.rs create mode 100644 src/test/ui/associated-type-bounds/type-alias.stderr create mode 100644 src/test/ui/associated-type-bounds/union-bounds.rs create mode 100644 src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs create mode 100644 src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr diff --git a/src/test/run-pass/issues/issue-25700-2.rs b/src/test/run-pass/issues/issue-25700-2.rs index 65de5edce48..b161e68abaf 100644 --- a/src/test/run-pass/issues/issue-25700-2.rs +++ b/src/test/run-pass/issues/issue-25700-2.rs @@ -18,5 +18,5 @@ fn record_type(i: Id::Untyped) -> u8 { } pub fn main() { - assert_eq!(record_type::(3), 42); + assert_eq!(record_type::(3), 42); } diff --git a/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs b/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs new file mode 100644 index 00000000000..0ea23ad1dbf --- /dev/null +++ b/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs @@ -0,0 +1,177 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha(x: T) -> usize { x.alpha() } +pub fn assert_static(_: T) -> usize { 24 } +pub fn assert_delta(x: T) -> usize { x.delta() } +pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } +pub fn assert_epsilon_forall Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + x.epsilon() + x.zeta().eta() +} + +// Implementations and types: + +#[derive(Copy, Clone)] +pub struct BetaType; + +#[derive(Copy, Clone)] +pub struct GammaType; + +#[derive(Copy, Clone)] +pub struct ZetaType; + +impl Beta for BetaType { + type Gamma = GammaType; + fn gamma(self) -> Self::Gamma { GammaType } +} + +impl<'a> Beta for &'a BetaType { + type Gamma = GammaType; + fn gamma(self) -> Self::Gamma { GammaType } +} + +impl Beta for GammaType { + type Gamma = Self; + fn gamma(self) -> Self::Gamma { self } +} + +impl Alpha for GammaType { + fn alpha(self) -> usize { 42 } +} + +impl Delta for GammaType { + fn delta(self) -> usize { 1337 } +} + +impl<'a> Epsilon<'a> for GammaType { + type Zeta = ZetaType; + fn zeta(&'a self) -> Self::Zeta { ZetaType } + + fn epsilon(&'a self) -> usize { 7331 } +} + +impl Eta for ZetaType { + fn eta(self) -> usize { 7 } +} + +// Desugared forms to check against: + +pub fn desugared_bound(beta: B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::(gamma) +} + +pub fn desugared_bound_region(beta: B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::(beta.gamma()) +} + +pub fn desugared_bound_multi(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::(beta.gamma()) + + assert_static::(beta.gamma()) + + assert_delta::(beta.gamma()) +} + +pub fn desugared_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta, + B::Gamma: 'a + Epsilon<'a>, +{ + assert_epsilon_specific::(gamma) +} + +pub fn desugared_bound_region_forall(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::(&g1) + + assert_epsilon_specific::(&g2) +} + +pub fn desugared_bound_region_forall2(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::(gamma) +} + +pub fn desugared_contraint_region_forall(beta: B) -> usize +where + for<'a> &'a B: Beta, + for<'a> <&'a B as Beta>::Gamma: Alpha, +{ + let g1 = beta.gamma(); + let g2 = beta.gamma(); + assert_alpha(g1) + assert_alpha(g2) +} + +pub fn desugared_bound_nested(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + ::Gamma: Delta, +{ + let go = beta.gamma(); + let gi = go.gamma(); + go.alpha() + gi.delta() +} + +pub fn desugared() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, desugared_bound(beta)); + assert_eq!(24, desugared_bound_region(beta)); + assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); + assert_eq!(7331, desugared_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(beta)); + assert_eq!(42 + 1337, desugared_bound_nested(beta)); +} diff --git a/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs b/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs new file mode 100644 index 00000000000..85d6c5aaf3c --- /dev/null +++ b/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs @@ -0,0 +1,182 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(&self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha(x: T) -> usize { x.alpha() } +pub fn assert_static(_: T) -> usize { 24 } +pub fn assert_delta(x: T) -> usize { x.delta() } +pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } +pub fn assert_epsilon_forall Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + x.epsilon() + x.zeta().eta() +} + +// Implementations and types: + +#[derive(Copy, Clone)] +pub struct BetaType; + +#[derive(Copy, Clone)] +pub struct GammaType; + +#[derive(Copy, Clone)] +pub struct ZetaType; + +impl Beta for &(dyn Beta + Send) { + type Gamma = T; + fn gamma(&self) -> Self::Gamma { (*self).gamma() } +} + +impl Beta for BetaType { + type Gamma = GammaType; + fn gamma(&self) -> Self::Gamma { GammaType } +} + +impl<'a> Beta for &'a BetaType { + type Gamma = GammaType; + fn gamma(&self) -> Self::Gamma { GammaType } +} + +impl Beta for GammaType { + type Gamma = Self; + fn gamma(&self) -> Self::Gamma { Self } +} + +impl Alpha for GammaType { + fn alpha(self) -> usize { 42 } +} + +impl Delta for GammaType { + fn delta(self) -> usize { 1337 } +} + +impl<'a> Epsilon<'a> for GammaType { + type Zeta = ZetaType; + fn zeta(&'a self) -> Self::Zeta { ZetaType } + + fn epsilon(&'a self) -> usize { 7331 } +} + +impl Eta for ZetaType { + fn eta(self) -> usize { 7 } +} + +// Desugared forms to check against: + +pub fn desugared_bound(beta: &B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::(gamma) +} + +pub fn desugared_bound_region(beta: &B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::(beta.gamma()) +} + +pub fn desugared_bound_multi(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::(beta.gamma()) + + assert_static::(beta.gamma()) + + assert_delta::(beta.gamma()) +} + +pub fn desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize +where + B: Beta, + B::Gamma: 'a + Epsilon<'a>, +{ + assert_epsilon_specific::(gamma) +} + +pub fn desugared_bound_region_forall(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::(&g1) + + assert_epsilon_specific::(&g2) +} + +pub fn desugared_bound_region_forall2(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::(gamma) +} + +pub fn desugared_contraint_region_forall(beta: &B) -> usize +where + for<'a> &'a B: Beta, + for<'a> <&'a B as Beta>::Gamma: Alpha, +{ + let g1 = beta.gamma(); + let g2 = beta.gamma(); + assert_alpha(g1) + assert_alpha(g2) +} + +pub fn desugared_bound_nested(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + ::Gamma: Delta, +{ + let go = beta.gamma(); + let gi = go.gamma(); + go.alpha() + gi.delta() +} + +pub fn desugared() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, desugared_bound(&beta)); + assert_eq!(24, desugared_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); + assert_eq!(7331, desugared_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(&beta)); + assert_eq!(42 + 1337, desugared_bound_nested(&beta)); +} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs new file mode 100644 index 00000000000..78704a9b512 --- /dev/null +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -0,0 +1,60 @@ +// compile-fail +// ignore-tidy-linelength + +// NOTE: rustc cannot currently handle bounds of the form `for<'a> >::Assoc: Baz`. +// This should hopefully be fixed with Chalk. + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Once; + +trait Lam { type App; } + +#[derive(Clone)] +struct L1; +impl<'a> Lam<&'a u8> for L1 { type App = u8; } + +#[derive(Clone)] +struct L2; +impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; } + +trait Case1 { + type C: Clone + Iterator Lam<&'a u8, App: + Debug + > + > + Sync>; +} + +pub struct S1; +impl Case1 for S1 { +//~^ ERROR `>::App` doesn't implement `std::fmt::Debug` [E0277] + type C = Once>; +} + +fn assume_case1() { +//~^ ERROR `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` [E0277] +//~| ERROR `<::C as std::iter::Iterator>::Item` is not an iterator [E0277] +//~| ERROR `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely [E0277] +//~| ERROR `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely [E0277] + fn assert_a<_0, A>() where A: Iterator, _0: Debug {} + assert_a::<_, T::A>(); + + fn assert_b<_0, B>() where B: Iterator, _0: 'static {} + assert_b::<_, T::B>(); + + fn assert_c<_0, _1, _2, C>() + where + C: Clone + Iterator, + _2: Send + Iterator, + _1: for<'a> Lam<&'a u8, App = _0>, + _0: Debug, + {} + assert_c::<_, _, _, T::C>(); +} + +fn main() { + assume_case1(S1); +} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr new file mode 100644 index 00000000000..aebf29cc332 --- /dev/null +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -0,0 +1,85 @@ +error[E0277]: `>::App` doesn't implement `std::fmt::Debug` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:32:6 + | +LL | impl Case1 for S1 { + | ^^^^^ `>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `for<'a> std::fmt::Debug` is not implemented for `>::App` + +error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<::C as std::iter::Iterator>::Item` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` + = help: consider adding a `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` bound + +error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` + = help: consider adding a `where <::C as std::iter::Iterator>::Item: std::marker::Send` bound +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` + = help: consider adding a `where <::C as std::iter::Iterator>::Item: std::marker::Sync` bound +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs new file mode 100644 index 00000000000..8c9110d03ec --- /dev/null +++ b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs @@ -0,0 +1,51 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Empty; +use std::ops::Range; + +trait Lam { type App; } + +#[derive(Clone)] +struct L1; +impl<'a> Lam<&'a u8> for L1 { type App = u8; } + +#[derive(Clone)] +struct L2; +impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; } + +trait Case1 { + type A: Iterator; + + type B: Iterator; +} + +pub struct S1; +impl Case1 for S1 { + type A = Empty; + type B = Range; +} + +// Ensure we don't have existential desugaring: + +pub trait Foo { type Out: Baz; } +pub trait Baz { type Assoc; } + +#[derive(Default)] +struct S2; +#[derive(Default)] +struct S3; +struct S4; +struct S5; +struct S6; +struct S7; + +impl Foo for S6 { type Out = S4; } +impl Foo for S7 { type Out = S5; } + +impl Baz for S4 { type Assoc = S2; } +impl Baz for S5 { type Assoc = S3; } + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs new file mode 100644 index 00000000000..bee56d6f689 --- /dev/null +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -0,0 +1,161 @@ +// compile-fail +// ignore-tidy-linelength +// error-pattern:could not find defining uses + +#![feature(associated_type_bounds)] +#![feature(existential_type)] +#![feature(impl_trait_in_bindings)] +#![feature(untagged_unions)] + +use std::iter; + +struct SI1> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SI2> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SI3> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW1 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW2 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW3 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +enum EI1> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EI2> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EI3> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW1 where T: Iterator { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW2 where T: Iterator { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW3 where T: Iterator { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +union UI1> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UI2> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UI3> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW1 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW2 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW3 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn FI1>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FI2>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FI3>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW1() where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW2() where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW3() where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn FRPIT1() -> impl Iterator { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FRPIT2() -> impl Iterator { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FRPIT3() -> impl Iterator { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT1(_: impl Iterator) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT2(_: impl Iterator) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT3(_: impl Iterator) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +const CIT1: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +const CIT2: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +const CIT3: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT1: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT2: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT3: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn lit1() { let _: impl Iterator = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn lit2() { let _: impl Iterator = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn lit3() { let _: impl Iterator = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +type TAI1> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAI2> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAI3> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW1 where T: Iterator = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW2 where T: Iterator = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW3 where T: Iterator = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +existential type ETAI1>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI2>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI3>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI4: Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI5: Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI6: Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +trait TRI1> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRI2> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRI3> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS1: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS2: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS3: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW1 where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW2 where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW3 where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW1 where Self: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW2 where Self: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW3 where Self: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA1 { type A: Iterator; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA2 { type A: Iterator; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA3 { type A: Iterator; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +type TADyn1 = dyn Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TADyn2 = Box>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TADyn3 = dyn Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr new file mode 100644 index 00000000000..fbf02ddc703 --- /dev/null +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -0,0 +1,627 @@ +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:12:36 + | +LL | struct SI1> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:14:36 + | +LL | struct SI2> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:16:39 + | +LL | struct SI3> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:18:45 + | +LL | struct SW1 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:20:45 + | +LL | struct SW2 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:22:48 + | +LL | struct SW3 where T: Iterator { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:25:34 + | +LL | enum EI1> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:27:34 + | +LL | enum EI2> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:29:37 + | +LL | enum EI3> { V(T) } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:31:43 + | +LL | enum EW1 where T: Iterator { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:33:43 + | +LL | enum EW2 where T: Iterator { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:35:46 + | +LL | enum EW3 where T: Iterator { V(T) } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:38:35 + | +LL | union UI1> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:40:35 + | +LL | union UI2> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:42:38 + | +LL | union UI3> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:44:44 + | +LL | union UW1 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:46:44 + | +LL | union UW2 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:48:47 + | +LL | union UW3 where T: Iterator { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:51:32 + | +LL | fn FI1>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:53:32 + | +LL | fn FI2>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:55:35 + | +LL | fn FI3>() {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:57:43 + | +LL | fn FW1() where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:59:43 + | +LL | fn FW2() where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:61:46 + | +LL | fn FW3() where T: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:70:40 + | +LL | fn FAPIT1(_: impl Iterator) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:72:40 + | +LL | fn FAPIT2(_: impl Iterator) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:74:43 + | +LL | fn FAPIT3(_: impl Iterator) {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:64:42 + | +LL | fn FRPIT1() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:66:42 + | +LL | fn FRPIT2() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:68:45 + | +LL | fn FRPIT3() -> impl Iterator { iter::empty() } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:77:39 + | +LL | const CIT1: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:79:39 + | +LL | const CIT2: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:81:42 + | +LL | const CIT3: impl Iterator = iter::empty(); + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:83:40 + | +LL | static SIT1: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:85:40 + | +LL | static SIT2: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:87:43 + | +LL | static SIT3: impl Iterator = iter::empty(); + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:90:46 + | +LL | fn lit1() { let _: impl Iterator = iter::empty(); } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:92:46 + | +LL | fn lit2() { let _: impl Iterator = iter::empty(); } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:94:49 + | +LL | fn lit3() { let _: impl Iterator = iter::empty(); } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:97:35 + | +LL | type TAI1> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:99:35 + | +LL | type TAI2> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:101:38 + | +LL | type TAI3> = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:103:44 + | +LL | type TAW1 where T: Iterator = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:105:44 + | +LL | type TAW2 where T: Iterator = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:107:47 + | +LL | type TAW3 where T: Iterator = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:110:1 + | +LL | existential type ETAI1>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:110:48 + | +LL | existential type ETAI1>: Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:112:1 + | +LL | existential type ETAI2>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:112:48 + | +LL | existential type ETAI2>: Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:114:1 + | +LL | existential type ETAI3>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:114:51 + | +LL | existential type ETAI3>: Copy; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:116:1 + | +LL | existential type ETAI4: Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:116:46 + | +LL | existential type ETAI4: Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:118:1 + | +LL | existential type ETAI5: Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:118:46 + | +LL | existential type ETAI5: Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:120:1 + | +LL | existential type ETAI6: Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:120:49 + | +LL | existential type ETAI6: Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:123:36 + | +LL | trait TRI1> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:125:36 + | +LL | trait TRI2> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:127:39 + | +LL | trait TRI3> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:129:34 + | +LL | trait TRS1: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:131:34 + | +LL | trait TRS2: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:133:37 + | +LL | trait TRS3: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:135:45 + | +LL | trait TRW1 where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:137:45 + | +LL | trait TRW2 where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:139:48 + | +LL | trait TRW3 where T: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:141:46 + | +LL | trait TRSW1 where Self: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:143:46 + | +LL | trait TRSW2 where Self: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:145:49 + | +LL | trait TRSW3 where Self: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:147:43 + | +LL | trait TRA1 { type A: Iterator; } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:149:43 + | +LL | trait TRA2 { type A: Iterator; } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:151:46 + | +LL | trait TRA3 { type A: Iterator; } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:154:40 + | +LL | type TADyn1 = dyn Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:156:44 + | +LL | type TADyn2 = Box>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:158:43 + | +LL | type TADyn3 = dyn Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: aborting due to 93 previous errors + +For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/associated-type-bounds/dyn-existential-type.rs b/src/test/ui/associated-type-bounds/dyn-existential-type.rs new file mode 100644 index 00000000000..dc0afaa934a --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-existential-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(existential_type)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +type Et1 = Box>; +fn def_et1() -> Et1 { Box::new(S1) } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +type Et2 = Box>; +fn def_et2() -> Et2 { Box::new(S1) } +pub fn use_et2() { assert_static(def_et2().mk()); } + +type Et3 = Box>>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + Box::new(A) +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +type Et4 = Box Tr2<'a>>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + Box::new(A) +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.rs b/src/test/ui/associated-type-bounds/dyn-lcsit.rs new file mode 100644 index 00000000000..439304fd309 --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.rs @@ -0,0 +1,69 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] + +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: &dyn Tr1 = &S1; +const sdef_et1: &dyn Tr1 = &S1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: &(dyn Tr1 + Sync) = &S1; +static sdef_et2: &(dyn Tr1 + Sync) = &S1; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: &dyn Tr1>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + &A +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: &(dyn Tr1 Tr2<'a>> + Sync) = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + &A +}; +static sdef_et4: &(dyn Tr1 Tr2<'a>> + Sync) = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs new file mode 100644 index 00000000000..f22a6c44cb8 --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs @@ -0,0 +1,73 @@ +// run-pass + +// FIXME: uncomment let binding types below when `impl_trait_in_bindings` feature is fixed. + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +fn def_et1() -> Box> { + let x /* : Box> */ = Box::new(S1); + x +} +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> Box> { + let x /* : Box> */ = Box::new(S1); + x +} +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> Box>>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x /* : Box>>>> */ + = Box::new(A); + x +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +fn def_et4() -> Box Tr2<'a>>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x /* : Box Tr2<'a>>> */ = Box::new(A); + x +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs new file mode 100644 index 00000000000..1b3e978594d --- /dev/null +++ b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -0,0 +1,26 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +trait Tr1: Sized { type As1; } +trait Tr2<'a>: Sized { type As2; } + +trait ObjTr1 { fn foo() -> Self where Self: Tr1; } +fn _assert_obj_safe_1(_: Box) {} + +trait ObjTr2 { fn foo() -> Self where Self: Tr1; } +fn _assert_obj_safe_2(_: Box) {} + +trait ObjTr3 { fn foo() -> Self where Self: Tr1 + 'static + Copy>; } +fn _assert_obj_safe_3(_: Box) {} + +trait ObjTr4 { fn foo() -> Self where Self: Tr1 Tr2<'a>>; } +fn _assert_obj_safe_4(_: Box) {} + +trait ObjTr5 { fn foo() -> Self where for<'a> Self: Tr1>; } +fn _assert_obj_safe_5(_: Box) {} + +trait ObjTr6 { fn foo() -> Self where Self: for<'a> Tr1 Tr2<'b>>>; } +fn _assert_obj_safe_6(_: Box) {} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/enum-bounds.rs b/src/test/ui/associated-type-bounds/enum-bounds.rs new file mode 100644 index 00000000000..a6b0bb7070b --- /dev/null +++ b/src/test/ui/associated-type-bounds/enum-bounds.rs @@ -0,0 +1,122 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +enum En1> { + Outest(T), + Outer(T::As1), + Inner(::As2), +} + +fn wrap_en1_1(x: T) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Outest(x) +} + +fn wrap_en1_2(x: T::As1) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Outer(x) +} + +fn wrap_en1_3(x: ::As2) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Inner(x) +} + +enum En2>> { + V0(T), + V1(T::As1), + V2(::As2), + V3(<::As2 as Tr3>::As3), +} + +enum En3> { + V0(T), + V1(&'static T::As1), +} + +enum En4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + V0(&'x1 >::As4), + V1(&'x2 >::As4), +} + +enum _En5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + _V0(&'x1 >::As4), + _V1(&'x2 >::As4), +} + +enum En6 +where + T: Tr1, +{ + V0(T), + V1(::As2), + V2(&'static T::As1), + V3(::As5), +} + +enum _En7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + V0(&'a T), + V1(&'b ::As2), +} + +fn _make_en7<'a, 'b, T>(x: _En7<'a, 'b, T>) +where + T: Tr1, +{ + match x { + _En7::V0(x) => { + let _: &'a T = &x; + }, + _En7::V1(_) => {}, + } +} + +enum EnSelf where Self: Tr1 { + V0(T), + V1(::As1), + V2(<::As1 as Tr2>::As2), +} + +impl Tr1 for EnSelf<&'static str> { type As1 = bool; } + +fn main() { + if let En1::Outest("foo") = wrap_en1_1::<_>("foo") {} else { panic!() }; + if let En1::Outer(true) = wrap_en1_2::<&str>(true) {} else { panic!() }; + if let En1::Inner(24u8) = wrap_en1_3::<&str>(24u8) {} else { panic!() }; + + let _ = En2::<_>::V0("151571"); + let _ = En2::<&str>::V1(false); + let _ = En2::<&str>::V2(42u8); + let _ = En2::<&str>::V3(|| 12u8); + + let _ = En3::<_>::V0("deadbeef"); + let _ = En3::<&str>::V1(&true); + + let f1 = (1,); + let f2 = (2,); + let _ = En4::<()>::V0(&f1.0); + let _ = En4::<()>::V1(&f2.0); + + let _ = En6::<_>::V0("bar"); + let _ = En6::<&str>::V1(24u8); + let _ = En6::<&str>::V2(&false); + let _ = En6::<&str>::V3(12u16); + + let _ = EnSelf::<_>::V0("foo"); + let _ = EnSelf::<&'static str>::V1(true); + let _ = EnSelf::<&'static str>::V2(24u8); +} diff --git a/src/test/ui/associated-type-bounds/existential-type.rs b/src/test/ui/associated-type-bounds/existential-type.rs new file mode 100644 index 00000000000..87046aec5c4 --- /dev/null +++ b/src/test/ui/associated-type-bounds/existential-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(existential_type)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +existential type Et1: Tr1; +fn def_et1() -> Et1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +existential type Et2: Tr1; +fn def_et2() -> Et2 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +existential type Et3: Tr1>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +existential type Et4: Tr1 Tr2<'a>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/fn-apit.rs b/src/test/ui/associated-type-bounds/fn-apit.rs new file mode 100644 index 00000000000..7e208b4e70d --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-apit.rs @@ -0,0 +1,58 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn apit_bound(beta: impl Beta) -> usize { + desugared_bound(beta) +} + +fn apit_bound_region(beta: impl Beta) -> usize { + desugared_bound_region(beta) +} + +fn apit_bound_multi( + beta: impl Copy + Beta +) -> usize { + desugared_bound_multi(beta) +} + +fn apit_bound_region_forall( + beta: impl Beta Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn apit_bound_region_forall2( + beta: impl Beta Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn apit_bound_nested( + beta: impl Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn apit_bound_nested2( + beta: impl Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, apit_bound(beta)); + assert_eq!(24, apit_bound_region(beta)); + assert_eq!(42 + 24 + 1337, apit_bound_multi(beta)); + assert_eq!(7331 * 2, apit_bound_region_forall(beta)); + assert_eq!(42 + 1337, apit_bound_nested(beta)); + assert_eq!(42 + 1337, apit_bound_nested2(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-aux.rs b/src/test/ui/associated-type-bounds/fn-aux.rs new file mode 100644 index 00000000000..434bdbe996c --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-aux.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn main() { + desugared(); +} diff --git a/src/test/ui/associated-type-bounds/fn-dyn-apit.rs b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs new file mode 100644 index 00000000000..9ff4a50e1e6 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs @@ -0,0 +1,60 @@ +// run-pass +// aux-build:fn-dyn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_dyn_aux; + +use fn_dyn_aux::*; + +// ATB, APIT (dyn trait): + +fn dyn_apit_bound(beta: &dyn Beta) -> usize { + desugared_bound(beta) +} + +fn dyn_apit_bound_region(beta: &dyn Beta) -> usize { + desugared_bound_region(beta) +} + +fn dyn_apit_bound_multi( + beta: &(dyn Beta + Send) +) -> usize { + desugared_bound_multi(beta) +} + +fn dyn_apit_bound_region_forall( + beta: &dyn Beta Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn dyn_apit_bound_region_forall2( + beta: &dyn Beta Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn dyn_apit_bound_nested( + beta: &dyn Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn dyn_apit_bound_nested2( + beta: &dyn Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, dyn_apit_bound(&beta)); + assert_eq!(24, dyn_apit_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, dyn_apit_bound_multi(&beta)); + assert_eq!(7331 * 2, dyn_apit_bound_region_forall(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested2(&beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-inline.rs b/src/test/ui/associated-type-bounds/fn-inline.rs new file mode 100644 index 00000000000..7b188763b7a --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-inline.rs @@ -0,0 +1,62 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Inline bounds: + +fn inline_bound>(beta: B) -> usize { + desugared_bound(beta) +} + +fn inline_bound_region>(beta: B) -> usize { + desugared_bound_region(beta) +} + +fn inline_bound_multi>( + beta: B +) -> usize { + desugared_bound_multi(beta) +} + +fn inline_bound_region_specific<'a, B: Beta>>( + gamma: &'a B::Gamma +) -> usize { + desugared_bound_region_specific::(gamma) +} + +fn inline_bound_region_forall Epsilon<'a>>>( + beta: B +) -> usize { + desugared_bound_region_forall(beta) +} + +fn inline_bound_region_forall2 Epsilon<'a, Zeta: Eta>>>( + beta: B +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn inline_bound_nested>>( + beta: B +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, inline_bound(beta)); + assert_eq!(24, inline_bound_region(beta)); + assert_eq!(42 + 24 + 1337, inline_bound_multi(beta)); + assert_eq!(7331, inline_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, inline_bound_region_forall(beta)); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, inline_bound_region_forall2(beta)); + assert_eq!(42 + 1337, inline_bound_nested(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-where.rs b/src/test/ui/associated-type-bounds/fn-where.rs new file mode 100644 index 00000000000..60d7149a56f --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-where.rs @@ -0,0 +1,78 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Where-clauses: + +fn where_bound(beta: B) -> usize +where + B: Beta +{ + desugared_bound(beta) +} + +fn where_bound_region(beta: B) -> usize +where + B: Beta +{ + desugared_bound_region(beta) +} + +fn where_bound_multi(beta: B) -> usize +where + B: Copy + Beta, +{ + desugared_bound_multi(beta) +} + +fn where_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta>, +{ + desugared_bound_region_specific::(gamma) +} + +fn where_bound_region_forall(beta: B) -> usize +where + B: Beta Epsilon<'a>>, +{ + desugared_bound_region_forall(beta) +} + +fn where_bound_region_forall2(beta: B) -> usize +where + B: Beta Epsilon<'a, Zeta: Eta>>, +{ + desugared_bound_region_forall2(beta) +} + +fn where_contraint_region_forall(beta: B) -> usize +where + for<'a> &'a B: Beta, +{ + desugared_contraint_region_forall(beta) +} + +fn where_bound_nested(beta: B) -> usize +where + B: Beta>, +{ + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, where_bound(beta)); + assert_eq!(24, where_bound_region(beta)); + assert_eq!(42 + 24 + 1337, where_bound_multi(beta)); + assert_eq!(7331, where_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, where_bound_region_forall::(beta)); + assert_eq!(42 + 1337, where_bound_nested::(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-wrap-apit.rs b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs new file mode 100644 index 00000000000..23790d416e1 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs @@ -0,0 +1,64 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, APIT + Wrap: + +struct Wrap(T); + +fn wrap_apit_bound(beta: Wrap>) -> usize { + desugared_bound(beta.0) +} + +fn wrap_apit_bound_region(beta: Wrap>) -> usize { + desugared_bound_region(beta.0) +} + +fn wrap_apit_bound_multi( + beta: Wrap> +) -> usize { + desugared_bound_multi(beta.0) +} + +fn wrap_apit_bound_region_forall( + beta: Wrap Epsilon<'a>>> +) -> usize { + desugared_bound_region_forall(beta.0) +} + +fn wrap_apit_bound_region_forall2( + beta: Wrap Epsilon<'a, Zeta: Eta>>> +) -> usize { + desugared_bound_region_forall2(beta.0) +} + +fn wrap_apit_bound_nested( + beta: Wrap>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn wrap_apit_bound_nested2( + beta: Wrap>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, wrap_apit_bound(Wrap(beta))); + assert_eq!(24, wrap_apit_bound_region(Wrap(beta))); + assert_eq!(42 + 24 + 1337, wrap_apit_bound_multi(Wrap(beta))); + assert_eq!(7331 * 2, wrap_apit_bound_region_forall(Wrap(beta))); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, wrap_apit_bound_region_forall2(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested2(Wrap(beta))); +} diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.rs b/src/test/ui/associated-type-bounds/implied-region-constraints.rs new file mode 100644 index 00000000000..4dbaab50a61 --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.rs @@ -0,0 +1,47 @@ +// compile-fail + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct St<'a, 'b, T: Tr1> { // `T: 'b` is *not* implied! + f0: &'a T, // `T: 'a` is implied. + f1: &'b ::As2, // `::As2: 'a` is implied. +} + +fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + // This should fail because `T: 'b` is not implied from `WF(St<'a, 'b, T>)`. + let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + //~^ ERROR lifetime mismatch [E0623] +} + +enum En7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, + T::As1: Tr2, +{ + V0(&'a T), + V1(&'b ::As2), +} + +fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + match x { + En7::V0(x) => { + // Also fails for the same reason as above: + let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + //~^ ERROR lifetime mismatch [E0623] + }, + En7::V1(_) => {}, + } +} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr new file mode 100644 index 00000000000..b07b20272a8 --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr @@ -0,0 +1,25 @@ +error[E0623]: lifetime mismatch + --> $DIR/implied-region-constraints.rs:19:64 + | +LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) + | ------------- + | | + | this type is declared with multiple lifetimes... +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + | ^^^^^ ...but data with one lifetime flows into the other here + +error[E0623]: lifetime mismatch + --> $DIR/implied-region-constraints.rs:40:72 + | +LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) + | -------------- + | | + | this type is declared with multiple lifetimes... +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + | ^^ ...but data with one lifetime flows into the other here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs new file mode 100644 index 00000000000..1257dc6e94b --- /dev/null +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -0,0 +1,36 @@ +// compile-fail +// ignore-tidy-linelength +// error-pattern:could not find defining uses + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +struct S1 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +struct S2 { f: Box> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +struct S3 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] + +enum E1 { V(dyn Iterator) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +enum E2 { V(Box>) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +enum E3 { V(dyn Iterator) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] + +union U1 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +union U2 { f: Box> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +union U3 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr new file mode 100644 index 00000000000..7bdd71b8296 --- /dev/null +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -0,0 +1,79 @@ +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:8:29 + | +LL | struct S1 { f: dyn Iterator } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:11:33 + | +LL | struct S2 { f: Box> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:14:29 + | +LL | struct S3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:18:26 + | +LL | enum E1 { V(dyn Iterator) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:21:30 + | +LL | enum E2 { V(Box>) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:24:26 + | +LL | enum E3 { V(dyn Iterator) } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:28:28 + | +LL | union U1 { f: dyn Iterator } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:31:32 + | +LL | union U2 { f: Box> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:34:28 + | +LL | union U3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ + +error[E0601]: `main` function not found in crate `inside_adt` + | + = note: consider adding a `main` function to `$DIR/inside-adt.rs` + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/associated-type-bounds/lcsit.rs b/src/test/ui/associated-type-bounds/lcsit.rs new file mode 100644 index 00000000000..85b6e804b4e --- /dev/null +++ b/src/test/ui/associated-type-bounds/lcsit.rs @@ -0,0 +1,78 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] + +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: impl Copy + Tr1 = { + let x: impl Copy + Tr1 = S1; + x +}; +static sdef_et1: impl Copy + Tr1 = cdef_et1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: impl Tr1 = { + let x: impl Tr1 = S1; + x +}; +static sdef_et2: impl Tr1 = cdef_et2; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: impl Tr1>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x: impl Tr1>>> = A; + x +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: impl Copy + Tr1 Tr2<'a>> = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x: impl Copy + Tr1 Tr2<'a>> = A; + x +}; + +static sdef_et4: impl Copy + Tr1 Tr2<'a>> = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs new file mode 100644 index 00000000000..25c2c2916f3 --- /dev/null +++ b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs @@ -0,0 +1,25 @@ +// compile-fail + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; + +trait Lam { type App; } + +fn nested_bounds<_0, _1, _2, D>() +where + D: Clone + Iterator Iterator Lam<&'a &'b u8, App = _0>>>, + //~^ ERROR nested quantification of lifetimes [E0316] + _0: Debug, +{} + +fn nested_bounds_desugared<_0, _1, _2, D>() +where + D: Clone + Iterator, + _2: Send + for<'a> Iterator, + for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, + //~^ ERROR nested quantification of lifetimes [E0316] + _0: Debug, +{} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr new file mode 100644 index 00000000000..44fa9e89d35 --- /dev/null +++ b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr @@ -0,0 +1,9 @@ +error[E0316]: nested quantification of lifetimes + --> $DIR/nested-lifetime-bounds.rs:20:37 + | +LL | for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0316`. diff --git a/src/test/ui/associated-type-bounds/rpit.rs b/src/test/ui/associated-type-bounds/rpit.rs new file mode 100644 index 00000000000..7b640d5a457 --- /dev/null +++ b/src/test/ui/associated-type-bounds/rpit.rs @@ -0,0 +1,64 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +fn def_et1() -> impl Tr1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> impl Tr1 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> impl Tr1>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} + +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +fn def_et4() -> impl Tr1 Tr2<'a>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} + +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/struct-bounds.rs b/src/test/ui/associated-type-bounds/struct-bounds.rs new file mode 100644 index 00000000000..2d189cd6672 --- /dev/null +++ b/src/test/ui/associated-type-bounds/struct-bounds.rs @@ -0,0 +1,115 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 {} +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 {} +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +struct St1> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +fn unwrap_1_st1>(x: St1) -> (T, T::As1, ::As2) { + (x.outest, x.outer, x.inner) +} + +fn unwrap_2_st1(x: St1) -> (T, T::As1, ::As2) +where + T: Tr1, + T::As1: Tr2, +{ + unwrap_1_st1(x) +} + +struct St2>> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +struct St3> { + outest: T, + outer: &'static T::As1, +} + +struct St4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +struct St5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +struct St6 +where + T: Tr1, +{ + f0: T, + f1: ::As2, + f2: &'static T::As1, + f3: ::As5, +} + +struct St7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + f0: &'a T, + f1: &'b ::As2, +} + +fn _use_st7<'a, 'b, T>(x: St7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +struct StSelf where Self: Tr1 { + f2: <::As1 as Tr2>::As2, +} + +impl Tr1 for StSelf<&'static str> { type As1 = bool; } + +fn main() { + let st1 = St1 { outest: "foo", outer: true, inner: 42u8 }; + assert_eq!(("foo", true, 42), unwrap_1_st1(st1)); + + let _ = St2 { outest: "foo", outer: true, inner: 42u8 }; + + let _ = St3 { outest: "foo", outer: &true }; + + let f1 = (1,); + let f2 = (2,); + let st4 = St4::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st4.f1, st4.f2)); + + // FIXME: requires lazy normalization. + /* + let f1 = (1,); + let f2 = (2,); + let st5 = St5::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st5.f1, st5.f2)); + */ + + let st6 = St6 { f0: "bar", f1: 24u8, f2: &true, f3: 12u16, }; + assert_eq!(("bar", 24, &true, 12), (st6.f0, st6.f1, st6.f2, st6.f3)); + + let stself = StSelf::<&'static str> { f2: 42u8 }; + assert_eq!(stself.f2, 42u8); +} diff --git a/src/test/ui/associated-type-bounds/trait-params.rs b/src/test/ui/associated-type-bounds/trait-params.rs new file mode 100644 index 00000000000..a9081d50cfc --- /dev/null +++ b/src/test/ui/associated-type-bounds/trait-params.rs @@ -0,0 +1,116 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +use std::iter::Once; +use std::ops::Range; + +pub trait Three { type A; type B; type C; } +pub fn assert_three() {} +pub fn assert_iterator() {} +pub fn assert_copy() {} +pub fn assert_static() {} +pub fn assert_send() {} +pub fn assert_forall_into Into<&'a u8>>() {} + +struct A; struct B; +impl<'a> Into<&'a u8> for A { fn into(self) -> &'a u8 { &0 } } +impl Three for B { type A = Range; type B = Range; type C = Range; } + +trait Case1 +where + A: Iterator, + B: Iterator, + C: Iterator, + D: Iterator Into<&'a u8>>, + E: Three, B: Iterator, C: Iterator>, + Self: Three, +{ + fn _a() { + assert_iterator::(); + assert_copy::(); + } + fn _b() { + assert_iterator::(); + assert_static::(); + } + fn _c() { + assert_iterator::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } + fn _d() { + assert_iterator::(); + assert_forall_into::(); + } + fn _e() { + assert_three::(); + assert_iterator::(); + assert_iterator::(); + assert_iterator::(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + } + fn _self() { + assert_three::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } +} + +struct DataCase1; +impl Three for DataCase1 { type A = u8; type B = u8; type C = u8; } +impl Case1, Range, Range, Once, B> for DataCase1 {} + +trait Case2< + A: Iterator, + B: Iterator, + C: Iterator, + D: Iterator Into<&'a u8>>, + E: Three, B: Iterator, C: Iterator>, +>: + Three +{ + fn _a() { + assert_iterator::(); + assert_copy::(); + } + fn _b() { + assert_iterator::(); + assert_static::(); + } + fn _c() { + assert_iterator::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } + fn _d() { + assert_iterator::(); + assert_forall_into::(); + } + fn _e() { + assert_three::(); + assert_iterator::(); + assert_iterator::(); + assert_iterator::(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + } + fn _self() { + assert_three::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } +} + +struct DataCase2; +impl Three for DataCase2 { type A = u8; type B = u8; type C = u8; } +impl Case2, Range, Range, Once, B> for DataCase2 {} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/type-alias.rs b/src/test/ui/associated-type-bounds/type-alias.rs new file mode 100644 index 00000000000..1602fdd275a --- /dev/null +++ b/src/test/ui/associated-type-bounds/type-alias.rs @@ -0,0 +1,19 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +type _TaWhere1 where T: Iterator = T; +type _TaWhere2 where T: Iterator = T; +type _TaWhere3 where T: Iterator = T; +type _TaWhere4 where T: Iterator = T; +type _TaWhere5 where T: Iterator Into<&'a u8>> = T; +type _TaWhere6 where T: Iterator> = T; + +type _TaInline1> = T; +type _TaInline2> = T; +type _TaInline3> = T; +type _TaInline4> = T; +type _TaInline5 Into<&'a u8>>> = T; +type _TaInline6>> = T; + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/type-alias.stderr b/src/test/ui/associated-type-bounds/type-alias.stderr new file mode 100644 index 00000000000..b93fc393ae3 --- /dev/null +++ b/src/test/ui/associated-type-bounds/type-alias.stderr @@ -0,0 +1,97 @@ +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:5:25 + | +LL | type _TaWhere1 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(type_alias_bounds)] on by default + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:6:25 + | +LL | type _TaWhere2 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:7:25 + | +LL | type _TaWhere3 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:8:25 + | +LL | type _TaWhere4 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:9:25 + | +LL | type _TaWhere5 where T: Iterator Into<&'a u8>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:10:25 + | +LL | type _TaWhere6 where T: Iterator> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:12:20 + | +LL | type _TaInline1> = T; + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:13:20 + | +LL | type _TaInline2> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:14:20 + | +LL | type _TaInline3> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:15:20 + | +LL | type _TaInline4> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:16:20 + | +LL | type _TaInline5 Into<&'a u8>>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:17:20 + | +LL | type _TaInline6>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + diff --git a/src/test/ui/associated-type-bounds/union-bounds.rs b/src/test/ui/associated-type-bounds/union-bounds.rs new file mode 100644 index 00000000000..ce482fff401 --- /dev/null +++ b/src/test/ui/associated-type-bounds/union-bounds.rs @@ -0,0 +1,123 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +#![allow(unions_with_drop_fields, unused_assignments)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +union Un1> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +union Un2>> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +union Un3> { + outest: T, + outer: &'static T::As1, +} + +union Un4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +union _Un5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +union Un6 +where + T: Tr1, +{ + f0: T, + f1: ::As2, + f2: &'static T::As1, + f3: ::As5, +} + +union _Un7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + f0: &'a T, + f1: &'b ::As2, +} + +unsafe fn _use_un7<'a, 'b, T>(x: _Un7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +union UnSelf where Self: Tr1 { + f0: T, + f1: ::As1, + f2: <::As1 as Tr2>::As2, +} + +impl Tr1 for UnSelf<&'static str> { type As1 = bool; } + +fn main() { + let mut un1 = Un1 { outest: "foo" }; + un1 = Un1 { outer: true }; + assert_eq!(unsafe { un1.outer }, true); + un1 = Un1 { inner: 42u8 }; + assert_eq!(unsafe { un1.inner }, 42u8); + + let mut un2 = Un2 { outest: "bar" }; + assert_eq!(unsafe { un2.outest }, "bar"); + un2 = Un2 { outer: true }; + assert_eq!(unsafe { un2.outer }, true); + un2 = Un2 { inner: 42u8 }; + assert_eq!(unsafe { un2.inner }, 42u8); + + let mut un3 = Un3 { outest: "baz" }; + assert_eq!(unsafe { un3.outest }, "baz"); + un3 = Un3 { outer: &true }; + assert_eq!(unsafe { *un3.outer }, true); + + let f1 = (1,); + let f2 = (2,); + let mut un4 = Un4::<()> { f1: &f1.0 }; + assert_eq!(1, unsafe { *un4.f1 }); + un4 = Un4 { f2: &f2.0 }; + assert_eq!(2, unsafe { *un4.f2 }); + + let mut un6 = Un6 { f0: "bar" }; + assert_eq!(unsafe { un6.f0 }, "bar"); + un6 = Un6 { f1: 24u8 }; + assert_eq!(unsafe { un6.f1 }, 24u8); + un6 = Un6 { f2: &true }; + assert_eq!(unsafe { un6.f2 }, &true); + un6 = Un6 { f3: 12u16 }; + assert_eq!(unsafe { un6.f3 }, 12u16); + + let mut unself = UnSelf::<_> { f0: "selfish" }; + assert_eq!(unsafe { unself.f0 }, "selfish"); + unself = UnSelf { f1: true }; + assert_eq!(unsafe { unself.f1 }, true); + unself = UnSelf { f2: 24u8 }; + assert_eq!(unsafe { unself.f2 }, 24u8); +} diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs new file mode 100644 index 00000000000..6b4f5005d48 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -0,0 +1,71 @@ +#![feature(untagged_unions)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; } + +trait _Tr3 { + type A: Iterator; + //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + + type B: Iterator; + //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +} + +struct _St1> { +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + outest: T, + outer: T::As1, + inner: ::As2, +} + +enum _En1> { +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + Outest(T), + Outer(T::As1), + Inner(::As2), +} + +union _Un1> { +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + outest: T, + outer: T::As1, + inner: ::As2, +} + +type _TaWhere1 where T: Iterator = T; +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + +fn _apit(_: impl Tr1) {} +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +fn _apit_dyn(_: &dyn Tr1) {} +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + +fn _rpit() -> impl Tr1 { S1 } +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +fn _rpit_dyn() -> Box> { Box::new(S1) } +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + +const _cdef: impl Tr1 = S1; +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// const _cdef_dyn: &dyn Tr1 = &S1; + +static _sdef: impl Tr1 = S1; +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// static _sdef_dyn: &dyn Tr1 = &S1; + +fn main() { + let _: impl Tr1 = S1; + //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] + // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. + // let _: &dyn Tr1 = &S1; +} diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr new file mode 100644 index 00000000000..9b83c1cfb33 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -0,0 +1,132 @@ +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:12:22 + | +LL | type A: Iterator; + | ^^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:15:22 + | +LL | type B: Iterator; + | ^^^^^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:19:20 + | +LL | struct _St1> { + | ^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:26:18 + | +LL | enum _En1> { + | ^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:33:19 + | +LL | union _Un1> { + | ^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:40:37 + | +LL | type _TaWhere1 where T: Iterator = T; + | ^^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:43:22 + | +LL | fn _apit(_: impl Tr1) {} + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:45:26 + | +LL | fn _apit_dyn(_: &dyn Tr1) {} + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:48:24 + | +LL | fn _rpit() -> impl Tr1 { S1 } + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:50:31 + | +LL | fn _rpit_dyn() -> Box> { Box::new(S1) } + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:53:23 + | +LL | const _cdef: impl Tr1 = S1; + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:59:24 + | +LL | static _sdef: impl Tr1 = S1; + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:66:21 + | +LL | let _: impl Tr1 = S1; + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:53:14 + | +LL | const _cdef: impl Tr1 = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:59:15 + | +LL | static _sdef: impl Tr1 = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:66:12 + | +LL | let _: impl Tr1 = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error: aborting due to 16 previous errors + +Some errors occurred: E0562, E0658. +For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr index c0ff56d5ec0..177e5f893ed 100644 --- a/src/test/ui/type/type-alias-bounds.stderr +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -1,13 +1,3 @@ -warning: duplicate auto trait `::marker[0]::Send[0]` found in type parameter bounds - --> $DIR/type-alias-bounds.rs:8:14 - | -LL | type SVec = Vec; - | ^^^^ ^^^^ subsequent use of auto trait - | | - | first use of auto trait - | - = note: #[warn(duplicate_auto_traits_in_bounds)] on by default - warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:8:14 |