Added test suite.
This commit is contained in:
parent
cad1b1847e
commit
4310ba2c98
@ -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);
|
||||
}
|
||||
|
177
src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs
Normal file
177
src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs
Normal file
@ -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));
|
||||
}
|
182
src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs
Normal file
182
src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs
Normal file
@ -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));
|
||||
}
|
@ -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);
|
||||
}
|
@ -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`.
|
@ -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() {}
|
161
src/test/ui/associated-type-bounds/duplicate.rs
Normal file
161
src/test/ui/associated-type-bounds/duplicate.rs
Normal file
@ -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() {}
|
627
src/test/ui/associated-type-bounds/duplicate.stderr
Normal file
627
src/test/ui/associated-type-bounds/duplicate.stderr
Normal file
@ -0,0 +1,627 @@
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:12:36
|
||||
|
|
||||
LL | struct SI1<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
|
||||
|
||||
For more information about this error, try `rustc --explain E0719`.
|
67
src/test/ui/associated-type-bounds/dyn-existential-type.rs
Normal file
67
src/test/ui/associated-type-bounds/dyn-existential-type.rs
Normal file
@ -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();
|
||||
}
|
69
src/test/ui/associated-type-bounds/dyn-lcsit.rs
Normal file
69
src/test/ui/associated-type-bounds/dyn-lcsit.rs
Normal file
@ -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();
|
||||
}
|
73
src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs
Normal file
73
src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs
Normal file
@ -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();
|
||||
}
|
@ -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() {}
|
122
src/test/ui/associated-type-bounds/enum-bounds.rs
Normal file
122
src/test/ui/associated-type-bounds/enum-bounds.rs
Normal file
@ -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);
|
||||
}
|
67
src/test/ui/associated-type-bounds/existential-type.rs
Normal file
67
src/test/ui/associated-type-bounds/existential-type.rs
Normal file
@ -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();
|
||||
}
|
58
src/test/ui/associated-type-bounds/fn-apit.rs
Normal file
58
src/test/ui/associated-type-bounds/fn-apit.rs
Normal file
@ -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));
|
||||
}
|
12
src/test/ui/associated-type-bounds/fn-aux.rs
Normal file
12
src/test/ui/associated-type-bounds/fn-aux.rs
Normal file
@ -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();
|
||||
}
|
60
src/test/ui/associated-type-bounds/fn-dyn-apit.rs
Normal file
60
src/test/ui/associated-type-bounds/fn-dyn-apit.rs
Normal file
@ -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));
|
||||
}
|
62
src/test/ui/associated-type-bounds/fn-inline.rs
Normal file
62
src/test/ui/associated-type-bounds/fn-inline.rs
Normal file
@ -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));
|
||||
}
|
78
src/test/ui/associated-type-bounds/fn-where.rs
Normal file
78
src/test/ui/associated-type-bounds/fn-where.rs
Normal file
@ -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));
|
||||
}
|
64
src/test/ui/associated-type-bounds/fn-wrap-apit.rs
Normal file
64
src/test/ui/associated-type-bounds/fn-wrap-apit.rs
Normal file
@ -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)));
|
||||
}
|
@ -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() {}
|
@ -0,0 +1,25 @@
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/implied-region-constraints.rs:19:64
|
||||
|
|
||||
LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>)
|
||||
| -------------
|
||||
| |
|
||||
| this type is declared with multiple lifetimes...
|
||||
...
|
||||
LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0;
|
||||
| ^^^^^ ...but data with one lifetime flows into the other here
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/implied-region-constraints.rs:40:72
|
||||
|
|
||||
LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>)
|
||||
| --------------
|
||||
| |
|
||||
| this type is declared with multiple lifetimes...
|
||||
...
|
||||
LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x;
|
||||
| ^^ ...but data with one lifetime flows into the other here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0623`.
|
36
src/test/ui/associated-type-bounds/inside-adt.rs
Normal file
36
src/test/ui/associated-type-bounds/inside-adt.rs
Normal file
@ -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]
|
79
src/test/ui/associated-type-bounds/inside-adt.stderr
Normal file
79
src/test/ui/associated-type-bounds/inside-adt.stderr
Normal file
@ -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`.
|
78
src/test/ui/associated-type-bounds/lcsit.rs
Normal file
78
src/test/ui/associated-type-bounds/lcsit.rs
Normal file
@ -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();
|
||||
}
|
25
src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs
Normal file
25
src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// compile-fail
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
trait Lam<Binder> { type App; }
|
||||
|
||||
fn nested_bounds<_0, _1, _2, D>()
|
||||
where
|
||||
D: Clone + Iterator<Item: Send + for<'a> Iterator<Item: for<'b> Lam<&'a &'b u8, App = _0>>>,
|
||||
//~^ ERROR nested quantification of lifetimes [E0316]
|
||||
_0: Debug,
|
||||
{}
|
||||
|
||||
fn nested_bounds_desugared<_0, _1, _2, D>()
|
||||
where
|
||||
D: Clone + Iterator<Item = _2>,
|
||||
_2: Send + for<'a> Iterator,
|
||||
for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>,
|
||||
//~^ ERROR nested quantification of lifetimes [E0316]
|
||||
_0: Debug,
|
||||
{}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,9 @@
|
||||
error[E0316]: nested quantification of lifetimes
|
||||
--> $DIR/nested-lifetime-bounds.rs:20:37
|
||||
|
|
||||
LL | for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0316`.
|
64
src/test/ui/associated-type-bounds/rpit.rs
Normal file
64
src/test/ui/associated-type-bounds/rpit.rs
Normal file
@ -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();
|
||||
}
|
115
src/test/ui/associated-type-bounds/struct-bounds.rs
Normal file
115
src/test/ui/associated-type-bounds/struct-bounds.rs
Normal file
@ -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);
|
||||
}
|
116
src/test/ui/associated-type-bounds/trait-params.rs
Normal file
116
src/test/ui/associated-type-bounds/trait-params.rs
Normal file
@ -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() {}
|
19
src/test/ui/associated-type-bounds/type-alias.rs
Normal file
19
src/test/ui/associated-type-bounds/type-alias.rs
Normal file
@ -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() {}
|
97
src/test/ui/associated-type-bounds/type-alias.stderr
Normal file
97
src/test/ui/associated-type-bounds/type-alias.stderr
Normal file
@ -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
|
||||
|
123
src/test/ui/associated-type-bounds/union-bounds.rs
Normal file
123
src/test/ui/associated-type-bounds/union-bounds.rs
Normal file
@ -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);
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
trait Tr1 { type As1; }
|
||||
trait Tr2 { type As2; }
|
||||
|
||||
struct S1;
|
||||
#[derive(Copy, Clone)]
|
||||
struct S2;
|
||||
impl Tr1 for S1 { type As1 = S2; }
|
||||
|
||||
trait _Tr3 {
|
||||
type A: Iterator<Item: Copy>;
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
|
||||
type B: Iterator<Item: 'static>;
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
}
|
||||
|
||||
struct _St1<T: Tr1<As1: Tr2>> {
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
outest: T,
|
||||
outer: T::As1,
|
||||
inner: <T::As1 as Tr2>::As2,
|
||||
}
|
||||
|
||||
enum _En1<T: Tr1<As1: Tr2>> {
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
Outest(T),
|
||||
Outer(T::As1),
|
||||
Inner(<T::As1 as Tr2>::As2),
|
||||
}
|
||||
|
||||
union _Un1<T: Tr1<As1: Tr2>> {
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
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 (see issue #52662) [E0658]
|
||||
|
||||
fn _apit(_: impl Tr1<As1: Copy>) {}
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
|
||||
fn _rpit() -> impl Tr1<As1: Copy> { S1 }
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
|
||||
const _cdef: impl Tr1<As1: Copy> = S1;
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
|
||||
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
|
||||
// const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1;
|
||||
|
||||
static _sdef: impl Tr1<As1: Copy> = S1;
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
|
||||
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
|
||||
// static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1;
|
||||
|
||||
fn main() {
|
||||
let _: impl Tr1<As1: Copy> = S1;
|
||||
//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658]
|
||||
//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
|
||||
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
|
||||
// let _: &dyn Tr1<As1: Copy> = &S1;
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:12:22
|
||||
|
|
||||
LL | type A: Iterator<Item: Copy>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:15:22
|
||||
|
|
||||
LL | type B: Iterator<Item: 'static>;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:19:20
|
||||
|
|
||||
LL | struct _St1<T: Tr1<As1: Tr2>> {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:26:18
|
||||
|
|
||||
LL | enum _En1<T: Tr1<As1: Tr2>> {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:33:19
|
||||
|
|
||||
LL | union _Un1<T: Tr1<As1: Tr2>> {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:40:37
|
||||
|
|
||||
LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:43:22
|
||||
|
|
||||
LL | fn _apit(_: impl Tr1<As1: Copy>) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:45:26
|
||||
|
|
||||
LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:48:24
|
||||
|
|
||||
LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:50:31
|
||||
|
|
||||
LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:53:23
|
||||
|
|
||||
LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:59:24
|
||||
|
|
||||
LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable (see issue #52662)
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:66:21
|
||||
|
|
||||
LL | let _: impl Tr1<As1: Copy> = S1;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(associated_type_bounds)] to the crate attributes to enable
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/feature-gate-associated_type_bounds.rs:53:14
|
||||
|
|
||||
LL | const _cdef: impl Tr1<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:59: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:66: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 occurred: E0562, E0658.
|
||||
For more information about an error, try `rustc --explain E0562`.
|
@ -1,13 +1,3 @@
|
||||
warning: duplicate auto trait `::marker[0]::Send[0]` found in type parameter bounds
|
||||
--> $DIR/type-alias-bounds.rs:8:14
|
||||
|
|
||||
LL | type SVec<T: Send + Send> = Vec<T>;
|
||||
| ^^^^ ^^^^ subsequent use of auto trait
|
||||
| |
|
||||
| first use of auto trait
|
||||
|
|
||||
= note: #[warn(duplicate_auto_traits_in_bounds)] on by default
|
||||
|
||||
warning: bounds on generic parameters are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:8:14
|
||||
|
|
||||
|
Loading…
x
Reference in New Issue
Block a user