-
Notifications
You must be signed in to change notification settings - Fork 12.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Alexander Regueiro
committed
Jun 5, 2019
1 parent
cad1b18
commit 4310ba2
Showing
36 changed files
with
3,138 additions
and
11 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
// Traits: | ||
|
||
pub trait Alpha { | ||
fn alpha(self) -> usize; | ||
} | ||
|
||
pub trait Beta { | ||
type Gamma; | ||
fn gamma(self) -> Self::Gamma; | ||
} | ||
|
||
pub trait Delta { | ||
fn delta(self) -> usize; | ||
} | ||
|
||
pub trait Epsilon<'a> { | ||
type Zeta; | ||
fn zeta(&'a self) -> Self::Zeta; | ||
|
||
fn epsilon(&'a self) -> usize; | ||
} | ||
|
||
pub trait Eta { | ||
fn eta(self) -> usize; | ||
} | ||
|
||
// Assertions: | ||
|
||
pub fn assert_alpha<T: Alpha>(x: T) -> usize { x.alpha() } | ||
pub fn assert_static<T: 'static>(_: T) -> usize { 24 } | ||
pub fn assert_delta<T: Delta>(x: T) -> usize { x.delta() } | ||
pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } | ||
pub fn assert_epsilon_forall<T: for<'a> Epsilon<'a>>() {} | ||
pub fn assert_forall_epsilon_zeta_satisfies_eta<T>(x: T) -> usize | ||
where | ||
T: for<'a> Epsilon<'a>, | ||
for<'a> <T as Epsilon<'a>>::Zeta: Eta, | ||
{ | ||
x.epsilon() + x.zeta().eta() | ||
} | ||
|
||
// Implementations and types: | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct BetaType; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct GammaType; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct ZetaType; | ||
|
||
impl Beta for BetaType { | ||
type Gamma = GammaType; | ||
fn gamma(self) -> Self::Gamma { GammaType } | ||
} | ||
|
||
impl<'a> Beta for &'a BetaType { | ||
type Gamma = GammaType; | ||
fn gamma(self) -> Self::Gamma { GammaType } | ||
} | ||
|
||
impl Beta for GammaType { | ||
type Gamma = Self; | ||
fn gamma(self) -> Self::Gamma { self } | ||
} | ||
|
||
impl Alpha for GammaType { | ||
fn alpha(self) -> usize { 42 } | ||
} | ||
|
||
impl Delta for GammaType { | ||
fn delta(self) -> usize { 1337 } | ||
} | ||
|
||
impl<'a> Epsilon<'a> for GammaType { | ||
type Zeta = ZetaType; | ||
fn zeta(&'a self) -> Self::Zeta { ZetaType } | ||
|
||
fn epsilon(&'a self) -> usize { 7331 } | ||
} | ||
|
||
impl Eta for ZetaType { | ||
fn eta(self) -> usize { 7 } | ||
} | ||
|
||
// Desugared forms to check against: | ||
|
||
pub fn desugared_bound<B>(beta: B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Alpha | ||
{ | ||
let gamma: B::Gamma = beta.gamma(); | ||
assert_alpha::<B::Gamma>(gamma) | ||
} | ||
|
||
pub fn desugared_bound_region<B>(beta: B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: 'static, | ||
{ | ||
assert_static::<B::Gamma>(beta.gamma()) | ||
} | ||
|
||
pub fn desugared_bound_multi<B>(beta: B) -> usize | ||
where | ||
B: Copy + Beta, | ||
B::Gamma: Alpha + 'static + Delta, | ||
{ | ||
assert_alpha::<B::Gamma>(beta.gamma()) + | ||
assert_static::<B::Gamma>(beta.gamma()) + | ||
assert_delta::<B::Gamma>(beta.gamma()) | ||
} | ||
|
||
pub fn desugared_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: 'a + Epsilon<'a>, | ||
{ | ||
assert_epsilon_specific::<B::Gamma>(gamma) | ||
} | ||
|
||
pub fn desugared_bound_region_forall<B>(beta: B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Copy + for<'a> Epsilon<'a>, | ||
{ | ||
assert_epsilon_forall::<B::Gamma>(); | ||
let g1: B::Gamma = beta.gamma(); | ||
let g2: B::Gamma = g1; | ||
assert_epsilon_specific::<B::Gamma>(&g1) + | ||
assert_epsilon_specific::<B::Gamma>(&g2) | ||
} | ||
|
||
pub fn desugared_bound_region_forall2<B>(beta: B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Copy + for<'a> Epsilon<'a>, | ||
for<'a> <B::Gamma as Epsilon<'a>>::Zeta: Eta, | ||
{ | ||
let gamma = beta.gamma(); | ||
assert_forall_epsilon_zeta_satisfies_eta::<B::Gamma>(gamma) | ||
} | ||
|
||
pub fn desugared_contraint_region_forall<B>(beta: B) -> usize | ||
where | ||
for<'a> &'a B: Beta, | ||
for<'a> <&'a B as Beta>::Gamma: Alpha, | ||
{ | ||
let g1 = beta.gamma(); | ||
let g2 = beta.gamma(); | ||
assert_alpha(g1) + assert_alpha(g2) | ||
} | ||
|
||
pub fn desugared_bound_nested<B>(beta: B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Copy + Alpha + Beta, | ||
<B::Gamma as Beta>::Gamma: Delta, | ||
{ | ||
let go = beta.gamma(); | ||
let gi = go.gamma(); | ||
go.alpha() + gi.delta() | ||
} | ||
|
||
pub fn desugared() { | ||
let beta = BetaType; | ||
let gamma = beta.gamma(); | ||
|
||
assert_eq!(42, desugared_bound(beta)); | ||
assert_eq!(24, desugared_bound_region(beta)); | ||
assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); | ||
assert_eq!(7331, desugared_bound_region_specific::<BetaType>(&gamma)); | ||
assert_eq!(7331 * 2, desugared_bound_region_forall(beta)); | ||
assert_eq!(42 + 1337, desugared_bound_nested(beta)); | ||
} |
182 changes: 182 additions & 0 deletions
182
src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
// Traits: | ||
|
||
pub trait Alpha { | ||
fn alpha(self) -> usize; | ||
} | ||
|
||
pub trait Beta { | ||
type Gamma; | ||
fn gamma(&self) -> Self::Gamma; | ||
} | ||
|
||
pub trait Delta { | ||
fn delta(self) -> usize; | ||
} | ||
|
||
pub trait Epsilon<'a> { | ||
type Zeta; | ||
fn zeta(&'a self) -> Self::Zeta; | ||
|
||
fn epsilon(&'a self) -> usize; | ||
} | ||
|
||
pub trait Eta { | ||
fn eta(self) -> usize; | ||
} | ||
|
||
// Assertions: | ||
|
||
pub fn assert_alpha<T: Alpha>(x: T) -> usize { x.alpha() } | ||
pub fn assert_static<T: 'static>(_: T) -> usize { 24 } | ||
pub fn assert_delta<T: Delta>(x: T) -> usize { x.delta() } | ||
pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } | ||
pub fn assert_epsilon_forall<T: for<'a> Epsilon<'a>>() {} | ||
pub fn assert_forall_epsilon_zeta_satisfies_eta<T>(x: T) -> usize | ||
where | ||
T: for<'a> Epsilon<'a>, | ||
for<'a> <T as Epsilon<'a>>::Zeta: Eta, | ||
{ | ||
x.epsilon() + x.zeta().eta() | ||
} | ||
|
||
// Implementations and types: | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct BetaType; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct GammaType; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct ZetaType; | ||
|
||
impl<T> Beta for &(dyn Beta<Gamma = T> + Send) { | ||
type Gamma = T; | ||
fn gamma(&self) -> Self::Gamma { (*self).gamma() } | ||
} | ||
|
||
impl Beta for BetaType { | ||
type Gamma = GammaType; | ||
fn gamma(&self) -> Self::Gamma { GammaType } | ||
} | ||
|
||
impl<'a> Beta for &'a BetaType { | ||
type Gamma = GammaType; | ||
fn gamma(&self) -> Self::Gamma { GammaType } | ||
} | ||
|
||
impl Beta for GammaType { | ||
type Gamma = Self; | ||
fn gamma(&self) -> Self::Gamma { Self } | ||
} | ||
|
||
impl Alpha for GammaType { | ||
fn alpha(self) -> usize { 42 } | ||
} | ||
|
||
impl Delta for GammaType { | ||
fn delta(self) -> usize { 1337 } | ||
} | ||
|
||
impl<'a> Epsilon<'a> for GammaType { | ||
type Zeta = ZetaType; | ||
fn zeta(&'a self) -> Self::Zeta { ZetaType } | ||
|
||
fn epsilon(&'a self) -> usize { 7331 } | ||
} | ||
|
||
impl Eta for ZetaType { | ||
fn eta(self) -> usize { 7 } | ||
} | ||
|
||
// Desugared forms to check against: | ||
|
||
pub fn desugared_bound<B: ?Sized>(beta: &B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Alpha | ||
{ | ||
let gamma: B::Gamma = beta.gamma(); | ||
assert_alpha::<B::Gamma>(gamma) | ||
} | ||
|
||
pub fn desugared_bound_region<B: ?Sized>(beta: &B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: 'static, | ||
{ | ||
assert_static::<B::Gamma>(beta.gamma()) | ||
} | ||
|
||
pub fn desugared_bound_multi<B: ?Sized>(beta: B) -> usize | ||
where | ||
B: Copy + Beta, | ||
B::Gamma: Alpha + 'static + Delta, | ||
{ | ||
assert_alpha::<B::Gamma>(beta.gamma()) + | ||
assert_static::<B::Gamma>(beta.gamma()) + | ||
assert_delta::<B::Gamma>(beta.gamma()) | ||
} | ||
|
||
pub fn desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: 'a + Epsilon<'a>, | ||
{ | ||
assert_epsilon_specific::<B::Gamma>(gamma) | ||
} | ||
|
||
pub fn desugared_bound_region_forall<B: ?Sized>(beta: &B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Copy + for<'a> Epsilon<'a>, | ||
{ | ||
assert_epsilon_forall::<B::Gamma>(); | ||
let g1: B::Gamma = beta.gamma(); | ||
let g2: B::Gamma = g1; | ||
assert_epsilon_specific::<B::Gamma>(&g1) + | ||
assert_epsilon_specific::<B::Gamma>(&g2) | ||
} | ||
|
||
pub fn desugared_bound_region_forall2<B: ?Sized>(beta: &B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Copy + for<'a> Epsilon<'a>, | ||
for<'a> <B::Gamma as Epsilon<'a>>::Zeta: Eta, | ||
{ | ||
let gamma = beta.gamma(); | ||
assert_forall_epsilon_zeta_satisfies_eta::<B::Gamma>(gamma) | ||
} | ||
|
||
pub fn desugared_contraint_region_forall<B: ?Sized>(beta: &B) -> usize | ||
where | ||
for<'a> &'a B: Beta, | ||
for<'a> <&'a B as Beta>::Gamma: Alpha, | ||
{ | ||
let g1 = beta.gamma(); | ||
let g2 = beta.gamma(); | ||
assert_alpha(g1) + assert_alpha(g2) | ||
} | ||
|
||
pub fn desugared_bound_nested<B: ?Sized>(beta: &B) -> usize | ||
where | ||
B: Beta, | ||
B::Gamma: Copy + Alpha + Beta, | ||
<B::Gamma as Beta>::Gamma: Delta, | ||
{ | ||
let go = beta.gamma(); | ||
let gi = go.gamma(); | ||
go.alpha() + gi.delta() | ||
} | ||
|
||
pub fn desugared() { | ||
let beta = BetaType; | ||
let gamma = beta.gamma(); | ||
|
||
assert_eq!(42, desugared_bound(&beta)); | ||
assert_eq!(24, desugared_bound_region(&beta)); | ||
assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); | ||
assert_eq!(7331, desugared_bound_region_specific::<BetaType>(&gamma)); | ||
assert_eq!(7331 * 2, desugared_bound_region_forall(&beta)); | ||
assert_eq!(42 + 1337, desugared_bound_nested(&beta)); | ||
} |
Oops, something went wrong.