diff options
| author | bors <bors@rust-lang.org> | 2019-06-06 03:56:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-06-06 03:56:22 +0000 |
| commit | 740668dbd99dbf1726bbb0cca6cd0943ea2f7e27 (patch) | |
| tree | 7fcf783b5f92803e8ca4985eaa24097e76b6192c /src/test | |
| parent | 1bec46c9a5399d5e95c05e3428c3abd264780705 (diff) | |
| parent | ee890331f6e33afe12ef250eb6388db2aab7cbbf (diff) | |
| download | rust-740668dbd99dbf1726bbb0cca6cd0943ea2f7e27.tar.gz rust-740668dbd99dbf1726bbb0cca6cd0943ea2f7e27.zip | |
Auto merge of #57428 - alexreg:associated_type_bounds, r=nikomatsakis,Centril
Implementation of RFC 2289 (associated_type_bounds) This PR implements the [`asociated_type_bounds` feature](https://github.com/rust-lang/rfcs/blob/master/text/2289-associated-type-bounds.md). Associated type bounds are implemented in: - function/method arguments and return types - structs, enums, unions - associated items in traits - type aliases - type parameter defaults - trait objects - let bindings CC @nikomatsakis @centril
Diffstat (limited to 'src/test')
51 files changed, 3250 insertions, 58 deletions
diff --git a/src/test/run-make-fulldeps/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json index c8b3d081869..0caf268aa00 100644 --- a/src/test/run-make-fulldeps/libtest-json/output.json +++ b/src/test/run-make-fulldeps/libtest-json/output.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs index 2e2a77b92ca..7e819e2b34e 100644 --- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs @@ -1,23 +1,21 @@ // ignore-cross-compile - // The general idea of this test is to enumerate all "interesting" expressions and check that -// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: +// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: // -// 1. The test focuses on expression nesting, because interactions between different expression -// types are harder to test manually than single expression types in isolation. +// 1. The test focuses on expression nesting, because interactions between different expression +// types are harder to test manually than single expression types in isolation. // -// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x + -// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct -// handling of an expression might depend on the expression's parent, but doesn't depend on its -// siblings or any more distant ancestors. +// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x + +// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct +// handling of an expression might depend on the expression's parent, but doesn't depend on its +// siblings or any more distant ancestors. // -// 3. The test only checks certain expression kinds. The assumption is that similar expression -// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer -// and parser. So if all combinations of exprs involving `if` work correctly, then combinations +// 3. The test only checks certain expression kinds. The assumption is that similar expression +// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer +// and parser. So if all combinations of exprs involving `if` work correctly, then combinations // using `while`, `if let`, and so on will likely work as well. - #![feature(rustc_private)] extern crate rustc_data_structures; @@ -155,9 +153,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { } -// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. +// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. -/// MutVisitor that removes all `ExprKind::Paren` nodes. +/// `MutVisitor` that removes all `ExprKind::Paren` nodes. struct RemoveParens; impl MutVisitor for RemoveParens { @@ -171,7 +169,7 @@ impl MutVisitor for RemoveParens { } -/// MutVisitor that inserts `ExprKind::Paren` nodes around every `Expr`. +/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`. struct AddParens; impl MutVisitor for AddParens { @@ -205,8 +203,8 @@ fn run() { // We want to know if `parsed` is structurally identical to `e`, ignoring trivial // differences like placement of `Paren`s or the exact ranges of node spans. - // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s - // everywhere we can, then pretty-print. This should give an unambiguous representation of + // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s + // everywhere we can, then pretty-print. This should give an unambiguous representation of // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't // relying on the correctness of the very thing we're testing. RemoveParens.visit_expr(&mut e); diff --git a/src/test/run-pass/issues/issue-25700-2.rs b/src/test/run-pass/issues/issue-25700-2.rs index 65de5edce48..b161e68abaf 100644 --- a/src/test/run-pass/issues/issue-25700-2.rs +++ b/src/test/run-pass/issues/issue-25700-2.rs @@ -18,5 +18,5 @@ fn record_type<Id: AstId>(i: Id::Untyped) -> u8 { } pub fn main() { - assert_eq!(record_type::<u32>(3), 42); + assert_eq!(record_type::<u32>(3), 42); } diff --git a/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs index 900b2b2206f..8bc00020652 100644 --- a/src/test/run-pass/multi-panic.rs +++ b/src/test/run-pass/multi-panic.rs @@ -8,7 +8,7 @@ fn check_for_no_backtrace(test: std::process::Output) { let mut it = err.lines(); assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked at")), Some(true)); - assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` \ + assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \ environment variable to display a backtrace.")); assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true)); assert_eq!(it.next(), None); diff --git a/src/test/run-pass/traits/trait-object-auto-dedup.rs b/src/test/run-pass/traits/trait-object-auto-dedup.rs index 98a386e4c6e..39d25eb7fe0 100644 --- a/src/test/run-pass/traits/trait-object-auto-dedup.rs +++ b/src/test/run-pass/traits/trait-object-auto-dedup.rs @@ -1,14 +1,15 @@ // run-pass + #![allow(unused_assignments)] + // Test that duplicate auto trait bounds in trait objects don't create new types. #[allow(unused_assignments)] - use std::marker::Send as SendAlias; // A dummy trait for the non-auto trait. trait Trait {} -// A dummy struct to implement Trait, Send, and . +// A dummy struct to implement `Trait` and `Send`. struct Struct; impl Trait for Struct {} @@ -23,12 +24,12 @@ impl dyn Trait + Send + Send { } fn main() { - // 1. Moving into a variable with more Sends and back. + // 1. Moving into a variable with more `Send`s and back. let mut dyn_trait_send = Box::new(Struct) as Box<dyn Trait + Send>; let dyn_trait_send_send: Box<dyn Trait + Send + Send> = dyn_trait_send; dyn_trait_send = dyn_trait_send_send; - // 2. Calling methods with different number of Sends. + // 2. Calling methods with different number of `Send`s. let dyn_trait_send = Box::new(Struct) as Box<dyn Trait + Send>; takes_dyn_trait_send_send(dyn_trait_send); diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 0c42c652d78..e362ecf349e 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -27,7 +27,7 @@ stderr: stderr 1 stderr 2 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:7:1 -note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. diff --git a/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs b/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs new file mode 100644 index 00000000000..0ea23ad1dbf --- /dev/null +++ b/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs @@ -0,0 +1,177 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha<T: Alpha>(x: T) -> usize { x.alpha() } +pub fn assert_static<T: 'static>(_: T) -> usize { 24 } +pub fn assert_delta<T: 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<T: for<'a> Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta<T>(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> <T as Epsilon<'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<B>(beta: B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::<B::Gamma>(gamma) +} + +pub fn desugared_bound_region<B>(beta: B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::<B::Gamma>(beta.gamma()) +} + +pub fn desugared_bound_multi<B>(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::<B::Gamma>(beta.gamma()) + + assert_static::<B::Gamma>(beta.gamma()) + + assert_delta::<B::Gamma>(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::<B::Gamma>(gamma) +} + +pub fn desugared_bound_region_forall<B>(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::<B::Gamma>(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::<B::Gamma>(&g1) + + assert_epsilon_specific::<B::Gamma>(&g2) +} + +pub fn desugared_bound_region_forall2<B>(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> <B::Gamma as Epsilon<'a>>::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::<B::Gamma>(gamma) +} + +pub fn desugared_contraint_region_forall<B>(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<B>(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + <B::Gamma as 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::<BetaType>(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(beta)); + assert_eq!(42 + 1337, desugared_bound_nested(beta)); +} diff --git a/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs b/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs new file mode 100644 index 00000000000..85d6c5aaf3c --- /dev/null +++ b/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs @@ -0,0 +1,182 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(&self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha<T: Alpha>(x: T) -> usize { x.alpha() } +pub fn assert_static<T: 'static>(_: T) -> usize { 24 } +pub fn assert_delta<T: 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<T: for<'a> Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta<T>(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> <T as Epsilon<'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<T> Beta for &(dyn Beta<Gamma = T> + 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<B: ?Sized>(beta: &B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::<B::Gamma>(gamma) +} + +pub fn desugared_bound_region<B: ?Sized>(beta: &B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::<B::Gamma>(beta.gamma()) +} + +pub fn desugared_bound_multi<B: ?Sized>(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::<B::Gamma>(beta.gamma()) + + assert_static::<B::Gamma>(beta.gamma()) + + assert_delta::<B::Gamma>(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::<B::Gamma>(gamma) +} + +pub fn desugared_bound_region_forall<B: ?Sized>(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::<B::Gamma>(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::<B::Gamma>(&g1) + + assert_epsilon_specific::<B::Gamma>(&g2) +} + +pub fn desugared_bound_region_forall2<B: ?Sized>(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> <B::Gamma as Epsilon<'a>>::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::<B::Gamma>(gamma) +} + +pub fn desugared_contraint_region_forall<B: ?Sized>(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<B: ?Sized>(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + <B::Gamma as 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::<BetaType>(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(&beta)); + assert_eq!(42 + 1337, desugared_bound_nested(&beta)); +} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs new file mode 100644 index 00000000000..78704a9b512 --- /dev/null +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -0,0 +1,60 @@ +// compile-fail +// ignore-tidy-linelength + +// NOTE: rustc cannot currently handle bounds of the form `for<'a> <Foo as Bar<'a>>::Assoc: Baz`. +// This should hopefully be fixed with Chalk. + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Once; + +trait Lam<Binder> { 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<Item: + Send + Iterator<Item: + for<'a> Lam<&'a u8, App: + Debug + > + > + Sync>; +} + +pub struct S1; +impl Case1 for S1 { +//~^ ERROR `<L1 as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` [E0277] + type C = Once<Once<L1>>; +} + +fn assume_case1<T: Case1>() { +//~^ ERROR `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` [E0277] +//~| ERROR `<<T as Case1>::C as std::iter::Iterator>::Item` is not an iterator [E0277] +//~| ERROR `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be sent between threads safely [E0277] +//~| ERROR `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be shared between threads safely [E0277] + fn assert_a<_0, A>() where A: Iterator<Item = _0>, _0: Debug {} + assert_a::<_, T::A>(); + + fn assert_b<_0, B>() where B: Iterator<Item = _0>, _0: 'static {} + assert_b::<_, T::B>(); + + fn assert_c<_0, _1, _2, C>() + where + C: Clone + Iterator<Item = _2>, + _2: Send + Iterator<Item = _1>, + _1: for<'a> Lam<&'a u8, App = _0>, + _0: Debug, + {} + assert_c::<_, _, _, T::C>(); +} + +fn main() { + assume_case1(S1); +} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr new file mode 100644 index 00000000000..aebf29cc332 --- /dev/null +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -0,0 +1,85 @@ +error[E0277]: `<L1 as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:32:6 + | +LL | impl Case1 for S1 { + | ^^^^^ `<L1 as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<L1 as Lam<&'a u8>>::App` + +error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` is not an iterator + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1<T: Case1>() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<<T as Case1>::C as std::iter::Iterator>::Item` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item` + = help: consider adding a `where <<T as Case1>::C as std::iter::Iterator>::Item: std::iter::Iterator` bound + +error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be sent between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1<T: Case1>() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item` + = help: consider adding a `where <<T as Case1>::C as std::iter::Iterator>::Item: std::marker::Send` bound +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be shared between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1<T: Case1>() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item` + = help: consider adding a `where <<T as Case1>::C as std::iter::Iterator>::Item: std::marker::Sync` bound +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1<T: Case1>() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs new file mode 100644 index 00000000000..8c9110d03ec --- /dev/null +++ b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs @@ -0,0 +1,51 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Empty; +use std::ops::Range; + +trait Lam<Binder> { 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<Item: Debug>; + + type B: Iterator<Item: 'static>; +} + +pub struct S1; +impl Case1 for S1 { + type A = Empty<String>; + type B = Range<u16>; +} + +// Ensure we don't have existential desugaring: + +pub trait Foo { type Out: Baz<Assoc: Default>; } +pub trait Baz { type Assoc; } + +#[derive(Default)] +struct S2; +#[derive(Default)] +struct S3; +struct S4; +struct S5; +struct S6; +struct S7; + +impl Foo for S6 { type Out = S4; } +impl Foo for S7 { type Out = S5; } + +impl Baz for S4 { type Assoc = S2; } +impl Baz for S5 { type Assoc = S3; } + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs new file mode 100644 index 00000000000..bee56d6f689 --- /dev/null +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -0,0 +1,161 @@ +// compile-fail +// ignore-tidy-linelength +// error-pattern:could not find defining uses + +#![feature(associated_type_bounds)] +#![feature(existential_type)] +#![feature(impl_trait_in_bindings)] +#![feature(untagged_unions)] + +use std::iter; + +struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn FI1<T: Iterator<Item: Copy, Item: Send>>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +type TAI1<T: Iterator<Item: Copy, Item: Send>> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +existential type ETAI1<T: Iterator<Item: Copy, Item: Send>>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI2<T: Iterator<Item: Copy, Item: Copy>>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI3<T: Iterator<Item: 'static, Item: 'static>>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI4: Iterator<Item: Copy, Item: Send>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI5: Iterator<Item: Copy, Item: Copy>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI6: Iterator<Item: 'static, Item: 'static>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +trait TRI1<T: Iterator<Item: Copy, Item: Send>> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS1: Iterator<Item: Copy, Item: Send> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS2: Iterator<Item: Copy, Item: Copy> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS3: Iterator<Item: 'static, Item: 'static> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +type TADyn1 = dyn Iterator<Item: Copy, Item: Send>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr new file mode 100644 index 00000000000..68367c91654 --- /dev/null +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -0,0 +1,632 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/duplicate.rs:7:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:12:36 + | +LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:14:36 + | +LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:16:39 + | +LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:18:45 + | +LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:20:45 + | +LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:22:48 + | +LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:25:34 + | +LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:27:34 + | +LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:29:37 + | +LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:31:43 + | +LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:33:43 + | +LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:35:46 + | +LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:38:35 + | +LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:40:35 + | +LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:42:38 + | +LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:44:44 + | +LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:46:44 + | +LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:48:47 + | +LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:51:32 + | +LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:53:32 + | +LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:55:35 + | +LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:57:43 + | +LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:59:43 + | +LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:61:46 + | +LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:70:40 + | +LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:72:40 + | +LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:74:43 + | +LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:64:42 + | +LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:66:42 + | +LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:68:45 + | +LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> { iter::empty() } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:77:39 + | +LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:79:39 + | +LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:81:42 + | +LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:83:40 + | +LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:85:40 + | +LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:87:43 + | +LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:90:46 + | +LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:92:46 + | +LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:94:49 + | +LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:97:35 + | +LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:99:35 + | +LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:101:38 + | +LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:103:44 + | +LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:105:44 + | +LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:107:47 + | +LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:110:1 + | +LL | existential type ETAI1<T: Iterator<Item: Copy, Item: Send>>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:110:48 + | +LL | existential type ETAI1<T: Iterator<Item: Copy, Item: Send>>: Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:112:1 + | +LL | existential type ETAI2<T: Iterator<Item: Copy, Item: Copy>>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:112:48 + | +LL | existential type ETAI2<T: Iterator<Item: Copy, Item: Copy>>: Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:114:1 + | +LL | existential type ETAI3<T: Iterator<Item: 'static, Item: 'static>>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:114:51 + | +LL | existential type ETAI3<T: Iterator<Item: 'static, Item: 'static>>: Copy; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:116:1 + | +LL | existential type ETAI4: Iterator<Item: Copy, Item: Send>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:116:46 + | +LL | existential type ETAI4: Iterator<Item: Copy, Item: Send>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:118:1 + | +LL | existential type ETAI5: Iterator<Item: Copy, Item: Copy>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:118:46 + | +LL | existential type ETAI5: Iterator<Item: Copy, Item: Copy>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:120:1 + | +LL | existential type ETAI6: Iterator<Item: 'static, Item: 'static>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:120:49 + | +LL | existential type ETAI6: Iterator<Item: 'static, Item: 'static>; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:123:36 + | +LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:125:36 + | +LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:127:39 + | +LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:129:34 + | +LL | trait TRS1: Iterator<Item: Copy, Item: Send> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:131:34 + | +LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:133:37 + | +LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:135:45 + | +LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:137:45 + | +LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:139:48 + | +LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:141:46 + | +LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:143:46 + | +LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:145:49 + | +LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:147:43 + | +LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:149:43 + | +LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:151:46 + | +LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:154:40 + | +LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:156:44 + | +LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:158:43 + | +LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: aborting due to 93 previous errors + diff --git a/src/test/ui/associated-type-bounds/dyn-existential-type.rs b/src/test/ui/associated-type-bounds/dyn-existential-type.rs new file mode 100644 index 00000000000..dc0afaa934a --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-existential-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(existential_type)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; } +fn assert_static<T: 'static>(_: T) {} +fn assert_forall_tr2<T: for<'a> 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<dyn Tr1<As1: Copy>>; +fn def_et1() -> Et1 { Box::new(S1) } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +type Et2 = Box<dyn Tr1<As1: 'static>>; +fn def_et2() -> Et2 { Box::new(S1) } +pub fn use_et2() { assert_static(def_et2().mk()); } + +type Et3 = Box<dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range<u8>; + 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<dyn Tr1<As1: for<'a> Tr2<'a>>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + Box::new(A) +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.rs b/src/test/ui/associated-type-bounds/dyn-lcsit.rs new file mode 100644 index 00000000000..439304fd309 --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.rs @@ -0,0 +1,69 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] + +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; } +fn assert_static<T: 'static>(_: T) {} +fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: &dyn Tr1<As1: Copy> = &S1; +const sdef_et1: &dyn Tr1<As1: Copy> = &S1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1; +static sdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: &dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range<u8>; + fn mk(&self) -> Self::As1 { 0..10 } + }; + &A +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + &A +}; +static sdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.stderr b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr new file mode 100644 index 00000000000..5fe4818ef8f --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/dyn-lcsit.rs:4:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs new file mode 100644 index 00000000000..f22a6c44cb8 --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs @@ -0,0 +1,73 @@ +// run-pass + +// FIXME: uncomment let binding types below when `impl_trait_in_bindings` feature is fixed. + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; } +fn assert_static<T: 'static>(_: T) {} +fn assert_forall_tr2<T: for<'a> 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<dyn Tr1<As1: Copy>> { + let x /* : Box<dyn Tr1<As1: Copy>> */ = Box::new(S1); + x +} +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> Box<dyn Tr1<As1: Send + 'static>> { + let x /* : Box<dyn Tr1<As1: Send + 'static>> */ = Box::new(S1); + x +} +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> Box<dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range<u8>; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x /* : Box<dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>> */ + = 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<dyn Tr1<As1: for<'a> 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<dyn Tr1<As1: for<'a> Tr2<'a>>> */ = Box::new(A); + x +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs new file mode 100644 index 00000000000..1b3e978594d --- /dev/null +++ b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -0,0 +1,26 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +trait Tr1: Sized { type As1; } +trait Tr2<'a>: Sized { type As2; } + +trait ObjTr1 { fn foo() -> Self where Self: Tr1<As1: Copy>; } +fn _assert_obj_safe_1(_: Box<dyn ObjTr1>) {} + +trait ObjTr2 { fn foo() -> Self where Self: Tr1<As1: 'static>; } +fn _assert_obj_safe_2(_: Box<dyn ObjTr2>) {} + +trait ObjTr3 { fn foo() -> Self where Self: Tr1<As1: Into<u8> + 'static + Copy>; } +fn _assert_obj_safe_3(_: Box<dyn ObjTr3>) {} + +trait ObjTr4 { fn foo() -> Self where Self: Tr1<As1: for<'a> Tr2<'a>>; } +fn _assert_obj_safe_4(_: Box<dyn ObjTr4>) {} + +trait ObjTr5 { fn foo() -> Self where for<'a> Self: Tr1<As1: Tr2<'a>>; } +fn _assert_obj_safe_5(_: Box<dyn ObjTr5>) {} + +trait ObjTr6 { fn foo() -> Self where Self: for<'a> Tr1<As1: Tr2<'a, As2: for<'b> Tr2<'b>>>; } +fn _assert_obj_safe_6(_: Box<dyn ObjTr6>) {} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/enum-bounds.rs b/src/test/ui/associated-type-bounds/enum-bounds.rs new file mode 100644 index 00000000000..a6b0bb7070b --- /dev/null +++ b/src/test/ui/associated-type-bounds/enum-bounds.rs @@ -0,0 +1,122 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +enum En1<T: Tr1<As1: Tr2>> { + Outest(T), + Outer(T::As1), + Inner(<T::As1 as Tr2>::As2), +} + +fn wrap_en1_1<T>(x: T) -> En1<T> where T: Tr1, T::As1: Tr2 { + En1::Outest(x) +} + +fn wrap_en1_2<T>(x: T::As1) -> En1<T> where T: Tr1, T::As1: Tr2 { + En1::Outer(x) +} + +fn wrap_en1_3<T>(x: <T::As1 as Tr2>::As2) -> En1<T> where T: Tr1, T::As1: Tr2 { + En1::Inner(x) +} + +enum En2<T: Tr1<As1: Tr2<As2: Tr3>>> { + V0(T), + V1(T::As1), + V2(<T::As1 as Tr2>::As2), + V3(<<T::As1 as Tr2>::As2 as Tr3>::As3), +} + +enum En3<T: Tr1<As1: 'static>> { + V0(T), + V1(&'static T::As1), +} + +enum En4<'x1, 'x2, T: Tr1<As1: for<'l> Tr4<'l>>> { + V0(&'x1 <T::As1 as Tr4<'x1>>::As4), + V1(&'x2 <T::As1 as Tr4<'x2>>::As4), +} + +enum _En5<'x1, 'x2, T: Tr1<As1: for<'l> Tr4<'l, As4: Copy>>> { + _V0(&'x1 <T::As1 as Tr4<'x1>>::As4), + _V1(&'x2 <T::As1 as Tr4<'x2>>::As4), +} + +enum En6<T> +where + T: Tr1<As1: Tr2 + 'static + Tr5>, +{ + V0(T), + V1(<T::As1 as Tr2>::As2), + V2(&'static T::As1), + V3(<T::As1 as Tr5>::As5), +} + +enum _En7<'a, 'b, T> // `<T::As1 as Tr2>::As2: 'a` is implied. +where + T: Tr1<As1: Tr2>, +{ + V0(&'a T), + V1(&'b <T::As1 as Tr2>::As2), +} + +fn _make_en7<'a, 'b, T>(x: _En7<'a, 'b, T>) +where + T: Tr1<As1: Tr2>, +{ + match x { + _En7::V0(x) => { + let _: &'a T = &x; + }, + _En7::V1(_) => {}, + } +} + +enum EnSelf<T> where Self: Tr1<As1: Tr2> { + V0(T), + V1(<Self as Tr1>::As1), + V2(<<Self as Tr1>::As1 as Tr2>::As2), +} + +impl Tr1 for EnSelf<&'static str> { type As1 = bool; } + +fn main() { + if let En1::Outest("foo") = wrap_en1_1::<_>("foo") {} else { panic!() }; + if let En1::Outer(true) = wrap_en1_2::<&str>(true) {} else { panic!() }; + if let En1::Inner(24u8) = wrap_en1_3::<&str>(24u8) {} else { panic!() }; + + let _ = En2::<_>::V0("151571"); + let _ = En2::<&str>::V1(false); + let _ = En2::<&str>::V2(42u8); + let _ = En2::<&str>::V3(|| 12u8); + + let _ = En3::<_>::V0("deadbeef"); + let _ = En3::<&str>::V1(&true); + + let f1 = (1,); + let f2 = (2,); + let _ = En4::<()>::V0(&f1.0); + let _ = En4::<()>::V1(&f2.0); + + let _ = En6::<_>::V0("bar"); + let _ = En6::<&str>::V1(24u8); + let _ = En6::<&str>::V2(&false); + let _ = En6::<&str>::V3(12u16); + + let _ = EnSelf::<_>::V0("foo"); + let _ = EnSelf::<&'static str>::V1(true); + let _ = EnSelf::<&'static str>::V2(24u8); +} diff --git a/src/test/ui/associated-type-bounds/existential-type.rs b/src/test/ui/associated-type-bounds/existential-type.rs new file mode 100644 index 00000000000..87046aec5c4 --- /dev/null +++ b/src/test/ui/associated-type-bounds/existential-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(existential_type)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; } +fn assert_static<T: 'static>(_: T) {} +fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +existential type Et1: Tr1<As1: Copy>; +fn def_et1() -> Et1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +existential type Et2: Tr1<As1: 'static>; +fn def_et2() -> Et2 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +existential type Et3: Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range<u8>; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +existential type Et4: Tr1<As1: for<'a> Tr2<'a>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/fn-apit.rs b/src/test/ui/associated-type-bounds/fn-apit.rs new file mode 100644 index 00000000000..7e208b4e70d --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-apit.rs @@ -0,0 +1,58 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn apit_bound(beta: impl Beta<Gamma: Alpha>) -> usize { + desugared_bound(beta) +} + +fn apit_bound_region(beta: impl Beta<Gamma: 'static>) -> usize { + desugared_bound_region(beta) +} + +fn apit_bound_multi( + beta: impl Copy + Beta<Gamma: Alpha + 'static + Delta> +) -> usize { + desugared_bound_multi(beta) +} + +fn apit_bound_region_forall( + beta: impl Beta<Gamma: Copy + for<'a> Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn apit_bound_region_forall2( + beta: impl Beta<Gamma: Copy + for<'a> Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn apit_bound_nested( + beta: impl Beta<Gamma: Copy + Alpha + Beta<Gamma: Delta>> +) -> usize { + desugared_bound_nested(beta) +} + +fn apit_bound_nested2( + beta: impl Beta<Gamma = impl Copy + Alpha + Beta<Gamma: Delta>> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, apit_bound(beta)); + assert_eq!(24, apit_bound_region(beta)); + assert_eq!(42 + 24 + 1337, apit_bound_multi(beta)); + assert_eq!(7331 * 2, apit_bound_region_forall(beta)); + assert_eq!(42 + 1337, apit_bound_nested(beta)); + assert_eq!(42 + 1337, apit_bound_nested2(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-aux.rs b/src/test/ui/associated-type-bounds/fn-aux.rs new file mode 100644 index 00000000000..434bdbe996c --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-aux.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn main() { + desugared(); +} diff --git a/src/test/ui/associated-type-bounds/fn-dyn-apit.rs b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs new file mode 100644 index 00000000000..9ff4a50e1e6 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs @@ -0,0 +1,60 @@ +// run-pass +// aux-build:fn-dyn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_dyn_aux; + +use fn_dyn_aux::*; + +// ATB, APIT (dyn trait): + +fn dyn_apit_bound(beta: &dyn Beta<Gamma: Alpha>) -> usize { + desugared_bound(beta) +} + +fn dyn_apit_bound_region(beta: &dyn Beta<Gamma: 'static>) -> usize { + desugared_bound_region(beta) +} + +fn dyn_apit_bound_multi( + beta: &(dyn Beta<Gamma: Alpha + 'static + Delta> + Send) +) -> usize { + desugared_bound_multi(beta) +} + +fn dyn_apit_bound_region_forall( + beta: &dyn Beta<Gamma: Copy + for<'a> Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn dyn_apit_bound_region_forall2( + beta: &dyn Beta<Gamma: Copy + for<'a> Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn dyn_apit_bound_nested( + beta: &dyn Beta<Gamma: Copy + Alpha + Beta<Gamma: Delta>> +) -> usize { + desugared_bound_nested(beta) +} + +fn dyn_apit_bound_nested2( + beta: &dyn Beta<Gamma = impl Copy + Alpha + Beta<Gamma: Delta>> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, dyn_apit_bound(&beta)); + assert_eq!(24, dyn_apit_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, dyn_apit_bound_multi(&beta)); + assert_eq!(7331 * 2, dyn_apit_bound_region_forall(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested2(&beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-inline.rs b/src/test/ui/associated-type-bounds/fn-inline.rs new file mode 100644 index 00000000000..7b188763b7a --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-inline.rs @@ -0,0 +1,62 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Inline bounds: + +fn inline_bound<B: Beta<Gamma: Alpha>>(beta: B) -> usize { + desugared_bound(beta) +} + +fn inline_bound_region<B: Beta<Gamma: 'static>>(beta: B) -> usize { + desugared_bound_region(beta) +} + +fn inline_bound_multi<B: Copy + Beta<Gamma: Alpha + 'static + Delta>>( + beta: B +) -> usize { + desugared_bound_multi(beta) +} + +fn inline_bound_region_specific<'a, B: Beta<Gamma: 'a + Epsilon<'a>>>( + gamma: &'a B::Gamma +) -> usize { + desugared_bound_region_specific::<B>(gamma) +} + +fn inline_bound_region_forall<B: Beta<Gamma: Copy + for<'a> Epsilon<'a>>>( + beta: B +) -> usize { + desugared_bound_region_forall(beta) +} + +fn inline_bound_region_forall2<B: Beta<Gamma: Copy + for<'a> Epsilon<'a, Zeta: Eta>>>( + beta: B +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn inline_bound_nested<B: Beta<Gamma: Copy + Alpha + Beta<Gamma: Delta>>>( + 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::<BetaType>(&gamma)); + assert_eq!(7331 * 2, inline_bound_region_forall(beta)); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, inline_bound_region_forall2(beta)); + assert_eq!(42 + 1337, inline_bound_nested(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-where.rs b/src/test/ui/associated-type-bounds/fn-where.rs new file mode 100644 index 00000000000..60d7149a56f --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-where.rs @@ -0,0 +1,78 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Where-clauses: + +fn where_bound<B>(beta: B) -> usize +where + B: Beta<Gamma: Alpha> +{ + desugared_bound(beta) +} + +fn where_bound_region<B>(beta: B) -> usize +where + B: Beta<Gamma: 'static> +{ + desugared_bound_region(beta) +} + +fn where_bound_multi<B>(beta: B) -> usize +where + B: Copy + Beta<Gamma: Alpha + 'static + Delta>, +{ + desugared_bound_multi(beta) +} + +fn where_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta<Gamma: 'a + Epsilon<'a>>, +{ + desugared_bound_region_specific::<B>(gamma) +} + +fn where_bound_region_forall<B>(beta: B) -> usize +where + B: Beta<Gamma: Copy + for<'a> Epsilon<'a>>, +{ + desugared_bound_region_forall(beta) +} + +fn where_bound_region_forall2<B>(beta: B) -> usize +where + B: Beta<Gamma: Copy + for<'a> Epsilon<'a, Zeta: Eta>>, +{ + desugared_bound_region_forall2(beta) +} + +fn where_contraint_region_forall<B>(beta: B) -> usize +where + for<'a> &'a B: Beta<Gamma: Alpha>, +{ + desugared_contraint_region_forall(beta) +} + +fn where_bound_nested<B>(beta: B) -> usize +where + B: Beta<Gamma: Copy + Alpha + Beta<Gamma: Delta>>, +{ + 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::<BetaType>(&gamma)); + assert_eq!(7331 * 2, where_bound_region_forall::<BetaType>(beta)); + assert_eq!(42 + 1337, where_bound_nested::<BetaType>(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-wrap-apit.rs b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs new file mode 100644 index 00000000000..23790d416e1 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs @@ -0,0 +1,64 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, APIT + Wrap: + +struct Wrap<T>(T); + +fn wrap_apit_bound(beta: Wrap<impl Beta<Gamma: Alpha>>) -> usize { + desugared_bound(beta.0) +} + +fn wrap_apit_bound_region(beta: Wrap<impl Beta<Gamma: 'static>>) -> usize { + desugared_bound_region(beta.0) +} + +fn wrap_apit_bound_multi( + beta: Wrap<impl Copy + Beta<Gamma: Alpha + 'static + Delta>> +) -> usize { + desugared_bound_multi(beta.0) +} + +fn wrap_apit_bound_region_forall( + beta: Wrap<impl Beta<Gamma: Copy + for<'a> Epsilon<'a>>> +) -> usize { + desugared_bound_region_forall(beta.0) +} + +fn wrap_apit_bound_region_forall2( + beta: Wrap<impl Beta<Gamma: Copy + for<'a> Epsilon<'a, Zeta: Eta>>> +) -> usize { + desugared_bound_region_forall2(beta.0) +} + +fn wrap_apit_bound_nested( + beta: Wrap<impl Beta<Gamma: Copy + Alpha + Beta<Gamma: Delta>>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn wrap_apit_bound_nested2( + beta: Wrap<impl Beta<Gamma = impl Copy + Alpha + Beta<Gamma: Delta>>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, wrap_apit_bound(Wrap(beta))); + assert_eq!(24, wrap_apit_bound_region(Wrap(beta))); + assert_eq!(42 + 24 + 1337, wrap_apit_bound_multi(Wrap(beta))); + assert_eq!(7331 * 2, wrap_apit_bound_region_forall(Wrap(beta))); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, wrap_apit_bound_region_forall2(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested2(Wrap(beta))); +} diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr new file mode 100644 index 00000000000..32d099fce75 --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/implied-region-constraints.rs:19: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` + +error: lifetime may not live long enough + --> $DIR/implied-region-constraints.rs:40: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` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.rs b/src/test/ui/associated-type-bounds/implied-region-constraints.rs new file mode 100644 index 00000000000..4dbaab50a61 --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.rs @@ -0,0 +1,47 @@ +// compile-fail + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct St<'a, 'b, T: Tr1<As1: Tr2>> { // `T: 'b` is *not* implied! + f0: &'a T, // `T: 'a` is implied. + f1: &'b <T::As1 as Tr2>::As2, // `<T::As1 as Tr2>::As2: 'a` is implied. +} + +fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + // This should fail because `T: 'b` is not implied from `WF(St<'a, 'b, T>)`. + let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + //~^ ERROR lifetime mismatch [E0623] +} + +enum En7<'a, 'b, T> // `<T::As1 as Tr2>::As2: 'a` is implied. +where + T: Tr1, + T::As1: Tr2, +{ + V0(&'a T), + V1(&'b <T::As1 as Tr2>::As2), +} + +fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + match x { + En7::V0(x) => { + // Also fails for the same reason as above: + let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + //~^ ERROR lifetime mismatch [E0623] + }, + En7::V1(_) => {}, + } +} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr new file mode 100644 index 00000000000..9968f3e8bac --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr @@ -0,0 +1,20 @@ +error[E0623]: lifetime mismatch + --> $DIR/implied-region-constraints.rs:19:64 + | +LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) + | ------------- this type is declared with multiple lifetimes... +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + | ^^^^^ ...but data with one lifetime flows into the other here + +error[E0623]: lifetime mismatch + --> $DIR/implied-region-constraints.rs:40:72 + | +LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) + | -------------- this type is declared with multiple lifetimes... +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + | ^^ ...but data with one lifetime flows into the other here + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs new file mode 100644 index 00000000000..1257dc6e94b --- /dev/null +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -0,0 +1,36 @@ +// compile-fail +// ignore-tidy-linelength +// error-pattern:could not find defining uses + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +struct S1 { f: dyn Iterator<Item: Copy> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +struct S2 { f: Box<dyn Iterator<Item: Copy>> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +struct S3 { f: dyn Iterator<Item: 'static> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] + +enum E1 { V(dyn Iterator<Item: Copy>) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +enum E2 { V(Box<dyn Iterator<Item: Copy>>) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +enum E3 { V(dyn Iterator<Item: 'static>) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] + +union U1 { f: dyn Iterator<Item: Copy> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +union U2 { f: Box<dyn Iterator<Item: Copy>> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +union U3 { f: dyn Iterator<Item: 'static> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr new file mode 100644 index 00000000000..7bdd71b8296 --- /dev/null +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -0,0 +1,79 @@ +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:8:29 + | +LL | struct S1 { f: dyn Iterator<Item: Copy> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:11:33 + | +LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:14:29 + | +LL | struct S3 { f: dyn Iterator<Item: 'static> } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:18:26 + | +LL | enum E1 { V(dyn Iterator<Item: Copy>) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:21:30 + | +LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:24:26 + | +LL | enum E3 { V(dyn Iterator<Item: 'static>) } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:28:28 + | +LL | union U1 { f: dyn Iterator<Item: Copy> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:31:32 + | +LL | union U2 { f: Box<dyn Iterator<Item: Copy>> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:34:28 + | +LL | union U3 { f: dyn Iterator<Item: 'static> } + | ^^^^^^^^^^^^^ + +error[E0601]: `main` function not found in crate `inside_adt` + | + = note: consider adding a `main` function to `$DIR/inside-adt.rs` + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/associated-type-bounds/lcsit.rs b/src/test/ui/associated-type-bounds/lcsit.rs new file mode 100644 index 00000000000..85b6e804b4e --- /dev/null +++ b/src/test/ui/associated-type-bounds/lcsit.rs @@ -0,0 +1,78 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] + +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; } +fn assert_static<T: 'static>(_: T) {} +fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: impl Copy + Tr1<As1: Copy> = { + let x: impl Copy + Tr1<As1: Copy> = S1; + x +}; +static sdef_et1: impl Copy + Tr1<As1: Copy> = cdef_et1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: impl Tr1<As1: 'static> = { + let x: impl Tr1<As1: 'static> = S1; + x +}; +static sdef_et2: impl Tr1<As1: 'static> = cdef_et2; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range<u8>; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x: impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = A; + x +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = A; + x +}; + +static sdef_et4: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/lcsit.stderr b/src/test/ui/associated-type-bounds/lcsit.stderr new file mode 100644 index 00000000000..8fda11beddc --- /dev/null +++ b/src/test/ui/associated-type-bounds/lcsit.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/lcsit.rs:4:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/associated-type-bounds/rpit.rs b/src/test/ui/associated-type-bounds/rpit.rs new file mode 100644 index 00000000000..7b640d5a457 --- /dev/null +++ b/src/test/ui/associated-type-bounds/rpit.rs @@ -0,0 +1,64 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; } +fn assert_static<T: 'static>(_: T) {} +fn assert_forall_tr2<T: for<'a> 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<As1: Copy> { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> impl Tr1<As1: 'static> { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range<u8>; + 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<As1: for<'a> Tr2<'a>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} + +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/struct-bounds.rs b/src/test/ui/associated-type-bounds/struct-bounds.rs new file mode 100644 index 00000000000..2d189cd6672 --- /dev/null +++ b/src/test/ui/associated-type-bounds/struct-bounds.rs @@ -0,0 +1,115 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 {} +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 {} +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +struct St1<T: Tr1<As1: Tr2>> { + outest: T, + outer: T::As1, + inner: <T::As1 as Tr2>::As2, +} + +fn unwrap_1_st1<T: Tr1<As1: Tr2>>(x: St1<T>) -> (T, T::As1, <T::As1 as Tr2>::As2) { + (x.outest, x.outer, x.inner) +} + +fn unwrap_2_st1<T>(x: St1<T>) -> (T, T::As1, <T::As1 as Tr2>::As2) +where + T: Tr1, + T::As1: Tr2, +{ + unwrap_1_st1(x) +} + +struct St2<T: Tr1<As1: Tr2<As2: Tr3>>> { + outest: T, + outer: T::As1, + inner: <T::As1 as Tr2>::As2, +} + +struct St3<T: Tr1<As1: 'static>> { + outest: T, + outer: &'static T::As1, +} + +struct St4<'x1, 'x2, T: Tr1<As1: for<'l> Tr4<'l>>> { + f1: &'x1 <T::As1 as Tr4<'x1>>::As4, + f2: &'x2 <T::As1 as Tr4<'x2>>::As4, +} + +struct St5<'x1, 'x2, T: Tr1<As1: for<'l> Tr4<'l, As4: Copy>>> { + f1: &'x1 <T::As1 as Tr4<'x1>>::As4, + f2: &'x2 <T::As1 as Tr4<'x2>>::As4, +} + +struct St6<T> +where + T: Tr1<As1: Tr2 + 'static + Tr5>, +{ + f0: T, + f1: <T::As1 as Tr2>::As2, + f2: &'static T::As1, + f3: <T::As1 as Tr5>::As5, +} + +struct St7<'a, 'b, T> // `<T::As1 as Tr2>::As2: 'a` is implied. +where + T: Tr1<As1: Tr2>, +{ + f0: &'a T, + f1: &'b <T::As1 as Tr2>::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<T> where Self: Tr1<As1: Tr2> { + f2: <<Self as Tr1>::As1 as Tr2>::As2, +} + +impl Tr1 for StSelf<&'static str> { type As1 = bool; } + +fn main() { + let st1 = St1 { outest: "foo", outer: true, inner: 42u8 }; + assert_eq!(("foo", true, 42), unwrap_1_st1(st1)); + + let _ = St2 { outest: "foo", outer: true, inner: 42u8 }; + + let _ = St3 { outest: "foo", outer: &true }; + + let f1 = (1,); + let f2 = (2,); + let st4 = St4::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st4.f1, st4.f2)); + + // FIXME: requires lazy normalization. + /* + let f1 = (1,); + let f2 = (2,); + let st5 = St5::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st5.f1, st5.f2)); + */ + + let st6 = St6 { f0: "bar", f1: 24u8, f2: &true, f3: 12u16, }; + assert_eq!(("bar", 24, &true, 12), (st6.f0, st6.f1, st6.f2, st6.f3)); + + let stself = StSelf::<&'static str> { f2: 42u8 }; + assert_eq!(stself.f2, 42u8); +} diff --git a/src/test/ui/associated-type-bounds/trait-params.rs b/src/test/ui/associated-type-bounds/trait-params.rs new file mode 100644 index 00000000000..a9081d50cfc --- /dev/null +++ b/src/test/ui/associated-type-bounds/trait-params.rs @@ -0,0 +1,116 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +use std::iter::Once; +use std::ops::Range; + +pub trait Three { type A; type B; type C; } +pub fn assert_three<T: ?Sized + Three>() {} +pub fn assert_iterator<T: Iterator>() {} +pub fn assert_copy<T: Copy>() {} +pub fn assert_static<T: 'static>() {} +pub fn assert_send<T: Send>() {} +pub fn assert_forall_into<T: for<'a> 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<u8>; type B = Range<u8>; type C = Range<u8>; } + +trait Case1<A, B, C, D, E> +where + A: Iterator<Item: Copy>, + B: Iterator<Item: 'static>, + C: Iterator<Item: 'static + Copy + Send>, + D: Iterator<Item: for<'a> Into<&'a u8>>, + E: Three<A: Iterator<Item: Copy>, B: Iterator<Item: Copy>, C: Iterator<Item: Copy>>, + Self: Three<A: 'static, B: Copy, C: Send>, +{ + fn _a() { + assert_iterator::<A>(); + assert_copy::<A::Item>(); + } + fn _b() { + assert_iterator::<B>(); + assert_static::<B::Item>(); + } + fn _c() { + assert_iterator::<C>(); + assert_copy::<C::Item>(); + assert_static::<C::Item>(); + assert_send::<C::Item>(); + } + fn _d() { + assert_iterator::<D>(); + assert_forall_into::<D::Item>(); + } + fn _e() { + assert_three::<E>(); + assert_iterator::<E::A>(); + assert_iterator::<E::B>(); + assert_iterator::<E::C>(); + assert_copy::<<E::A as Iterator>::Item>(); + assert_copy::<<E::B as Iterator>::Item>(); + assert_copy::<<E::C as Iterator>::Item>(); + } + fn _self() { + assert_three::<Self>(); + assert_copy::<Self::B>(); + assert_static::<Self::A>(); + assert_send::<Self::C>(); + } +} + +struct DataCase1; +impl Three for DataCase1 { type A = u8; type B = u8; type C = u8; } +impl Case1<Range<u8>, Range<u8>, Range<u8>, Once<A>, B> for DataCase1 {} + +trait Case2< + A: Iterator<Item: Copy>, + B: Iterator<Item: 'static>, + C: Iterator<Item: 'static + Copy + Send>, + D: Iterator<Item: for<'a> Into<&'a u8>>, + E: Three<A: Iterator<Item: Copy>, B: Iterator<Item: Copy>, C: Iterator<Item: Copy>>, +>: + Three<A: 'static, B: Copy, C: Send> +{ + fn _a() { + assert_iterator::<A>(); + assert_copy::<A::Item>(); + } + fn _b() { + assert_iterator::<B>(); + assert_static::<B::Item>(); + } + fn _c() { + assert_iterator::<C>(); + assert_copy::<C::Item>(); + assert_static::<C::Item>(); + assert_send::<C::Item>(); + } + fn _d() { + assert_iterator::<D>(); + assert_forall_into::<D::Item>(); + } + fn _e() { + assert_three::<E>(); + assert_iterator::<E::A>(); + assert_iterator::<E::B>(); + assert_iterator::<E::C>(); + assert_copy::<<E::A as Iterator>::Item>(); + assert_copy::<<E::B as Iterator>::Item>(); + assert_copy::<<E::C as Iterator>::Item>(); + } + fn _self() { + assert_three::<Self>(); + assert_copy::<Self::B>(); + assert_static::<Self::A>(); + assert_send::<Self::C>(); + } +} + +struct DataCase2; +impl Three for DataCase2 { type A = u8; type B = u8; type C = u8; } +impl Case2<Range<u8>, Range<u8>, Range<u8>, Once<A>, B> for DataCase2 {} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/type-alias.rs b/src/test/ui/associated-type-bounds/type-alias.rs new file mode 100644 index 00000000000..1602fdd275a --- /dev/null +++ b/src/test/ui/associated-type-bounds/type-alias.rs @@ -0,0 +1,19 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +type _TaWhere1<T> where T: Iterator<Item: Copy> = T; +type _TaWhere2<T> where T: Iterator<Item: 'static> = T; +type _TaWhere3<T> where T: Iterator<Item: 'static> = T; +type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T; +type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T; +type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T; + +type _TaInline1<T: Iterator<Item: Copy>> = T; +type _TaInline2<T: Iterator<Item: 'static>> = T; +type _TaInline3<T: Iterator<Item: 'static>> = T; +type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T; +type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T; +type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T; + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/type-alias.stderr b/src/test/ui/associated-type-bounds/type-alias.stderr new file mode 100644 index 00000000000..b93fc393ae3 --- /dev/null +++ b/src/test/ui/associated-type-bounds/type-alias.stderr @@ -0,0 +1,97 @@ +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:5:25 + | +LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(type_alias_bounds)] on by default + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:6:25 + | +LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:7:25 + | +LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:8:25 + | +LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:9:25 + | +LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:10:25 + | +LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:12:20 + | +LL | type _TaInline1<T: Iterator<Item: Copy>> = T; + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:13:20 + | +LL | type _TaInline2<T: Iterator<Item: 'static>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:14:20 + | +LL | type _TaInline3<T: Iterator<Item: 'static>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:15:20 + | +LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:16:20 + | +LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:17:20 + | +LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + diff --git a/src/test/ui/associated-type-bounds/union-bounds.rs b/src/test/ui/associated-type-bounds/union-bounds.rs new file mode 100644 index 00000000000..ce482fff401 --- /dev/null +++ b/src/test/ui/associated-type-bounds/union-bounds.rs @@ -0,0 +1,123 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +#![allow(unions_with_drop_fields, unused_assignments)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +union Un1<T: Tr1<As1: Tr2>> { + outest: T, + outer: T::As1, + inner: <T::As1 as Tr2>::As2, +} + +union Un2<T: Tr1<As1: Tr2<As2: Tr3>>> { + outest: T, + outer: T::As1, + inner: <T::As1 as Tr2>::As2, +} + +union Un3<T: Tr1<As1: 'static>> { + outest: T, + outer: &'static T::As1, +} + +union Un4<'x1, 'x2, T: Tr1<As1: for<'l> Tr4<'l>>> { + f1: &'x1 <T::As1 as Tr4<'x1>>::As4, + f2: &'x2 <T::As1 as Tr4<'x2>>::As4, +} + +union _Un5<'x1, 'x2, T: Tr1<As1: for<'l> Tr4<'l, As4: Copy>>> { + f1: &'x1 <T::As1 as Tr4<'x1>>::As4, + f2: &'x2 <T::As1 as Tr4<'x2>>::As4, +} + +union Un6<T> +where + T: Tr1<As1: Tr2 + 'static + Tr5>, +{ + f0: T, + f1: <T::As1 as Tr2>::As2, + f2: &'static T::As1, + f3: <T::As1 as Tr5>::As5, +} + +union _Un7<'a, 'b, T> // `<T::As1 as Tr2>::As2: 'a` is implied. +where + T: Tr1<As1: Tr2>, +{ + f0: &'a T, + f1: &'b <T::As1 as Tr2>::As2, +} + +unsafe fn _use_un7<'a, 'b, T>(x: _Un7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +union UnSelf<T> where Self: Tr1<As1: Tr2> { + f0: T, + f1: <Self as Tr1>::As1, + f2: <<Self as Tr1>::As1 as Tr2>::As2, +} + +impl Tr1 for UnSelf<&'static str> { type As1 = bool; } + +fn main() { + let mut un1 = Un1 { outest: "foo" }; + un1 = Un1 { outer: true }; + assert_eq!(unsafe { un1.outer }, true); + un1 = Un1 { inner: 42u8 }; + assert_eq!(unsafe { un1.inner }, 42u8); + + let mut un2 = Un2 { outest: "bar" }; + assert_eq!(unsafe { un2.outest }, "bar"); + un2 = Un2 { outer: true }; + assert_eq!(unsafe { un2.outer }, true); + un2 = Un2 { inner: 42u8 }; + assert_eq!(unsafe { un2.inner }, 42u8); + + let mut un3 = Un3 { outest: "baz" }; + assert_eq!(unsafe { un3.outest }, "baz"); + un3 = Un3 { outer: &true }; + assert_eq!(unsafe { *un3.outer }, true); + + let f1 = (1,); + let f2 = (2,); + let mut un4 = Un4::<()> { f1: &f1.0 }; + assert_eq!(1, unsafe { *un4.f1 }); + un4 = Un4 { f2: &f2.0 }; + assert_eq!(2, unsafe { *un4.f2 }); + + let mut un6 = Un6 { f0: "bar" }; + assert_eq!(unsafe { un6.f0 }, "bar"); + un6 = Un6 { f1: 24u8 }; + assert_eq!(unsafe { un6.f1 }, 24u8); + un6 = Un6 { f2: &true }; + assert_eq!(unsafe { un6.f2 }, &true); + un6 = Un6 { f3: 12u16 }; + assert_eq!(unsafe { un6.f3 }, 12u16); + + let mut unself = UnSelf::<_> { f0: "selfish" }; + assert_eq!(unsafe { unself.f0 }, "selfish"); + unself = UnSelf { f1: true }; + assert_eq!(unsafe { unself.f1 }, true); + unself = UnSelf { f2: 24u8 }; + assert_eq!(unsafe { unself.f2 }, 24u8); +} diff --git a/src/test/ui/deprecation/deprecation-in-staged-api.rs b/src/test/ui/deprecation/deprecation-in-staged-api.rs index bcc17c789f5..f667de83b56 100644 --- a/src/test/ui/deprecation/deprecation-in-staged-api.rs +++ b/src/test/ui/deprecation/deprecation-in-staged-api.rs @@ -1,8 +1,8 @@ -// #[deprecated] can't be used in staged api +// #[deprecated] cannot be used in staged API #![feature(staged_api)] #![stable(feature = "stable_test_feature", since = "1.0.0")] #[deprecated] -fn main() { } //~ERROR `#[deprecated]` cannot be used in staged api +fn main() { } //~ ERROR `#[deprecated]` cannot be used in staged API diff --git a/src/test/ui/deprecation/deprecation-in-staged-api.stderr b/src/test/ui/deprecation/deprecation-in-staged-api.stderr index 6a8056ec2d9..c6881d5a573 100644 --- a/src/test/ui/deprecation/deprecation-in-staged-api.stderr +++ b/src/test/ui/deprecation/deprecation-in-staged-api.stderr @@ -1,4 +1,4 @@ -error: `#[deprecated]` cannot be used in staged api, use `#[rustc_deprecated]` instead +error: `#[deprecated]` cannot be used in staged API; use `#[rustc_deprecated]` instead --> $DIR/deprecation-in-staged-api.rs:8:1 | LL | fn main() { } diff --git a/src/test/ui/existential_types/no_revealing_outside_defining_module.rs b/src/test/ui/existential_types/no_revealing_outside_defining_module.rs index 142f2f6d751..04793c67b56 100644 --- a/src/test/ui/existential_types/no_revealing_outside_defining_module.rs +++ b/src/test/ui/existential_types/no_revealing_outside_defining_module.rs @@ -9,7 +9,7 @@ mod boo { } } -// don't actually know the type here +// We don't actually know the type here. fn bomp2() { let _: &str = bomp(); //~ ERROR mismatched types diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs new file mode 100644 index 00000000000..3d75251e156 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -0,0 +1,72 @@ +#![feature(untagged_unions)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; } + +trait _Tr3 { + type A: Iterator<Item: Copy>; + //~^ ERROR associated type bounds are unstable + + type B: Iterator<Item: 'static>; + //~^ ERROR associated type bounds are unstable +} + +struct _St1<T: Tr1<As1: Tr2>> { +//~^ ERROR associated type bounds are unstable + outest: T, + outer: T::As1, + inner: <T::As1 as Tr2>::As2, +} + +enum _En1<T: Tr1<As1: Tr2>> { +//~^ ERROR associated type bounds are unstable + Outest(T), + Outer(T::As1), + Inner(<T::As1 as Tr2>::As2), +} + +union _Un1<T: Tr1<As1: Tr2>> { +//~^ ERROR associated type bounds are unstable + outest: T, + outer: T::As1, + inner: <T::As1 as Tr2>::As2, +} + +type _TaWhere1<T> where T: Iterator<Item: Copy> = T; +//~^ ERROR associated type bounds are unstable + +fn _apit(_: impl Tr1<As1: Copy>) {} +//~^ ERROR associated type bounds are unstable +fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {} +//~^ ERROR associated type bounds are unstable + +fn _rpit() -> impl Tr1<As1: Copy> { S1 } +//~^ ERROR associated type bounds are unstable + +fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) } +//~^ ERROR associated type bounds are unstable + +const _cdef: impl Tr1<As1: Copy> = S1; +//~^ ERROR associated type bounds are unstable +//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1; + +static _sdef: impl Tr1<As1: Copy> = S1; +//~^ ERROR associated type bounds are unstable +//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1; + +fn main() { + let _: impl Tr1<As1: Copy> = S1; + //~^ ERROR associated type bounds are unstable + //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] + // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. + // let _: &dyn Tr1<As1: Copy> = &S1; +} diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr new file mode 100644 index 00000000000..702f61262df --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -0,0 +1,145 @@ +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:12:22 + | +LL | type A: Iterator<Item: Copy>; + | ^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:15:22 + | +LL | type B: Iterator<Item: 'static>; + | ^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:19:20 + | +LL | struct _St1<T: Tr1<As1: Tr2>> { + | ^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:26:18 + | +LL | enum _En1<T: Tr1<As1: Tr2>> { + | ^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:33:19 + | +LL | union _Un1<T: Tr1<As1: Tr2>> { + | ^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:40:37 + | +LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T; + | ^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:43:22 + | +LL | fn _apit(_: impl Tr1<As1: Copy>) {} + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:45:26 + | +LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {} + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:48:24 + | +LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 } + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:51:31 + | +LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) } + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:54:23 + | +LL | const _cdef: impl Tr1<As1: Copy> = S1; + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:60:24 + | +LL | static _sdef: impl Tr1<As1: Copy> = S1; + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:67:21 + | +LL | let _: impl Tr1<As1: Copy> = S1; + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:54:14 + | +LL | const _cdef: impl Tr1<As1: Copy> = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:60:15 + | +LL | static _sdef: impl Tr1<As1: Copy> = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:67:12 + | +LL | let _: impl Tr1<As1: Copy> = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error: aborting due to 16 previous errors + +Some errors have detailed explanations: E0562, E0658. +For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 4b7c04f1e43..b1e4edd9980 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -5,7 +5,7 @@ LL | fn elided(x: &i32) -> impl Copy { x } | - ^^^^^^^^^ opaque type requires that `'1` must outlive `'static` | | | let's call the lifetime of this reference `'1` -help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | -- ^^^^^^^^^ opaque type requires that `'a` must outlive `'static` | | | lifetime `'a` defined here -help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr index 0bf120cf7ec..0736f25cb51 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr @@ -5,7 +5,7 @@ LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> { | - ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` | | | let's call the lifetime of this reference `'1` -help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint | LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> { | -- ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static` | | | lifetime `'a` defined here -help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint | LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index fabaea0535f..c4f6e021262 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,5 +1,5 @@ thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1085:5 -note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic diff --git a/src/test/ui/symbol-names/basic.stderr b/src/test/ui/symbol-names/basic.stderr new file mode 100644 index 00000000000..7539cbada8b --- /dev/null +++ b/src/test/ui/symbol-names/basic.stderr @@ -0,0 +1,14 @@ +error: symbol-name(_ZN5basic4main17hd72940ef9669d526E) + --> $DIR/basic.rs:3:1 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(main) + --> $DIR/basic.rs:4:1 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr new file mode 100644 index 00000000000..20e48782a3a --- /dev/null +++ b/src/test/ui/symbol-names/impl1.stderr @@ -0,0 +1,26 @@ +error: symbol-name(_ZN5impl13foo3Foo3bar17he53b9bee7600ed8dE) + --> $DIR/impl1.rs:8:9 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(foo::Foo::bar) + --> $DIR/impl1.rs:9:9 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h86c41f0462d901d4E) + --> $DIR/impl1.rs:18:9 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(bar::<impl foo::Foo>::baz) + --> $DIR/impl1.rs:19:9 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs index e2be2b98902..f3cc5becc6f 100644 --- a/src/test/ui/type/type-alias-bounds.rs +++ b/src/test/ui/type/type-alias-bounds.rs @@ -1,44 +1,44 @@ -// Test ignored_generic_bounds lint warning about bounds in type aliases +// Test `ignored_generic_bounds` lint warning about bounds in type aliases. // compile-pass #![allow(dead_code)] use std::rc::Rc; -type SVec<T: Send+Send> = Vec<T>; +type SVec<T: Send + Send> = Vec<T>; //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type S2Vec<T> where T: Send = Vec<T>; //~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] -type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); +type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] -type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>); +type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); //~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] -static STATIC : u32 = 0; +static STATIC: u32 = 0; fn foo<'a>(y: &'a i32) { // If any of the bounds above would matter, the code below would be rejected. // This can be seen when replacing the type aliases above by newtype structs. // (The type aliases have no unused parameters to make that a valid transformation.) - let mut x : SVec<_> = Vec::new(); + let mut x: SVec<_> = Vec::new(); x.push(Rc::new(42)); // is not send - let mut x : S2Vec<_> = Vec::new(); - x.push(Rc::new(42)); // is not send + let mut x: S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not `Send` - let mut x : VVec<'static, 'a> = (&STATIC, Vec::new()); - x.1.push(y); // 'a: 'static does not hold + let mut x: VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // `'a: 'static` does not hold - let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new()); - x.1.push(y); // &'a i32: 'static does not hold + let mut x: WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold - let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); - x.1.push(y); // &'a i32: 'static does not hold + let mut x: W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold } -// Bounds are not checked either, i.e., the definition is not necessarily well-formed +// Bounds are not checked either; i.e., the definition is not necessarily well-formed. struct Sendable<T: Send>(T); type MySendable<T> = Sendable<T>; // no error here! @@ -47,9 +47,9 @@ trait Bound { type Assoc; } type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases -// This errors -// type T3<U> = U::Assoc; -// Do this instead +// This errors: +// `type T3<U> = U::Assoc;` +// Do this instead: type T4<U> = <U as Bound>::Assoc; // Make sure the help about associatd types is not shown incorrectly diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr index 3cc844365fd..177e5f893ed 100644 --- a/src/test/ui/type/type-alias-bounds.stderr +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -1,8 +1,8 @@ warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:8:14 | -LL | type SVec<T: Send+Send> = Vec<T>; - | ^^^^ ^^^^ +LL | type SVec<T: Send + Send> = Vec<T>; + | ^^^^ ^^^^ | = note: #[warn(type_alias_bounds)] on by default = help: the bound will not be checked when the type alias is used, and should be removed @@ -18,16 +18,16 @@ LL | type S2Vec<T> where T: Send = Vec<T>; warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:12:19 | -LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); - | ^^ ^^ +LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ | = help: the bound will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:14:18 | -LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>); - | ^^ ^^ +LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); + | ^^ ^^ | = help: the bound will not be checked when the type alias is used, and should be removed |
