Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Tests for RFC 2289, Associated type bounds
// run-pass
use core::fmt::Debug;
use core::iter::{Empty, Once};
use core::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>;
type C: Clone + Iterator<Item:
Send + Iterator<Item:
for<'a> Lam<&'a u8, App:
Debug
>
> + Sync>;
// Let's be really annoying and introduce a `for<'a>` binder in an outer
// ATB which is then used in an inner ATB:
type D: Clone + Iterator<Item: // <- Outer ATB
Send + for<'a> Iterator<Item: // <- Inner ATB
for<'b> Lam<&'a &'b u8, App:
Debug
>
> + Sync>;
}
pub struct S1;
impl Case1 for S1 {
type A = Empty<String>;
type B = Range<u16>;
type C = Once<Once<L1>>;
type D = Once<Once<L2>>;
}
fn _assume_case1<T: Case1>() {
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 assert_d<_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>,
_0: Debug,
{}
assert_d::<_, _, _, T::D>();
}
// compile-fail
struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
const CIT1: impl Iterator<Item: Copy, Item: Send> = ();
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
const CIT2: impl Iterator<Item: Copy, Item: Copy> = ();
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
const CIT3: impl Iterator<Item: 'static, Item: 'static> = ();
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
static SIT1: impl Iterator<Item: Copy, Item: Send> = ();
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
static SIT2: impl Iterator<Item: Copy, Item: Copy> = ();
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
static SIT3: impl Iterator<Item: 'static, Item: 'static> = ();
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = (); }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = (); }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = (); }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
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
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
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
existential type ETAI1: Iterator<Item: Copy, Item: Send>;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
existential type ETAI2: Iterator<Item: Copy, Item: Copy>;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
existential type ETAI3: Iterator<Item: 'static, Item: 'static>;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRS1: Iterator<Item: Copy, Item: Send> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRS2: Iterator<Item: Copy, Item: Copy> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRS3: Iterator<Item: 'static, Item: 'static> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SDyn1 { f: dyn Iterator<Item: Copy, Item: Send> };
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SDyn2 { f: Box<dyn Iterator<Item: Copy, Item: Copy>> };
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
struct SDyn3 { f: dyn Iterator<Item: 'static, Item: 'static> };
// ~^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
// run-pass
#![feature(existential_type)]
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()); }
use core::ops::Add;
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();
}
// run-pass
#![feature(impl_trait_in_bindings)]
#![allow(non_upper_case_globals)]
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()); }
use core::ops::Add;
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();
}
// run-pass
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()); }
use core::ops::Add;
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();
}
// compile-pass
trait Tr1: Sized { type As1; }
trait Tr2<'a>: Sized { type As1; }
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>) {}
// run-pass
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);
}
// run-pass
#![feature(existential_type)]
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()); }
use core::ops::Add;
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();
}
// run-pass
use fn_aux::*;
// ATB, APIT:
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));
}
// run-pass
// 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));
}
// Check dynamic semantics:
fn main() {
desugared();
}
// run-pass
use fn_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 Copy + Beta<Gamma: Alpha + 'static + Delta>
) -> 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));
}
// run-pass
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(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 inline() {
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::<BetaType>(beta));
assert_eq!(42 + 1337, inline_bound_nested::<BetaType>(beta));
}
// run-pass
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(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));
}
// run-pass
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(beta));
assert_eq!(24, wrap_apit_bound_region(beta));
assert_eq!(42 + 24 + 1337, wrap_apit_bound_multi(beta));
assert_eq!(7331 * 2, wrap_apit_bound_region_forall(beta));
assert_eq!(42 + 1337, wrap_apit_bound_nested(beta));
assert_eq!(42 + 1337, wrap_apit_bound_nested2(beta));
}
// compile-fail
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[E0623]: lifetime mismatch
}
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[E0623]: lifetime mismatch
},
En7::V1(_) => {},
}
}
// run-pass
#![feature(impl_trait_in_bindings)]
#![allow(non_upper_case_globals)]
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()); }
use core::ops::Add;
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();
}
// run-pass
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()); }
use core::ops::Add;
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();
}
// run-pass
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: This won't work due to lack of lazy norm:
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);
}
// compile-pass
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>>() {}
use core::ops::Range;
use core::iter::Once;
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 {}
// compile-pass
// These constraints have no effect:
type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
// ~^ WARNING where clauses are not enforced in type aliases
type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
// ~^ WARNING where clauses are not enforced in type aliases
type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
// ~^ WARNING where clauses are not enforced in type aliases
type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + S
// ~^ WARNING where clauses are not enforced in type aliasesend> = T;
type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
// ~^ WARNING where clauses are not enforced in type aliases
type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
// ~^ WARNING where clauses are not enforced in type aliases
type _TaInline1<T: Iterator<Item: Copy>> = T;
// ~^ WARNING bounds on generic parameters are not enforced in type aliases
type _TaInline2<T: Iterator<Item: 'static>> = T;
// ~^ WARNING bounds on generic parameters are not enforced in type aliases
type _TaInline3<T: Iterator<Item: 'static>> = T;
// ~^ WARNING bounds on generic parameters are not enforced in type aliases
type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
// ~^ WARNING bounds on generic parameters are not enforced in type aliases
type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
// ~^ WARNING bounds on generic parameters are not enforced in type aliases
type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
// ~^ WARNING bounds on generic parameters are not enforced in type aliases
// run-pass
#![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);
}
@Centril

This comment has been minimized.

Copy link
Owner Author

Centril commented Mar 4, 2019

  • Add a lot of compile-fail tests.
    • Failing when duplicate mentions of associated item.
  • Add tests for traits.
    • Inline quantification bounds
    • In where clauses
    • In supertrait bounds.
    • Add tests for bounds on associated types in traits.
  • Add tests for existential type.
  • Add tests for existential associated types
  • Add tests for type aliases.
  • Add tests for methods
    • Object safety.
  • Add tests for dyn Trait.
    • In fn
    • In let + static + const
    • In type (existential type)
    • In impl ... for ... { type Foo: Bar<dyn Baz<Quux: Wibble>>; }
    • In associated type defaults (should probably be deferred to work on ATDs)
    • In impl ... for dyn Foo<Bar: Baz> (run-pass or compile-fail? TBD...)
    • In static, enum, and union fields (run-pass or compile-fail? TBD...)
  • Add tests for RPIT.
  • Add tests for CIIT
  • Add tests for SIIT.
  • Add tests for LBIT.
  • Add tests for TypeAscriptionIT.
  • Add tests for AsIT.
  • Take a look at type grammar and where bounds may occur.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.