Last active
March 6, 2019 18:20
-
-
Save Centril/2470b7f89657da457ed25078a9cdab72 to your computer and use it in GitHub Desktop.
Tests for RFC 2289, Associated type bounds
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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>(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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>) {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(_) => {}, | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
existential type
.dyn Trait
.fn
let
+static
+const
type
(existential type)impl ... for ... { type Foo: Bar<dyn Baz<Quux: Wibble>>; }
impl ... for dyn Foo<Bar: Baz>
(run-pass or compile-fail? TBD...)static
,enum
, andunion
fields (run-pass or compile-fail? TBD...)Add tests for TypeAscriptionIT.Add tests for AsIT.