Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
131 changes: 131 additions & 0 deletions tests/pretty/delegation/generics.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
//@ pretty-compare-only
//@ pretty-mode:hir
//@ pp-exact:generics.pp

#![allow(incomplete_features)]
#![attr = Feature([fn_delegation#0])]
extern crate std;
#[attr = PreludeImport]
use ::std::prelude::rust_2015::*;

mod free_to_trait {
trait Trait<'a, XX, Y, T = (), const N: usize = 2> {
fn method<A, B>(&self, t: (T, A, B), slice: &'_ [usize; N]) { }
fn r#static<A, B>(t: (T, A, B), slice: &'_ [usize; N]) { }
}

struct X;
impl <XX, Y, T, const N: usize> Trait<'_, XX, Y, T, N> for X { }

// When infer is specified for default parameter the generic param is generated.
#[attr = Inline(Hint)]
fn foo<'a, Self, XX, Y, T, const N: _, A, B>(self: _, arg1: _, arg2: _)
-> _ where
'a:'a {
<Self as Trait::<'a, XX, Y, T, N>>::method::<A, B>(self, arg1, arg2)
}
#[attr = Inline(Hint)]
fn static_foo<'a, Self, XX, Y, T, const N: _, A, B>(arg0: _, arg1: _) -> _
where
'a:'a {
<Self as Trait::<'a, XX, Y, T, N>>::r#static::<A, B>(arg0, arg1)
}

// When default params are omitted they are not generated but used in signature inheritance.
#[attr = Inline(Hint)]
fn bar<'a, Self, XX, Y, A, B>(self: _, arg1: _, arg2: _) -> _ where
'a:'a {
<Self as Trait::<'a, XX, Y>>::method::<A, B>(self, arg1, arg2)
}
#[attr = Inline(Hint)]
fn static_bar<'a, Self, XX, Y, A, B>(arg0: _, arg1: _) -> _ where
'a:'a { <Self as Trait::<'a, XX, Y>>::r#static::<A, B>(arg0, arg1) }

// Check with user specified args in child:
// When infer is specified for default parameter the generic param is generated.
#[attr = Inline(Hint)]
fn foo1<'a, Self, XX, Y, T, const N: _, B>(self: _, arg1: _, arg2: _) -> _
where
'a:'a {
<Self as Trait::<'a, XX, Y, T, N>>::method::<(), B>(self, arg1, arg2)
}
#[attr = Inline(Hint)]
fn static_foo1<'a, Self, XX, Y, T, const N: _, B>(arg0: _, arg1: _) -> _
where
'a:'a {
<Self as Trait::<'a, XX, Y, T, N>>::r#static::<(), B>(arg0, arg1)
}

// When default params are omitted they are not generated but used in signature inheritance.
#[attr = Inline(Hint)]
fn bar1<'a, Self, XX, Y, A>(self: _, arg1: _, arg2: _) -> _ where
'a:'a {
<Self as Trait::<'a, XX, Y>>::method::<A, ()>(self, arg1, arg2)
}
#[attr = Inline(Hint)]
fn static_bar1<'a, Self, XX, Y, A>(arg0: _, arg1: _) -> _ where
'a:'a { <Self as Trait::<'a, XX, Y>>::r#static::<A, ()>(arg0, arg1) }

// Check with explicit self type.
#[attr = Inline(Hint)]
fn foo2<'a, XX, Y, T, const N: _, A, B>(self: _, arg1: _, arg2: _) -> _
where
'a:'a {
<X as Trait::<'a, XX, Y, T, N>>::method::<A, B>(self, arg1, arg2)
}
#[attr = Inline(Hint)]
fn static_foo2<'a, XX, Y, T, const N: _, A, B>(arg0: _, arg1: _) -> _
where
'a:'a {
<X as Trait::<'a, XX, Y, T, N>>::r#static::<A, B>(arg0, arg1)
}

#[attr = Inline(Hint)]
fn bar2<'a, XX, Y, A, B>(self: _, arg1: _, arg2: _) -> _ where
'a:'a { <X as Trait::<'a, XX, Y>>::method::<A, B>(self, arg1, arg2) }
#[attr = Inline(Hint)]
fn static_bar2<'a, XX, Y, A, B>(arg0: _, arg1: _) -> _ where
'a:'a { <X as Trait::<'a, XX, Y>>::r#static::<A, B>(arg0, arg1) }

#[attr = Inline(Hint)]
fn foo3<'a, XX, Y, T, const N: _, B>(self: _, arg1: _, arg2: _) -> _ where
'a:'a {
<X as Trait::<'a, XX, Y, T, N>>::method::<(), B>(self, arg1, arg2)
}
#[attr = Inline(Hint)]
fn static_foo3<'a, XX, Y, T, const N: _, B>(arg0: _, arg1: _) -> _ where
'a:'a {
<X as Trait::<'a, XX, Y, T, N>>::r#static::<(), B>(arg0, arg1)
}

#[attr = Inline(Hint)]
fn bar3<'a, XX, Y, A>(self: _, arg1: _, arg2: _) -> _ where
'a:'a { <X as Trait::<'a, XX, Y>>::method::<A, ()>(self, arg1, arg2) }
#[attr = Inline(Hint)]
fn static_bar3<'a, XX, Y, A>(arg0: _, arg1: _) -> _ where
'a:'a { <X as Trait::<'a, XX, Y>>::r#static::<A, ()>(arg0, arg1) }
}

mod trait_impl_to_trait {
trait Trait<'a, X, Y, T = (), const N: usize = 2> {
fn foo(&self, t: (T, T, T), slice: &'_ [usize; N]) { }
fn bar(&self, t: (T, T, T), slice: &'_ [usize; N]) { }
}

struct S;
impl <X, Y> Trait<'_, X, Y> for S { }

struct W(S);
impl <X, Y> Trait<'_, X, Y> for W {
// Generics of both methods match generics of their signature
// functions in `Trait` declaration, no matter specified infers.
#[attr = Inline(Hint)]
fn foo(self: _, arg1: _, arg2: _)
-> _ { Trait::<'static, X, Y>::foo(self.0, arg1, arg2) }
#[attr = Inline(Hint)]
fn bar(self: _, arg1: _, arg2: _)
-> _ { Trait::<'static, X, Y, _, _>::foo(self.0, arg1, arg2) }
}
}

fn main() { }
66 changes: 66 additions & 0 deletions tests/pretty/delegation/generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//@ pretty-compare-only
//@ pretty-mode:hir
//@ pp-exact:generics.pp

#![allow(incomplete_features)]
#![feature(fn_delegation)]

mod free_to_trait {
trait Trait<'a, XX, Y, T = (), const N: usize = 2> {
fn method<A, B>(&self, t: (T, A, B), slice: &[usize; N]) {}
fn r#static<A, B>(t: (T, A, B), slice: &[usize; N]) {}
}

struct X;
impl<XX, Y, T, const N: usize> Trait<'_, XX, Y, T, N> for X {}

// When infer is specified for default parameter the generic param is generated.
reuse Trait::<'_, _, _, _, _>::method as foo;
reuse Trait::<'_, _, _, _, _>::r#static as static_foo;

// When default params are omitted they are not generated but used in signature inheritance.
reuse Trait::<'_, _, _>::method as bar;
reuse Trait::<'_, _, _>::r#static as static_bar;

// Check with user specified args in child:
// When infer is specified for default parameter the generic param is generated.
reuse Trait::<'_, _, _, _, _>::method::<(), _> as foo1;
reuse Trait::<'_, _, _, _, _>::r#static::<(), _> as static_foo1;

// When default params are omitted they are not generated but used in signature inheritance.
reuse Trait::<'_, _, _>::method::<_, ()> as bar1;
reuse Trait::<'_, _, _>::r#static::<_, ()> as static_bar1;

// Check with explicit self type.
reuse <X as Trait::<'_, _, _, _, _>>::method as foo2;
reuse <X as Trait::<'_, _, _, _, _>>::r#static as static_foo2;

reuse <X as Trait::<'_, _, _>>::method as bar2;
reuse <X as Trait::<'_, _, _>>::r#static as static_bar2;

reuse <X as Trait::<'_, _, _, _, _>>::method::<(), _> as foo3;
reuse <X as Trait::<'_, _, _, _, _>>::r#static::<(), _> as static_foo3;

reuse <X as Trait::<'_, _, _>>::method::<_, ()> as bar3;
reuse <X as Trait::<'_, _, _>>::r#static::<_, ()> as static_bar3;
}

mod trait_impl_to_trait {
trait Trait<'a, X, Y, T = (), const N: usize = 2> {
fn foo(&self, t: (T, T, T), slice: &[usize; N]) {}
fn bar(&self, t: (T, T, T), slice: &[usize; N]) {}
}

struct S;
impl<X, Y> Trait<'_, X, Y> for S {}

struct W(S);
impl<X, Y> Trait<'_, X, Y> for W {
// Generics of both methods match generics of their signature
// functions in `Trait` declaration, no matter specified infers.
reuse Trait::<'static, X, Y>::foo { self.0 }
reuse Trait::<'static, X, Y, _, _>::foo as bar { self.0 }
}
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![no_std]
//@ pretty-compare-only
//@ pretty-mode:expanded
//@ pp-exact:delegation-impl-reuse.pp
//@ pp-exact:impl-reuse.pp

#![allow(incomplete_features)]
#![feature(fn_delegation)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ pretty-compare-only
//@ pretty-mode:expanded
//@ pp-exact:delegation-impl-reuse.pp
//@ pp-exact:impl-reuse.pp

#![allow(incomplete_features)]
#![feature(fn_delegation)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@ aux-crate:to_reuse_functions=to-reuse-functions.rs
//@ pretty-mode:hir
//@ pretty-compare-only
//@ pp-exact:delegation-inherit-attributes.pp
//@ pp-exact:inherit-attributes.pp

#![allow(incomplete_features)]
#![attr = Feature([fn_delegation#0])]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@ aux-crate:to_reuse_functions=to-reuse-functions.rs
//@ pretty-mode:hir
//@ pretty-compare-only
//@ pp-exact:delegation-inherit-attributes.pp
//@ pp-exact:inherit-attributes.pp

#![allow(incomplete_features)]
#![feature(fn_delegation)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ pretty-compare-only
//@ pretty-mode:hir
//@ pp-exact:delegation-inline-attribute.pp
//@ pp-exact:inline-attribute.pp

#![allow(incomplete_features)]
#![attr = Feature([fn_delegation#0])]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ pretty-compare-only
//@ pretty-mode:hir
//@ pp-exact:delegation-inline-attribute.pp
//@ pp-exact:inline-attribute.pp

#![allow(incomplete_features)]
#![feature(fn_delegation)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use ::std::prelude::rust_2015::*;
//@ pretty-compare-only
//@ pretty-mode:hir
//@ pp-exact:delegation-self-rename.pp
//@ pp-exact:self-rename.pp


trait Trait<'a, A, const B: bool> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ pretty-compare-only
//@ pretty-mode:hir
//@ pp-exact:delegation-self-rename.pp
//@ pp-exact:self-rename.pp

#![feature(fn_delegation)]

Expand Down
124 changes: 124 additions & 0 deletions tests/ui/delegation/generics/infer-defaults.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#![feature(fn_delegation)]

mod free_to_trait {
trait Trait<'a, XX, Y, T = (), const N: usize = 2> {
fn foo<A, B>(&self, t: (T, A, B), slice: &[usize; N]) {}
}

struct X;
impl<XX, Y, T, const N: usize> Trait<'_, XX, Y, T, N> for X {}

// When infer is specified for default parameter the generic param is generated.
reuse Trait::<'_, _, _, _, _>::foo as foo;
// When default params are omitted they are not generated but used in signature inheritance.
reuse Trait::<'_, _, _>::foo as bar;

// Check with user specified args in child:
// When infer is specified for default parameter the generic param is generated.
reuse Trait::<'_, _, _, _, _>::foo::<(), _> as foo1;
// When default params are omitted they are not generated but used in signature inheritance.
reuse Trait::<'_, _, _>::foo::<_, ()> as bar1;

// Check with explicit self type.
reuse <X as Trait::<'_, _, _, _, _>>::foo as foo2;
reuse <X as Trait::<'_, _, _>>::foo as bar2;

reuse <X as Trait::<'_, _, _, _, _>>::foo::<(), _> as foo3;
reuse <X as Trait::<'_, _, _>>::foo::<_, ()> as bar3;

fn check() {
foo::<'static, X, (), (), (), 1, (), ()>(&X, ((), (), ()), &[1]);
bar::<'static, X, (), (), (), ()>(&X, ((), (), ()), &[1, 2]);

foo1::<'static, X, (), (), (), 2, ()>(&X, ((), (), ()), &[1, 2]);
bar1::<'static, X, (), (), ()>(&X, ((), (), ()), &[1, 2]);

foo2::<'static, (), (), (), 3, (), ()>(&X, ((), (), ()), &[1, 2, 3]);
bar2::<'static, (), (), (), ()>(&X, ((), (), ()), &[1, 2]);

foo3::<'static, (), (), (), 4, ()>(&X, ((), (), ()), &[1, 2, 3, 4]);
bar3::<'static, (), (), ()>(&X, ((), (), ()), &[1, 2]);
}
}

mod trait_to_trait {
trait Trait<'a, X, Y, T = (), const N: usize = 2> {
fn foo(&self, t: (T, T, T), slice: &[usize; N]) {}
fn bar(&self, t: (T, T, T), slice: &[usize; N]) {}
}

trait Trait2<'a, X, Y>: Trait<'a, X, Y> {
// Default params are generated as usual generics as infers are specified.
reuse Trait::<'a, X, Y, _, _>::foo;
//~^ ERROR: the trait bound `Self: trait_to_trait::Trait<'a, X, Y, T, N>` is not satisfied

// Default params are not generated, as they are not specified.
reuse Trait::<'a, X, Y>::foo as bar;
}

impl Trait<'static, (), ()> for () {}
impl Trait2<'static, (), ()> for () {}

fn check() {
Trait2::<'static, (), ()>::foo::<(), 1>(&(), ((), (), ()), &[1]);
Trait2::<'static, (), ()>::bar(&(), ((), (), ()), &[1, 2]);
}
}

mod trait_impl_to_trait {
trait Trait<'a, X, Y, T = (), const N: usize = 2> {
fn foo(&self, t: (T, T, T), slice: &[usize; N]) {}
fn bar(&self, t: (T, T, T), slice: &[usize; N]) {}
}

struct S;
impl<X, Y> Trait<'_, X, Y> for S {}

struct W(S);
impl<X, Y> Trait<'_, X, Y> for W {
// Generics of both methods match generics of their signature
// functions in `Trait` declaration, no matter specified infers.
reuse Trait::<'static, X, Y>::foo { self.0 }
reuse Trait::<'static, X, Y, _, _>::foo as bar { self.0 }
}

fn check() {
W(S).foo(((), (), ()), &[1, 2]);
W(S).foo::<1, 2, 3>(((), (), ()), &[1, 2]);
//~^ ERROR: method takes 0 generic arguments but 3 generic arguments were supplied

W(S).bar(((), (), ()), &[1]);
//~^ ERROR: mismatched types
W(S).bar::<((), ()), 0>(((), (), ()), &[1, 2]);
//~^ ERROR: method takes 0 generic arguments but 2 generic arguments were supplied

W(S).bar(((), (), ()), &[1, 2]);
}
}

mod inherent_impl_to_trait {
trait Trait<'a, X, Y, T = (), const N: usize = 2> {
fn foo(&self, t: (T, T, T), slice: &[usize; N]) {}
}

struct S<T>(T);

impl<T: Trait<'static, (), ()>> S<T> {
// Default params are not generated, as they are not specified.
reuse Trait::<'static, (), ()>::foo { self.0 }

// Default params are generated as usual generics as infers are specified.
reuse Trait::<'static, (), (), _, _>::foo as bar { self.0 }
//~^ ERROR: the trait bound `T: inherent_impl_to_trait::Trait<'static, (), (), T, N>` is not satisfied
}

impl Trait<'static, (), ()> for () {}

fn check() {
S(()).foo(((), (), ()), &[1, 2]);
S(()).bar(((), (), ()), &[1, 2]);
S(()).bar::<usize, 4>((1, 2, 3), &[1, 2, 3, 4]);
}
}

fn main() {}
Loading
Loading