From a4b7ed7a42c716ab9f05e351f003d589124fd55d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:58 +0200 Subject: Adding upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- .../ambiguous-associated-type.rs | 12 + .../ambiguous-associated-type2.rs | 10 + .../ambiguous-associated-type2.stderr | 16 + .../assoc-type-bound-through-where-clause.rs | 16 + .../assoc-type-eq-with-dyn-atb-fail.rs | 36 ++ .../assoc-type-eq-with-dyn-atb-fail.stderr | 9 + .../associated-item-through-where-clause.rs | 21 + .../ui/associated-type-bounds/auxiliary/fn-aux.rs | 177 +++++++ .../associated-type-bounds/auxiliary/fn-dyn-aux.rs | 182 ++++++++ .../bad-bounds-on-assoc-in-trait.rs | 67 +++ .../bad-bounds-on-assoc-in-trait.stderr | 39 ++ tests/ui/associated-type-bounds/binder-on-bound.rs | 9 + .../associated-type-bounds/binder-on-bound.stderr | 8 + .../bounds-on-assoc-in-trait.rs | 54 +++ .../bounds-on-assoc-in-trait.stderr | 26 ++ .../const-projection-err.gce.stderr | 24 + .../associated-type-bounds/const-projection-err.rs | 18 + .../const-projection-err.stock.stderr | 17 + tests/ui/associated-type-bounds/duplicate.rs | 259 +++++++++++ tests/ui/associated-type-bounds/duplicate.stderr | 507 +++++++++++++++++++++ .../associated-type-bounds/dyn-impl-trait-type.rs | 66 +++ .../ui/associated-type-bounds/dyn-rpit-and-let.rs | 73 +++ tests/ui/associated-type-bounds/elision.rs | 9 + tests/ui/associated-type-bounds/elision.stderr | 28 ++ .../entails-sized-object-safety.rs | 26 ++ tests/ui/associated-type-bounds/enum-bounds.rs | 123 +++++ tests/ui/associated-type-bounds/fn-apit.rs | 59 +++ tests/ui/associated-type-bounds/fn-aux.rs | 12 + tests/ui/associated-type-bounds/fn-dyn-apit.rs | 61 +++ tests/ui/associated-type-bounds/fn-inline.rs | 63 +++ tests/ui/associated-type-bounds/fn-where.rs | 79 ++++ tests/ui/associated-type-bounds/fn-wrap-apit.rs | 65 +++ ...handle-predicates-that-can-define-assoc-type.rs | 10 + tests/ui/associated-type-bounds/hrtb.rs | 65 +++ .../implied-region-constraints.rs | 45 ++ .../implied-region-constraints.stderr | 28 ++ tests/ui/associated-type-bounds/inside-adt.rs | 30 ++ tests/ui/associated-type-bounds/inside-adt.stderr | 131 ++++++ tests/ui/associated-type-bounds/issue-102335-ty.rs | 12 + .../associated-type-bounds/issue-102335-ty.stderr | 9 + tests/ui/associated-type-bounds/issue-61752.rs | 24 + tests/ui/associated-type-bounds/issue-70292.rs | 21 + tests/ui/associated-type-bounds/issue-71443-1.rs | 9 + .../ui/associated-type-bounds/issue-71443-1.stderr | 11 + tests/ui/associated-type-bounds/issue-71443-2.rs | 11 + tests/ui/associated-type-bounds/issue-73818.rs | 25 + tests/ui/associated-type-bounds/issue-79949.rs | 25 + tests/ui/associated-type-bounds/issue-81193.rs | 15 + tests/ui/associated-type-bounds/issue-83017.rs | 39 ++ tests/ui/associated-type-bounds/issue-99828.rs | 11 + tests/ui/associated-type-bounds/issue-99828.stderr | 21 + .../missing-trait-bound-for-assoc-fails.rs | 10 + .../missing-trait-bound-for-assoc-fails.stderr | 16 + .../order-dependent-bounds-issue-54121.rs | 47 ++ tests/ui/associated-type-bounds/rpit.rs | 64 +++ tests/ui/associated-type-bounds/struct-bounds.rs | 116 +++++ .../supertrait-referencing-self.rs | 12 + .../supertrait-referencing.rs | 19 + .../supertrait-where-referencing-self.rs | 27 ++ .../trait-alias-impl-trait.rs | 96 ++++ tests/ui/associated-type-bounds/trait-params.rs | 116 +++++ .../traits-assoc-anonymized.rs | 33 ++ .../traits-assoc-type-macros.rs | 43 ++ tests/ui/associated-type-bounds/type-alias.rs | 19 + tests/ui/associated-type-bounds/type-alias.stderr | 147 ++++++ tests/ui/associated-type-bounds/union-bounds.rs | 123 +++++ 66 files changed, 3601 insertions(+) create mode 100644 tests/ui/associated-type-bounds/ambiguous-associated-type.rs create mode 100644 tests/ui/associated-type-bounds/ambiguous-associated-type2.rs create mode 100644 tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr create mode 100644 tests/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs create mode 100644 tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs create mode 100644 tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr create mode 100644 tests/ui/associated-type-bounds/associated-item-through-where-clause.rs create mode 100644 tests/ui/associated-type-bounds/auxiliary/fn-aux.rs create mode 100644 tests/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs create mode 100644 tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs create mode 100644 tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr create mode 100644 tests/ui/associated-type-bounds/binder-on-bound.rs create mode 100644 tests/ui/associated-type-bounds/binder-on-bound.stderr create mode 100644 tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs create mode 100644 tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr create mode 100644 tests/ui/associated-type-bounds/const-projection-err.gce.stderr create mode 100644 tests/ui/associated-type-bounds/const-projection-err.rs create mode 100644 tests/ui/associated-type-bounds/const-projection-err.stock.stderr create mode 100644 tests/ui/associated-type-bounds/duplicate.rs create mode 100644 tests/ui/associated-type-bounds/duplicate.stderr create mode 100644 tests/ui/associated-type-bounds/dyn-impl-trait-type.rs create mode 100644 tests/ui/associated-type-bounds/dyn-rpit-and-let.rs create mode 100644 tests/ui/associated-type-bounds/elision.rs create mode 100644 tests/ui/associated-type-bounds/elision.stderr create mode 100644 tests/ui/associated-type-bounds/entails-sized-object-safety.rs create mode 100644 tests/ui/associated-type-bounds/enum-bounds.rs create mode 100644 tests/ui/associated-type-bounds/fn-apit.rs create mode 100644 tests/ui/associated-type-bounds/fn-aux.rs create mode 100644 tests/ui/associated-type-bounds/fn-dyn-apit.rs create mode 100644 tests/ui/associated-type-bounds/fn-inline.rs create mode 100644 tests/ui/associated-type-bounds/fn-where.rs create mode 100644 tests/ui/associated-type-bounds/fn-wrap-apit.rs create mode 100644 tests/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs create mode 100644 tests/ui/associated-type-bounds/hrtb.rs create mode 100644 tests/ui/associated-type-bounds/implied-region-constraints.rs create mode 100644 tests/ui/associated-type-bounds/implied-region-constraints.stderr create mode 100644 tests/ui/associated-type-bounds/inside-adt.rs create mode 100644 tests/ui/associated-type-bounds/inside-adt.stderr create mode 100644 tests/ui/associated-type-bounds/issue-102335-ty.rs create mode 100644 tests/ui/associated-type-bounds/issue-102335-ty.stderr create mode 100644 tests/ui/associated-type-bounds/issue-61752.rs create mode 100644 tests/ui/associated-type-bounds/issue-70292.rs create mode 100644 tests/ui/associated-type-bounds/issue-71443-1.rs create mode 100644 tests/ui/associated-type-bounds/issue-71443-1.stderr create mode 100644 tests/ui/associated-type-bounds/issue-71443-2.rs create mode 100644 tests/ui/associated-type-bounds/issue-73818.rs create mode 100644 tests/ui/associated-type-bounds/issue-79949.rs create mode 100644 tests/ui/associated-type-bounds/issue-81193.rs create mode 100644 tests/ui/associated-type-bounds/issue-83017.rs create mode 100644 tests/ui/associated-type-bounds/issue-99828.rs create mode 100644 tests/ui/associated-type-bounds/issue-99828.stderr create mode 100644 tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs create mode 100644 tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr create mode 100644 tests/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs create mode 100644 tests/ui/associated-type-bounds/rpit.rs create mode 100644 tests/ui/associated-type-bounds/struct-bounds.rs create mode 100644 tests/ui/associated-type-bounds/supertrait-referencing-self.rs create mode 100644 tests/ui/associated-type-bounds/supertrait-referencing.rs create mode 100644 tests/ui/associated-type-bounds/supertrait-where-referencing-self.rs create mode 100644 tests/ui/associated-type-bounds/trait-alias-impl-trait.rs create mode 100644 tests/ui/associated-type-bounds/trait-params.rs create mode 100644 tests/ui/associated-type-bounds/traits-assoc-anonymized.rs create mode 100644 tests/ui/associated-type-bounds/traits-assoc-type-macros.rs create mode 100644 tests/ui/associated-type-bounds/type-alias.rs create mode 100644 tests/ui/associated-type-bounds/type-alias.stderr create mode 100644 tests/ui/associated-type-bounds/union-bounds.rs (limited to 'tests/ui/associated-type-bounds') diff --git a/tests/ui/associated-type-bounds/ambiguous-associated-type.rs b/tests/ui/associated-type-bounds/ambiguous-associated-type.rs new file mode 100644 index 000000000..9c47a003d --- /dev/null +++ b/tests/ui/associated-type-bounds/ambiguous-associated-type.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(associated_type_bounds)] + +pub struct Flatten +where + I: Iterator, +{ + inner: ::IntoIter, +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs b/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs new file mode 100644 index 000000000..48de59334 --- /dev/null +++ b/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs @@ -0,0 +1,10 @@ +trait Foo { + type Item; +} +trait Bar { + type Item; +} +trait Baz: Foo + Bar {} +//~^ ERROR cycle detected when computing the super traits of `Baz` with associated type name `Item` [E0391] + +fn main() {} diff --git a/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr b/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr new file mode 100644 index 000000000..4162cdaa8 --- /dev/null +++ b/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr @@ -0,0 +1,16 @@ +error[E0391]: cycle detected when computing the super traits of `Baz` with associated type name `Item` + --> $DIR/ambiguous-associated-type2.rs:7:1 + | +LL | trait Baz: Foo + Bar {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: ...which immediately requires computing the super traits of `Baz` with associated type name `Item` again +note: cycle used when computing the super traits of `Baz` + --> $DIR/ambiguous-associated-type2.rs:7:1 + | +LL | trait Baz: Foo + Bar {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs b/tests/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs new file mode 100644 index 000000000..49f111407 --- /dev/null +++ b/tests/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs @@ -0,0 +1,16 @@ +// Check that `where Self::Output: Copy` is turned into a bound on `Op::Output`. + +//check-pass + +trait Op +where + Self::Output: Copy, +{ + type Output; +} + +fn duplicate(x: T::Output) -> (T::Output, T::Output) { + (x, x) +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs new file mode 100644 index 000000000..4c36289f4 --- /dev/null +++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs @@ -0,0 +1,36 @@ +// This test documents that `type Out = Box>;` +// is allowed and will correctly reject an opaque `type Out` which +// does not satisfy the bound `::Assoc: Copy`. +// +// FIXME(rust-lang/lang): I think this behavior is logical if we want to allow +// `dyn Trait` but we should decide if we want that. // Centril +// +// Additionally, as reported in https://github.com/rust-lang/rust/issues/63594, +// we check that the spans for the error message are sane here. + +#![feature(associated_type_bounds)] + +fn main() {} + +trait Bar { + type Assoc; +} + +trait Thing { + type Out; + fn func() -> Self::Out; +} + +struct AssocNoCopy; +impl Bar for AssocNoCopy { + type Assoc = String; +} + +impl Thing for AssocNoCopy { + type Out = Box>; + + fn func() -> Self::Out { + //~^ ERROR the trait bound `String: Copy` is not satisfied + Box::new(AssocNoCopy) + } +} diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr new file mode 100644 index 000000000..a32ab4531 --- /dev/null +++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:32:18 + | +LL | fn func() -> Self::Out { + | ^^^^^^^^^ the trait `Copy` is not implemented for `String` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-type-bounds/associated-item-through-where-clause.rs b/tests/ui/associated-type-bounds/associated-item-through-where-clause.rs new file mode 100644 index 000000000..3eb50ab55 --- /dev/null +++ b/tests/ui/associated-type-bounds/associated-item-through-where-clause.rs @@ -0,0 +1,21 @@ +// check-pass + +trait Foo { + type Item; +} + +trait Bar +where + Self: Foo, +{ +} + +#[allow(dead_code)] +fn foo(_m: M) +where + M: Bar, + M::Item: Send, +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/auxiliary/fn-aux.rs b/tests/ui/associated-type-bounds/auxiliary/fn-aux.rs new file mode 100644 index 000000000..0ea23ad1d --- /dev/null +++ b/tests/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/tests/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs b/tests/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs new file mode 100644 index 000000000..85d6c5aaf --- /dev/null +++ b/tests/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/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs new file mode 100644 index 000000000..d180de9be --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -0,0 +1,67 @@ +// 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>; + //~^ ERROR `<::C as Iterator>::Item` is not an iterator + //~| ERROR `<::C as Iterator>::Item` cannot be sent between threads safely + //~| ERROR `<::C as Iterator>::Item` cannot be shared between threads safely +} + +pub struct S1; +impl Case1 for S1 { + type C = Once>; +} + +fn assume_case1() { + 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/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr new file mode 100644 index 000000000..c23e54594 --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -0,0 +1,39 @@ +error[E0277]: `<::C as Iterator>::Item` cannot be sent between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:36 + | +LL | type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; + | ^^^^ `<::C as Iterator>::Item` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `<::C as Iterator>::Item` +help: consider further restricting the associated type + | +LL | trait Case1 where <::C as Iterator>::Item: Send { + | ++++++++++++++++++++++++++++++++++++++++++++++++++ + +error[E0277]: `<::C as Iterator>::Item` is not an iterator + --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:43 + | +LL | type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<::C as Iterator>::Item` is not an iterator + | + = help: the trait `Iterator` is not implemented for `<::C as Iterator>::Item` +help: consider further restricting the associated type + | +LL | trait Case1 where <::C as Iterator>::Item: Iterator { + | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +error[E0277]: `<::C as Iterator>::Item` cannot be shared between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:93 + | +LL | type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; + | ^^^^ `<::C as Iterator>::Item` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `<::C as Iterator>::Item` +help: consider further restricting the associated type + | +LL | trait Case1 where <::C as Iterator>::Item: Sync { + | ++++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-type-bounds/binder-on-bound.rs b/tests/ui/associated-type-bounds/binder-on-bound.rs new file mode 100644 index 000000000..6cba45129 --- /dev/null +++ b/tests/ui/associated-type-bounds/binder-on-bound.rs @@ -0,0 +1,9 @@ +trait Trait { + type Bound<'a>; +} + +fn foo() where Trait Bound<'a> = &'a ()> { + //~^ ERROR `for<...>` is not allowed on associated type bounds +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/binder-on-bound.stderr b/tests/ui/associated-type-bounds/binder-on-bound.stderr new file mode 100644 index 000000000..f71f72bfb --- /dev/null +++ b/tests/ui/associated-type-bounds/binder-on-bound.stderr @@ -0,0 +1,8 @@ +error: `for<...>` is not allowed on associated type bounds + --> $DIR/binder-on-bound.rs:5:22 + | +LL | fn foo() where Trait Bound<'a> = &'a ()> { + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs new file mode 100644 index 000000000..23be73501 --- /dev/null +++ b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs @@ -0,0 +1,54 @@ +#![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; + //~^ ERROR `<::A as Iterator>::Item` doesn't implement `Debug` + + type B: Iterator; +} + +pub struct S1; +impl Case1 for S1 { + type A = Empty; + type B = Range; +} + +// Ensure we don't have opaque `impl Trait` desugaring: + +// What is this supposed to mean? Rustc currently lowers `: Default` in the +// bounds of `Out`, but trait selection can't find the bound since it applies +// to a type other than `Self::Out`. +pub trait Foo { type Out: Baz; } +//~^ ERROR trait bound `<::Out as Baz>::Assoc: Default` is not satisfied +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/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr new file mode 100644 index 000000000..4e2313bd4 --- /dev/null +++ b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr @@ -0,0 +1,26 @@ +error[E0277]: `<::A as Iterator>::Item` doesn't implement `Debug` + --> $DIR/bounds-on-assoc-in-trait.rs:18:28 + | +LL | type A: Iterator; + | ^^^^^ `<::A as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `<::A as Iterator>::Item` +help: consider further restricting the associated type + | +LL | trait Case1 where <::A as Iterator>::Item: Debug { + | +++++++++++++++++++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `<::Out as Baz>::Assoc: Default` is not satisfied + --> $DIR/bounds-on-assoc-in-trait.rs:35:38 + | +LL | pub trait Foo { type Out: Baz; } + | ^^^^^^^ the trait `Default` is not implemented for `<::Out as Baz>::Assoc` + | +help: consider further restricting the associated type + | +LL | pub trait Foo where <::Out as Baz>::Assoc: Default { type Out: Baz; } + | +++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr b/tests/ui/associated-type-bounds/const-projection-err.gce.stderr new file mode 100644 index 000000000..0f1ec9ad0 --- /dev/null +++ b/tests/ui/associated-type-bounds/const-projection-err.gce.stderr @@ -0,0 +1,24 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-projection-err.rs:4:26 + | +LL | #![cfg_attr(gce, feature(generic_const_exprs))] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0271]: type mismatch resolving `::A == 1` + --> $DIR/const-projection-err.rs:14:11 + | +LL | foo::(); + | ^ expected `0`, found `1` + | +note: required by a bound in `foo` + --> $DIR/const-projection-err.rs:11:28 + | +LL | fn foo>() {} + | ^^^^^ required by this bound in `foo` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-type-bounds/const-projection-err.rs b/tests/ui/associated-type-bounds/const-projection-err.rs new file mode 100644 index 000000000..bead85630 --- /dev/null +++ b/tests/ui/associated-type-bounds/const-projection-err.rs @@ -0,0 +1,18 @@ +// revisions: stock gce + +#![feature(associated_const_equality)] +#![cfg_attr(gce, feature(generic_const_exprs))] +//[gce]~^ WARN the feature `generic_const_exprs` is incomplete + +trait TraitWAssocConst { + const A: usize; +} + +fn foo>() {} + +fn bar>() { + foo::(); + //~^ ERROR type mismatch resolving `::A == 1` +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr b/tests/ui/associated-type-bounds/const-projection-err.stock.stderr new file mode 100644 index 000000000..bf0824259 --- /dev/null +++ b/tests/ui/associated-type-bounds/const-projection-err.stock.stderr @@ -0,0 +1,17 @@ +error[E0271]: type mismatch resolving `::A == 1` + --> $DIR/const-projection-err.rs:14:11 + | +LL | foo::(); + | ^ expected `1`, found `::A` + | + = note: expected constant `1` + found constant `::A` +note: required by a bound in `foo` + --> $DIR/const-projection-err.rs:11:28 + | +LL | fn foo>() {} + | ^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs new file mode 100644 index 000000000..f67410986 --- /dev/null +++ b/tests/ui/associated-type-bounds/duplicate.rs @@ -0,0 +1,259 @@ +#![feature(associated_type_bounds)] +#![feature(type_alias_impl_trait)] + +use std::iter; +use std::mem::ManuallyDrop; + +struct SI1> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + f: T, +} +struct SI2> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + f: T, +} +struct SI3> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + f: T, +} +struct SW1 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + f: T, +} +struct SW2 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + f: T, +} +struct SW3 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + f: T, +} + +enum EI1> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + V(T), +} +enum EI2> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + V(T), +} +enum EI3> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + V(T), +} +enum EW1 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + V(T), +} +enum EW2 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + V(T), +} +enum EW3 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + V(T), +} + +union UI1> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + f: ManuallyDrop, +} +union UI2> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + f: ManuallyDrop, +} +union UI3> { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + f: ManuallyDrop, +} +union UW1 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + f: ManuallyDrop, +} +union UW2 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + f: ManuallyDrop, +} +union UW3 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ + f: ManuallyDrop, +} + +fn FI1>() {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +fn FI2>() {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +fn FI3>() {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +fn FW1() +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +fn FW2() +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +fn FW3() +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} + +fn FRPIT1() -> impl Iterator { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + iter::empty() +} +fn FRPIT2() -> impl Iterator { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + iter::empty() +} +fn FRPIT3() -> impl Iterator { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + iter::empty() +} +fn FAPIT1(_: impl Iterator) {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +fn FAPIT2(_: impl Iterator) {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +fn FAPIT3(_: impl Iterator) {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + +type TAI1> = T; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type TAI2> = T; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type TAI3> = T; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type TAW1 +where + T: Iterator, +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] += T; +type TAW2 +where + T: Iterator, +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] += T; +type TAW3 +where + T: Iterator, +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] += T; + +type ETAI1> = impl Copy; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type ETAI2> = impl Copy; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type ETAI3> = impl Copy; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type ETAI4 = impl Iterator; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type ETAI5 = impl Iterator; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type ETAI6 = impl Iterator; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + +trait TRI1> {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +trait TRI2> {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +trait TRI3> {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +trait TRS1: Iterator {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +trait TRS2: Iterator {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +trait TRS3: Iterator {} +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +trait TRW1 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +trait TRW2 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +trait TRW3 +where + T: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +trait TRSW1 +where + Self: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + //~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +trait TRSW2 +where + Self: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + //~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +trait TRSW3 +where + Self: Iterator, + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + //~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +{ +} +trait TRA1 { + type A: Iterator; + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +} +trait TRA2 { + type A: Iterator; + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +} +trait TRA3 { + type A: Iterator; + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +} + +type TADyn1 = dyn Iterator; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type TADyn2 = Box>; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +type TADyn3 = dyn Iterator; +//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] + +fn main() {} diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr new file mode 100644 index 000000000..c3061327f --- /dev/null +++ b/tests/ui/associated-type-bounds/duplicate.stderr @@ -0,0 +1,507 @@ +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:7:36 + | +LL | struct SI1> { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:11:36 + | +LL | struct SI2> { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:15:39 + | +LL | struct SI3> { + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:21:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:28:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:35:32 + | +LL | T: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:41:34 + | +LL | enum EI1> { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:45:34 + | +LL | enum EI2> { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:49:37 + | +LL | enum EI3> { + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:55:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:62:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:69:32 + | +LL | T: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:75:35 + | +LL | union UI1> { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:79:35 + | +LL | union UI2> { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:83:38 + | +LL | union UI3> { + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:89:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:96:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:103:32 + | +LL | T: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:109:32 + | +LL | fn FI1>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:111:32 + | +LL | fn FI2>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:113:35 + | +LL | fn FI3>() {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:117:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:123:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:129:32 + | +LL | T: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:134:42 + | +LL | fn FRPIT1() -> impl Iterator { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:138:42 + | +LL | fn FRPIT2() -> impl Iterator { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:142:45 + | +LL | fn FRPIT3() -> impl Iterator { + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:146:40 + | +LL | fn FAPIT1(_: impl Iterator) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:148:40 + | +LL | fn FAPIT2(_: impl Iterator) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:150:43 + | +LL | fn FAPIT3(_: impl Iterator) {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:153:35 + | +LL | type TAI1> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:155:35 + | +LL | type TAI2> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:157:38 + | +LL | type TAI3> = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:161:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:166:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:171:32 + | +LL | T: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:175:36 + | +LL | type ETAI1> = impl Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:177:36 + | +LL | type ETAI2> = impl Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:179:39 + | +LL | type ETAI3> = impl Copy; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:181:40 + | +LL | type ETAI4 = impl Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:183:40 + | +LL | type ETAI5 = impl Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:185:43 + | +LL | type ETAI6 = impl Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:188:36 + | +LL | trait TRI1> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:190:36 + | +LL | trait TRI2> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:192:39 + | +LL | trait TRI3> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:194:34 + | +LL | trait TRS1: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:196:34 + | +LL | trait TRS2: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:198:37 + | +LL | trait TRS3: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:202:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:208:29 + | +LL | T: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:214:32 + | +LL | T: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:220:32 + | +LL | Self: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:220:32 + | +LL | Self: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:227:32 + | +LL | Self: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:227:32 + | +LL | Self: Iterator, + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:234:35 + | +LL | Self: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:234:35 + | +LL | Self: Iterator, + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:252:40 + | +LL | type TADyn1 = dyn Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:254:44 + | +LL | type TADyn2 = Box>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:256:43 + | +LL | type TADyn3 = dyn Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:240:34 + | +LL | type A: Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:244:34 + | +LL | type A: Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:248:37 + | +LL | type A: Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: aborting due to 63 previous errors + +For more information about this error, try `rustc --explain E0719`. diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs new file mode 100644 index 000000000..a8d00803a --- /dev/null +++ b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs @@ -0,0 +1,66 @@ +// 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 } } + +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/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs new file mode 100644 index 000000000..08f965452 --- /dev/null +++ b/tests/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/tests/ui/associated-type-bounds/elision.rs b/tests/ui/associated-type-bounds/elision.rs new file mode 100644 index 000000000..d00def571 --- /dev/null +++ b/tests/ui/associated-type-bounds/elision.rs @@ -0,0 +1,9 @@ +#![feature(associated_type_bounds)] +#![feature(anonymous_lifetime_in_impl_trait)] + +// The same thing should happen for constraints in dyn trait. +fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } +//~^ ERROR missing lifetime specifier +//~| ERROR mismatched types + +fn main() {} diff --git a/tests/ui/associated-type-bounds/elision.stderr b/tests/ui/associated-type-bounds/elision.stderr new file mode 100644 index 000000000..ea3024627 --- /dev/null +++ b/tests/ui/associated-type-bounds/elision.stderr @@ -0,0 +1,28 @@ +error[E0106]: missing lifetime specifier + --> $DIR/elision.rs:5:70 + | +LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } + | ------------------------------------------------ ^^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `x`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime parameter + | +LL | fn f<'a>(x: &'a mut dyn Iterator>) -> Option<&'a ()> { x.next() } + | ++++ ++ ~~ ~~ + +error[E0308]: mismatched types + --> $DIR/elision.rs:5:79 + | +LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } + | ----------------------------- -------------- ^^^^^^^^ expected `&()`, found type parameter `impl Iterator` + | | | + | | expected `Option<&'static ()>` because of return type + | this type parameter + | + = note: expected enum `Option<&'static ()>` + found enum `Option>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0308. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/associated-type-bounds/entails-sized-object-safety.rs b/tests/ui/associated-type-bounds/entails-sized-object-safety.rs new file mode 100644 index 000000000..f5a9bac6e --- /dev/null +++ b/tests/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -0,0 +1,26 @@ +// build-pass (FIXME(62277): could be check-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/tests/ui/associated-type-bounds/enum-bounds.rs b/tests/ui/associated-type-bounds/enum-bounds.rs new file mode 100644 index 000000000..193f2efe1 --- /dev/null +++ b/tests/ui/associated-type-bounds/enum-bounds.rs @@ -0,0 +1,123 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![allow(dead_code)] + +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/tests/ui/associated-type-bounds/fn-apit.rs b/tests/ui/associated-type-bounds/fn-apit.rs new file mode 100644 index 000000000..3c9f51133 --- /dev/null +++ b/tests/ui/associated-type-bounds/fn-apit.rs @@ -0,0 +1,59 @@ +// run-pass +// aux-build:fn-aux.rs + +#![allow(unused)] +#![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/tests/ui/associated-type-bounds/fn-aux.rs b/tests/ui/associated-type-bounds/fn-aux.rs new file mode 100644 index 000000000..434bdbe99 --- /dev/null +++ b/tests/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/tests/ui/associated-type-bounds/fn-dyn-apit.rs b/tests/ui/associated-type-bounds/fn-dyn-apit.rs new file mode 100644 index 000000000..c4e8092c2 --- /dev/null +++ b/tests/ui/associated-type-bounds/fn-dyn-apit.rs @@ -0,0 +1,61 @@ +// run-pass +// aux-build:fn-dyn-aux.rs + +#![allow(unused)] +#![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/tests/ui/associated-type-bounds/fn-inline.rs b/tests/ui/associated-type-bounds/fn-inline.rs new file mode 100644 index 000000000..8fa7212d6 --- /dev/null +++ b/tests/ui/associated-type-bounds/fn-inline.rs @@ -0,0 +1,63 @@ +// run-pass +// aux-build:fn-aux.rs + +#![allow(unused)] +#![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/tests/ui/associated-type-bounds/fn-where.rs b/tests/ui/associated-type-bounds/fn-where.rs new file mode 100644 index 000000000..9c4f82ac9 --- /dev/null +++ b/tests/ui/associated-type-bounds/fn-where.rs @@ -0,0 +1,79 @@ +// run-pass +// aux-build:fn-aux.rs + +#![allow(unused)] +#![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/tests/ui/associated-type-bounds/fn-wrap-apit.rs b/tests/ui/associated-type-bounds/fn-wrap-apit.rs new file mode 100644 index 000000000..96df13e37 --- /dev/null +++ b/tests/ui/associated-type-bounds/fn-wrap-apit.rs @@ -0,0 +1,65 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] +#![allow(dead_code)] + +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/tests/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs b/tests/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs new file mode 100644 index 000000000..b1e54ec04 --- /dev/null +++ b/tests/ui/associated-type-bounds/handle-predicates-that-can-define-assoc-type.rs @@ -0,0 +1,10 @@ +// check-pass + +trait Foo {} +trait Bar { + type A; + type B; +} +trait Baz: Bar + Foo {} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/hrtb.rs b/tests/ui/associated-type-bounds/hrtb.rs new file mode 100644 index 000000000..7ab383649 --- /dev/null +++ b/tests/ui/associated-type-bounds/hrtb.rs @@ -0,0 +1,65 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait A<'a> {} +trait B<'b> {} +fn foo() +where + for<'a> T: A<'a> + 'a, +{ +} +trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { + type As; +} +struct D +where + T: for<'c> C<'c, As: A<'c>>, +{ + t: std::marker::PhantomData, +} + +trait E<'e> { + type As; +} +trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {} +struct G +where + for<'f> T: F<'f, As: E<'f>> + 'f, +{ + t: std::marker::PhantomData, +} + +trait I<'a, 'b, 'c> { + type As; +} +trait H<'d, 'e>: for<'f> I<'d, 'f, 'e> + 'd {} +fn foo2() +where + T: for<'g> H<'g, 'g, As: for<'h> H<'h, 'g> + 'g>, +{ +} + +fn foo3() +where + T: for<'i> H<'i, 'i, As: for<'j> H<'j, 'i, As: for<'k> I<'i, 'k, 'j> + 'j> + 'i>, +{ +} +fn foo4() +where + T: for<'l, 'i> H<'l, 'i, As: for<'j> H<'j, 'i, As: for<'k> I<'l, 'k, 'j> + 'j> + 'i>, +{ +} + +struct X<'x, 'y> { + x: std::marker::PhantomData<&'x ()>, + y: std::marker::PhantomData<&'y ()>, +} + +fn foo5() +where + T: for<'l, 'i> H<'l, 'i, As: for<'j> H<'j, 'i, As: for<'k> H<'j, 'k, As = X<'j, 'k>> + 'j> + 'i> +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/implied-region-constraints.rs b/tests/ui/associated-type-bounds/implied-region-constraints.rs new file mode 100644 index 000000000..38219da61 --- /dev/null +++ b/tests/ui/associated-type-bounds/implied-region-constraints.rs @@ -0,0 +1,45 @@ +#![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 may not live long enough +} + +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 may not live long enough + }, + En7::V1(_) => {}, + } +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/implied-region-constraints.stderr b/tests/ui/associated-type-bounds/implied-region-constraints.stderr new file mode 100644 index 000000000..cddce8777 --- /dev/null +++ b/tests/ui/associated-type-bounds/implied-region-constraints.stderr @@ -0,0 +1,28 @@ +error: lifetime may not live long enough + --> $DIR/implied-region-constraints.rs:17:56 + | +LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + | ^^^^^ type annotation requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + +error: lifetime may not live long enough + --> $DIR/implied-region-constraints.rs:38:64 + | +LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + | ^^^^^ type annotation requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs new file mode 100644 index 000000000..8eb8c44bb --- /dev/null +++ b/tests/ui/associated-type-bounds/inside-adt.rs @@ -0,0 +1,30 @@ +#![feature(associated_type_bounds)] + +use std::mem::ManuallyDrop; + +struct S1 { f: dyn Iterator } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +struct S2 { f: Box> } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +struct S3 { f: dyn Iterator } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions + +enum E1 { V(dyn Iterator) } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR the size for values of type `(dyn Iterator + 'static)` +enum E2 { V(Box>) } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +enum E3 { V(dyn Iterator) } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR the size for values of type `(dyn Iterator + 'static)` + +union U1 { f: ManuallyDrop> } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR the size for values of type `(dyn Iterator + 'static)` +union U2 { f: ManuallyDrop>> } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +union U3 { f: ManuallyDrop> } +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR the size for values of type `(dyn Iterator + 'static)` + +fn main() {} diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr new file mode 100644 index 000000000..dbfcfa580 --- /dev/null +++ b/tests/ui/associated-type-bounds/inside-adt.stderr @@ -0,0 +1,131 @@ +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:5:29 + | +LL | struct S1 { f: dyn Iterator } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:7:33 + | +LL | struct S2 { f: Box> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:9:29 + | +LL | struct S3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:12:26 + | +LL | enum E1 { V(dyn Iterator) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:15:30 + | +LL | enum E2 { V(Box>) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:17:26 + | +LL | enum E3 { V(dyn Iterator) } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:21:41 + | +LL | union U1 { f: ManuallyDrop> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:24:45 + | +LL | union U2 { f: ManuallyDrop>> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:26:41 + | +LL | union U3 { f: ManuallyDrop> } + | ^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time + --> $DIR/inside-adt.rs:12:13 + | +LL | enum E1 { V(dyn Iterator) } + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum E1 { V(&dyn Iterator) } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum E1 { V(Box>) } + | ++++ + + +error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time + --> $DIR/inside-adt.rs:17:13 + | +LL | enum E3 { V(dyn Iterator) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum E3 { V(&dyn Iterator) } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum E3 { V(Box>) } + | ++++ + + +error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time + --> $DIR/inside-adt.rs:21:15 + | +LL | union U1 { f: ManuallyDrop> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `ManuallyDrop<(dyn Iterator + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: required because it appears within the type `ManuallyDrop<(dyn Iterator + 'static)>` + = note: no field of a union may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | union U1 { f: &ManuallyDrop> } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | union U1 { f: Box>> } + | ++++ + + +error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time + --> $DIR/inside-adt.rs:26:15 + | +LL | union U3 { f: ManuallyDrop> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `ManuallyDrop<(dyn Iterator + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: required because it appears within the type `ManuallyDrop<(dyn Iterator + 'static)>` + = note: no field of a union may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | union U3 { f: &ManuallyDrop> } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | union U3 { f: Box>> } + | ++++ + + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.rs b/tests/ui/associated-type-bounds/issue-102335-ty.rs new file mode 100644 index 000000000..363df73c1 --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-102335-ty.rs @@ -0,0 +1,12 @@ +trait T { + type A: S = ()>; + //~^ ERROR associated type bindings are not allowed here +} + +trait Q {} + +trait S { + type C: Q; +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.stderr b/tests/ui/associated-type-bounds/issue-102335-ty.stderr new file mode 100644 index 000000000..8777b2965 --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-102335-ty.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-102335-ty.rs:2:17 + | +LL | type A: S = ()>; + | ^^^^^^^^^ associated type not allowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/ui/associated-type-bounds/issue-61752.rs b/tests/ui/associated-type-bounds/issue-61752.rs new file mode 100644 index 000000000..f38ec640e --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-61752.rs @@ -0,0 +1,24 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait Foo { + type Bar; +} + +impl Foo for () { + type Bar = (); +} + +fn a() where F::Bar: Copy {} + +fn b() where ::Bar: Copy {} + +// This used to complain about ambiguous associated types. +fn c>() where F::Bar: Copy {} + +fn main() { + a::<()>(); + b::<()>(); + c::<()>(); +} diff --git a/tests/ui/associated-type-bounds/issue-70292.rs b/tests/ui/associated-type-bounds/issue-70292.rs new file mode 100644 index 000000000..945d7688c --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-70292.rs @@ -0,0 +1,21 @@ +// check-pass + +#![feature(associated_type_bounds)] + +fn foo(_: F) +where + F: for<'a> Trait, +{ +} + +trait Trait { + type Output; +} + +impl Trait for T { + type Output = (); +} + +fn main() { + foo(()); +} diff --git a/tests/ui/associated-type-bounds/issue-71443-1.rs b/tests/ui/associated-type-bounds/issue-71443-1.rs new file mode 100644 index 000000000..5d2a3e6cb --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-71443-1.rs @@ -0,0 +1,9 @@ +#![feature(associated_type_bounds)] + +struct Incorrect; + +fn hello Iterator>() { + Incorrect //~ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/issue-71443-1.stderr b/tests/ui/associated-type-bounds/issue-71443-1.stderr new file mode 100644 index 000000000..a9459ee74 --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-71443-1.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-71443-1.rs:6:5 + | +LL | fn hello Iterator>() { + | - help: try adding a return type: `-> Incorrect` +LL | Incorrect + | ^^^^^^^^^ expected `()`, found struct `Incorrect` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-type-bounds/issue-71443-2.rs b/tests/ui/associated-type-bounds/issue-71443-2.rs new file mode 100644 index 000000000..813dcd60a --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-71443-2.rs @@ -0,0 +1,11 @@ +// check-pass + +#![feature(associated_type_bounds)] + +fn hello<'b, F>() +where + for<'a> F: Iterator + 'b, +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/issue-73818.rs b/tests/ui/associated-type-bounds/issue-73818.rs new file mode 100644 index 000000000..bb890f72a --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-73818.rs @@ -0,0 +1,25 @@ +// Test that associated type bounds are correctly normalized when checking +// default associated type values. +// check-pass + +#![allow(incomplete_features)] +#![feature(specialization)] + +#[derive(PartialEq)] +enum Never {} +trait Foo { + type Assoc: PartialEq; // PartialEq<::Assoc> +} +impl Foo for T { + default type Assoc = Never; +} + +trait Trait1 { + type Selection: PartialEq; +} +trait Trait2: PartialEq {} +impl Trait1 for T { + default type Selection = T; +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/issue-79949.rs b/tests/ui/associated-type-bounds/issue-79949.rs new file mode 100644 index 000000000..9dd37f981 --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-79949.rs @@ -0,0 +1,25 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(associated_type_bounds)] + +trait MP { + type T<'a>; +} +struct S(String); +impl MP for S { + type T<'a> = &'a str; +} + +trait SR: MP { + fn sr(&self) -> i32 + where + for<'a> IM: T::T<'a>>>; +} + +trait T { + type T; +} +trait U {} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/issue-81193.rs b/tests/ui/associated-type-bounds/issue-81193.rs new file mode 100644 index 000000000..d2aa54ab9 --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-81193.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait A<'a, 'b> {} + +trait B<'a, 'b, 'c> {} + +fn err<'u, 'a, F>() +where + for<'b> F: Iterator B<'a, 'b, 'c> + for<'c> A<'a, 'c>>, +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/issue-83017.rs b/tests/ui/associated-type-bounds/issue-83017.rs new file mode 100644 index 000000000..a02208661 --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-83017.rs @@ -0,0 +1,39 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait TraitA<'a> { + type AsA; +} + +trait TraitB<'a, 'b> { + type AsB; +} + +trait TraitC<'a, 'b, 'c> {} + +struct X; + +impl<'a, 'b, 'c> TraitC<'a, 'b, 'c> for X {} + +struct Y; + +impl<'a, 'b> TraitB<'a, 'b> for Y { + type AsB = X; +} + +struct Z; + +impl<'a> TraitA<'a> for Z { + type AsA = Y; +} + +fn foo() +where + for<'a> T: TraitA<'a, AsA: for<'b> TraitB<'a, 'b, AsB: for<'c> TraitC<'a, 'b, 'c>>>, +{ +} + +fn main() { + foo::(); +} diff --git a/tests/ui/associated-type-bounds/issue-99828.rs b/tests/ui/associated-type-bounds/issue-99828.rs new file mode 100644 index 000000000..7b711283f --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-99828.rs @@ -0,0 +1,11 @@ +fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + //~^ ERROR expected associated type bound, found constant + //~| ERROR associated const equality is incomplete + vec.iter() +} + +fn main() { + let vec = Vec::new(); + let mut iter = get_iter(&vec); + iter.next(); +} diff --git a/tests/ui/associated-type-bounds/issue-99828.stderr b/tests/ui/associated-type-bounds/issue-99828.stderr new file mode 100644 index 000000000..dc93c47da --- /dev/null +++ b/tests/ui/associated-type-bounds/issue-99828.stderr @@ -0,0 +1,21 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/issue-99828.rs:1:43 + | +LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + | ^^^^^^^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error: expected associated type bound, found constant + --> $DIR/issue-99828.rs:1:43 + | +LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + | ^^^^^^^^^ + | +note: associated type defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs new file mode 100644 index 000000000..07d0f8f87 --- /dev/null +++ b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs @@ -0,0 +1,10 @@ +#[allow(dead_code)] +fn foo(_m: M) +where + M::Item: Temp, + //~^ ERROR cannot find trait `Temp` in this scope [E0405] + //~| ERROR associated type `Item` not found for `M` [E0220] +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr new file mode 100644 index 000000000..bc2807b03 --- /dev/null +++ b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr @@ -0,0 +1,16 @@ +error[E0405]: cannot find trait `Temp` in this scope + --> $DIR/missing-trait-bound-for-assoc-fails.rs:4:14 + | +LL | M::Item: Temp, + | ^^^^ not found in this scope + +error[E0220]: associated type `Item` not found for `M` + --> $DIR/missing-trait-bound-for-assoc-fails.rs:4:8 + | +LL | M::Item: Temp, + | ^^^^ associated type `Item` not found + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0220, E0405. +For more information about an error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs b/tests/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs new file mode 100644 index 000000000..77e4bd4d6 --- /dev/null +++ b/tests/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs @@ -0,0 +1,47 @@ +// check-pass + +// From https://github.com/rust-lang/rust/issues/54121/ +// +// Whether the code compiled depended on the order of the trait bounds in +// `type T: Tr + Tr` +// But both should compile as order shouldn't matter. + +trait Tr { + fn exec(a: A, b: B); +} + +trait P { + // This compiled successfully + type T: Tr + Tr; +} + +trait Q { + // This didn't compile + type T: Tr + Tr; +} + +#[allow(dead_code)] +fn f() { + ::T::exec(0u8, 0u8) +} + +#[allow(dead_code)] +fn g() { + // A mismatched types error was emitted on this line. + ::T::exec(0u8, 0u8) +} + +// Another reproduction of the same issue +trait Trait { + type Type: Into + Into + Copy; + type Type1; + type Type2; +} + +#[allow(dead_code)] +fn foo(x: T::Type) { + let _1: T::Type1 = x.into(); + let _2: T::Type2 = x.into(); +} + +fn main() { } diff --git a/tests/ui/associated-type-bounds/rpit.rs b/tests/ui/associated-type-bounds/rpit.rs new file mode 100644 index 000000000..47cadf331 --- /dev/null +++ b/tests/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/tests/ui/associated-type-bounds/struct-bounds.rs b/tests/ui/associated-type-bounds/struct-bounds.rs new file mode 100644 index 000000000..2c1ce1c37 --- /dev/null +++ b/tests/ui/associated-type-bounds/struct-bounds.rs @@ -0,0 +1,116 @@ +// run-pass + +#![allow(unused)] +#![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/tests/ui/associated-type-bounds/supertrait-referencing-self.rs b/tests/ui/associated-type-bounds/supertrait-referencing-self.rs new file mode 100644 index 000000000..c82ec01f4 --- /dev/null +++ b/tests/ui/associated-type-bounds/supertrait-referencing-self.rs @@ -0,0 +1,12 @@ +// check-pass +trait Foo { + type Bar; +} +trait Qux: Foo + AsRef {} +trait Foo2 {} + +trait Qux2: Foo2 + AsRef { + type Bar; +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/supertrait-referencing.rs b/tests/ui/associated-type-bounds/supertrait-referencing.rs new file mode 100644 index 000000000..2e9753515 --- /dev/null +++ b/tests/ui/associated-type-bounds/supertrait-referencing.rs @@ -0,0 +1,19 @@ +// check-pass + +// The goal of this test is to ensure that T: Bar +// in the where clause does not cycle + +trait Foo { + type Item; +} + +trait Bar {} + +fn baz() +where + T: Foo, + T: Bar, +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/supertrait-where-referencing-self.rs b/tests/ui/associated-type-bounds/supertrait-where-referencing-self.rs new file mode 100644 index 000000000..72a6be9ff --- /dev/null +++ b/tests/ui/associated-type-bounds/supertrait-where-referencing-self.rs @@ -0,0 +1,27 @@ +// check-pass + +// Test that we do not get a cycle due to +// resolving `Self::Bar` in the where clauses +// on a trait definition (in particular, in +// a where clause that is defining a superpredicate). + +trait Foo { + type Bar; +} +trait Qux +where + Self: Foo, + Self: AsRef, +{ +} +trait Foo2 {} + +trait Qux2 +where + Self: Foo2, + Self: AsRef, +{ + type Bar; +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs new file mode 100644 index 000000000..e223a8957 --- /dev/null +++ b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs @@ -0,0 +1,96 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(type_alias_impl_trait)] + +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 = impl Tr1; +fn def_et1() -> Et1 { + S1 +} +pub fn use_et1() { + assert_copy(def_et1().mk()); +} + +type Et2 = impl Tr1; +fn def_et2() -> Et2 { + S1 +} +pub fn use_et2() { + assert_static(def_et2().mk()); +} + +type Et3 = impl 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()); +} + +type Et4 = impl 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/tests/ui/associated-type-bounds/trait-params.rs b/tests/ui/associated-type-bounds/trait-params.rs new file mode 100644 index 000000000..b0703a4ee --- /dev/null +++ b/tests/ui/associated-type-bounds/trait-params.rs @@ -0,0 +1,116 @@ +// build-pass (FIXME(62277): could be check-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/tests/ui/associated-type-bounds/traits-assoc-anonymized.rs b/tests/ui/associated-type-bounds/traits-assoc-anonymized.rs new file mode 100644 index 000000000..a9d6eed81 --- /dev/null +++ b/tests/ui/associated-type-bounds/traits-assoc-anonymized.rs @@ -0,0 +1,33 @@ +// check-pass + +pub struct LookupInternedStorage; + +impl QueryStorageOps for LookupInternedStorage +where + Q: Query, + for<'d> Q: QueryDb<'d>, +{ + fn fmt_index(&self, db: &>::DynDb) { + <>::DynDb as HasQueryGroup>::group_storage(db); + } +} + +pub trait HasQueryGroup { + fn group_storage(&self); +} + +pub trait QueryStorageOps +where + Q: Query, +{ + fn fmt_index(&self, db: &>::DynDb); +} + +pub trait QueryDb<'d> { + type DynDb: HasQueryGroup + 'd; + type Group; +} + +pub trait Query: for<'d> QueryDb<'d> {} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/traits-assoc-type-macros.rs b/tests/ui/associated-type-bounds/traits-assoc-type-macros.rs new file mode 100644 index 000000000..d854dce38 --- /dev/null +++ b/tests/ui/associated-type-bounds/traits-assoc-type-macros.rs @@ -0,0 +1,43 @@ +// check-pass +// incremental + +// This test case makes sure that we can compile with incremental compilation +// enabled when there are macros, traits, inheritance and associated types involved. + +trait Deserializer { + type Error; +} + +trait Deserialize { + fn deserialize(_: D) -> D::Error + where + D: Deserializer; +} + +macro_rules! impl_deserialize { + ($name:ident) => { + impl Deserialize for $name { + fn deserialize(_: D) -> D::Error + where + D: Deserializer, + { + loop {} + } + } + }; +} + +macro_rules! formats { + { + $($name:ident,)* + } => { + $( + pub struct $name; + + impl_deserialize!($name); + )* + } +} +formats! { Foo, Bar, } + +fn main() {} diff --git a/tests/ui/associated-type-bounds/type-alias.rs b/tests/ui/associated-type-bounds/type-alias.rs new file mode 100644 index 000000000..f74c5ff1e --- /dev/null +++ b/tests/ui/associated-type-bounds/type-alias.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(associated_type_bounds)] + +type _TaWhere1 where T: Iterator = T; //~ WARNING type_alias_bounds +type _TaWhere2 where T: Iterator = T; //~ WARNING type_alias_bounds +type _TaWhere3 where T: Iterator = T; //~ WARNING type_alias_bounds +type _TaWhere4 where T: Iterator = T; //~ WARNING type_alias_bounds +type _TaWhere5 where T: Iterator Into<&'a u8>> = T; //~ WARNING type_alias_bounds +type _TaWhere6 where T: Iterator> = T; //~ WARNING type_alias_bounds + +type _TaInline1> = T; //~ WARNING type_alias_bounds +type _TaInline2> = T; //~ WARNING type_alias_bounds +type _TaInline3> = T; //~ WARNING type_alias_bounds +type _TaInline4> = T; //~ WARNING type_alias_bounds +type _TaInline5 Into<&'a u8>>> = T; //~ WARNING type_alias_bounds +type _TaInline6>> = T; //~ WARNING type_alias_bounds + +fn main() {} diff --git a/tests/ui/associated-type-bounds/type-alias.stderr b/tests/ui/associated-type-bounds/type-alias.stderr new file mode 100644 index 000000000..c22b80b88 --- /dev/null +++ b/tests/ui/associated-type-bounds/type-alias.stderr @@ -0,0 +1,147 @@ +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 + | +LL - type _TaWhere1 where T: Iterator = T; +LL + type _TaWhere1 = T; + | + +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 + | +LL - type _TaWhere2 where T: Iterator = T; +LL + type _TaWhere2 = T; + | + +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 + | +LL - type _TaWhere3 where T: Iterator = T; +LL + type _TaWhere3 = T; + | + +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 + | +LL - type _TaWhere4 where T: Iterator = T; +LL + type _TaWhere4 = T; + | + +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 + | +LL - type _TaWhere5 where T: Iterator Into<&'a u8>> = T; +LL + type _TaWhere5 = T; + | + +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 + | +LL - type _TaWhere6 where T: Iterator> = T; +LL + type _TaWhere6 = T; + | + +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 + | +LL - type _TaInline1> = T; +LL + type _TaInline1 = T; + | + +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 + | +LL - type _TaInline2> = T; +LL + type _TaInline2 = T; + | + +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 + | +LL - type _TaInline3> = T; +LL + type _TaInline3 = T; + | + +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 + | +LL - type _TaInline4> = T; +LL + type _TaInline4 = T; + | + +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 + | +LL - type _TaInline5 Into<&'a u8>>> = T; +LL + type _TaInline5 = T; + | + +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 + | +LL - type _TaInline6>> = T; +LL + type _TaInline6 = T; + | + +warning: 12 warnings emitted + diff --git a/tests/ui/associated-type-bounds/union-bounds.rs b/tests/ui/associated-type-bounds/union-bounds.rs new file mode 100644 index 000000000..46e5aef04 --- /dev/null +++ b/tests/ui/associated-type-bounds/union-bounds.rs @@ -0,0 +1,123 @@ +// run-pass + +#![feature(associated_type_bounds)] + +#![allow(unused_assignments)] + +trait Tr1: Copy { type As1: Copy; } +trait Tr2: Copy { type As2: Copy; } +trait Tr3: Copy { type As3: Copy; } +trait Tr4<'a>: Copy { type As4: Copy; } +trait Tr5: Copy { type As5: Copy; } + +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; +} + +#[derive(Copy, Clone)] +union UnSelf where Self: Tr1, T: Copy { + 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); +} -- cgit v1.2.3