diff --git a/tests/pretty/auxiliary/to-reuse-functions.rs b/tests/pretty/delegation/auxiliary/to-reuse-functions.rs
similarity index 100%
rename from tests/pretty/auxiliary/to-reuse-functions.rs
rename to tests/pretty/delegation/auxiliary/to-reuse-functions.rs
diff --git a/tests/pretty/delegation.rs b/tests/pretty/delegation/delegation.rs
similarity index 100%
rename from tests/pretty/delegation.rs
rename to tests/pretty/delegation/delegation.rs
diff --git a/tests/pretty/delegation/generics.pp b/tests/pretty/delegation/generics.pp
new file mode 100644
index 0000000000000..f5429c3c26a75
--- /dev/null
+++ b/tests/pretty/delegation/generics.pp
@@ -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(&self, t: (T, A, B), slice: &'_ [usize; N]) { }
+ fn r#static(t: (T, A, B), slice: &'_ [usize; N]) { }
+ }
+
+ struct X;
+ impl 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 {
+ >::method::(self, arg1, arg2)
+ }
+ #[attr = Inline(Hint)]
+ fn static_foo<'a, Self, XX, Y, T, const N: _, A, B>(arg0: _, arg1: _) -> _
+ where
+ 'a:'a {
+ >::r#static::(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 {
+ >::method::(self, arg1, arg2)
+ }
+ #[attr = Inline(Hint)]
+ fn static_bar<'a, Self, XX, Y, A, B>(arg0: _, arg1: _) -> _ where
+ 'a:'a { >::r#static::(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 {
+ >::method::<(), B>(self, arg1, arg2)
+ }
+ #[attr = Inline(Hint)]
+ fn static_foo1<'a, Self, XX, Y, T, const N: _, B>(arg0: _, arg1: _) -> _
+ where
+ 'a:'a {
+ >::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 {
+ >::method::(self, arg1, arg2)
+ }
+ #[attr = Inline(Hint)]
+ fn static_bar1<'a, Self, XX, Y, A>(arg0: _, arg1: _) -> _ where
+ 'a:'a { >::r#static::(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 {
+ >::method::(self, arg1, arg2)
+ }
+ #[attr = Inline(Hint)]
+ fn static_foo2<'a, XX, Y, T, const N: _, A, B>(arg0: _, arg1: _) -> _
+ where
+ 'a:'a {
+ >::r#static::(arg0, arg1)
+ }
+
+ #[attr = Inline(Hint)]
+ fn bar2<'a, XX, Y, A, B>(self: _, arg1: _, arg2: _) -> _ where
+ 'a:'a { >::method::(self, arg1, arg2) }
+ #[attr = Inline(Hint)]
+ fn static_bar2<'a, XX, Y, A, B>(arg0: _, arg1: _) -> _ where
+ 'a:'a { >::r#static::(arg0, arg1) }
+
+ #[attr = Inline(Hint)]
+ fn foo3<'a, XX, Y, T, const N: _, B>(self: _, arg1: _, arg2: _) -> _ where
+ 'a:'a {
+ >::method::<(), B>(self, arg1, arg2)
+ }
+ #[attr = Inline(Hint)]
+ fn static_foo3<'a, XX, Y, T, const N: _, B>(arg0: _, arg1: _) -> _ where
+ 'a:'a {
+ >::r#static::<(), B>(arg0, arg1)
+ }
+
+ #[attr = Inline(Hint)]
+ fn bar3<'a, XX, Y, A>(self: _, arg1: _, arg2: _) -> _ where
+ 'a:'a { >::method::(self, arg1, arg2) }
+ #[attr = Inline(Hint)]
+ fn static_bar3<'a, XX, Y, A>(arg0: _, arg1: _) -> _ where
+ 'a:'a { >::r#static::(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 Trait<'_, X, Y> for S { }
+
+ struct W(S);
+ impl 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() { }
diff --git a/tests/pretty/delegation/generics.rs b/tests/pretty/delegation/generics.rs
new file mode 100644
index 0000000000000..7491bc663393a
--- /dev/null
+++ b/tests/pretty/delegation/generics.rs
@@ -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(&self, t: (T, A, B), slice: &[usize; N]) {}
+ fn r#static(t: (T, A, B), slice: &[usize; N]) {}
+ }
+
+ struct X;
+ impl 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 >::method as foo2;
+ reuse >::r#static as static_foo2;
+
+ reuse >::method as bar2;
+ reuse >::r#static as static_bar2;
+
+ reuse >::method::<(), _> as foo3;
+ reuse >::r#static::<(), _> as static_foo3;
+
+ reuse >::method::<_, ()> as bar3;
+ reuse >::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 Trait<'_, X, Y> for S {}
+
+ struct W(S);
+ impl 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() {}
diff --git a/tests/pretty/delegation-impl-reuse.pp b/tests/pretty/delegation/impl-reuse.pp
similarity index 94%
rename from tests/pretty/delegation-impl-reuse.pp
rename to tests/pretty/delegation/impl-reuse.pp
index 6c6c8a594fc8e..2097b23e5c524 100644
--- a/tests/pretty/delegation-impl-reuse.pp
+++ b/tests/pretty/delegation/impl-reuse.pp
@@ -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)]
diff --git a/tests/pretty/delegation-impl-reuse.rs b/tests/pretty/delegation/impl-reuse.rs
similarity index 87%
rename from tests/pretty/delegation-impl-reuse.rs
rename to tests/pretty/delegation/impl-reuse.rs
index 9265ea18a76f0..3e813bf10d01e 100644
--- a/tests/pretty/delegation-impl-reuse.rs
+++ b/tests/pretty/delegation/impl-reuse.rs
@@ -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)]
diff --git a/tests/pretty/delegation-inherit-attributes.pp b/tests/pretty/delegation/inherit-attributes.pp
similarity index 98%
rename from tests/pretty/delegation-inherit-attributes.pp
rename to tests/pretty/delegation/inherit-attributes.pp
index e29f76089256d..a45eb5a1c5f38 100644
--- a/tests/pretty/delegation-inherit-attributes.pp
+++ b/tests/pretty/delegation/inherit-attributes.pp
@@ -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])]
diff --git a/tests/pretty/delegation-inherit-attributes.rs b/tests/pretty/delegation/inherit-attributes.rs
similarity index 97%
rename from tests/pretty/delegation-inherit-attributes.rs
rename to tests/pretty/delegation/inherit-attributes.rs
index 581294d472a33..538fb7cd7d75a 100644
--- a/tests/pretty/delegation-inherit-attributes.rs
+++ b/tests/pretty/delegation/inherit-attributes.rs
@@ -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)]
diff --git a/tests/pretty/delegation-inline-attribute.pp b/tests/pretty/delegation/inline-attribute.pp
similarity index 98%
rename from tests/pretty/delegation-inline-attribute.pp
rename to tests/pretty/delegation/inline-attribute.pp
index 8cf2d98eeb412..361eb56f558f4 100644
--- a/tests/pretty/delegation-inline-attribute.pp
+++ b/tests/pretty/delegation/inline-attribute.pp
@@ -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])]
diff --git a/tests/pretty/delegation-inline-attribute.rs b/tests/pretty/delegation/inline-attribute.rs
similarity index 98%
rename from tests/pretty/delegation-inline-attribute.rs
rename to tests/pretty/delegation/inline-attribute.rs
index c79f68f8942d2..f390bf64b24a7 100644
--- a/tests/pretty/delegation-inline-attribute.rs
+++ b/tests/pretty/delegation/inline-attribute.rs
@@ -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)]
diff --git a/tests/pretty/delegation-self-rename.pp b/tests/pretty/delegation/self-rename.pp
similarity index 97%
rename from tests/pretty/delegation-self-rename.pp
rename to tests/pretty/delegation/self-rename.pp
index 526021c061178..661a0ab5490eb 100644
--- a/tests/pretty/delegation-self-rename.pp
+++ b/tests/pretty/delegation/self-rename.pp
@@ -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> {
diff --git a/tests/pretty/delegation-self-rename.rs b/tests/pretty/delegation/self-rename.rs
similarity index 93%
rename from tests/pretty/delegation-self-rename.rs
rename to tests/pretty/delegation/self-rename.rs
index 9054bb2b89571..c04980508cb85 100644
--- a/tests/pretty/delegation-self-rename.rs
+++ b/tests/pretty/delegation/self-rename.rs
@@ -1,6 +1,6 @@
//@ pretty-compare-only
//@ pretty-mode:hir
-//@ pp-exact:delegation-self-rename.pp
+//@ pp-exact:self-rename.pp
#![feature(fn_delegation)]
diff --git a/tests/ui/delegation/generics/infer-defaults.rs b/tests/ui/delegation/generics/infer-defaults.rs
new file mode 100644
index 0000000000000..c801eab6af083
--- /dev/null
+++ b/tests/ui/delegation/generics/infer-defaults.rs
@@ -0,0 +1,124 @@
+#![feature(fn_delegation)]
+
+mod free_to_trait {
+ trait Trait<'a, XX, Y, T = (), const N: usize = 2> {
+ fn foo(&self, t: (T, A, B), slice: &[usize; N]) {}
+ }
+
+ struct X;
+ impl 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 >::foo as foo2;
+ reuse >::foo as bar2;
+
+ reuse >::foo::<(), _> as foo3;
+ reuse >::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 Trait<'_, X, Y> for S {}
+
+ struct W(S);
+ impl 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);
+
+ impl> S {
+ // 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::((1, 2, 3), &[1, 2, 3, 4]);
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/generics/infer-defaults.stderr b/tests/ui/delegation/generics/infer-defaults.stderr
new file mode 100644
index 0000000000000..4d9695fc823e7
--- /dev/null
+++ b/tests/ui/delegation/generics/infer-defaults.stderr
@@ -0,0 +1,70 @@
+error[E0277]: the trait bound `Self: trait_to_trait::Trait<'a, X, Y, T, N>` is not satisfied
+ --> $DIR/infer-defaults.rs:52:40
+ |
+LL | reuse Trait::<'a, X, Y, _, _>::foo;
+ | ^^^ the trait `trait_to_trait::Trait<'a, X, Y, T, N>` is not implemented for `Self`
+ |
+help: consider further restricting `Self`
+ |
+LL | reuse Trait::<'a, X, Y, _, _>::foo Self: trait_to_trait::Trait<'a, X, Y, T, N>;
+ | +++++++++++++++++++++++++++++++++++++++++++
+
+error[E0107]: method takes 0 generic arguments but 3 generic arguments were supplied
+ --> $DIR/infer-defaults.rs:87:14
+ |
+LL | W(S).foo::<1, 2, 3>(((), (), ()), &[1, 2]);
+ | ^^^----------- help: remove the unnecessary generics
+ | |
+ | expected 0 generic arguments
+ |
+note: method defined here, with 0 generic parameters
+ --> $DIR/infer-defaults.rs:70:12
+ |
+LL | fn foo(&self, t: (T, T, T), slice: &[usize; N]) {}
+ | ^^^
+
+error[E0308]: mismatched types
+ --> $DIR/infer-defaults.rs:90:32
+ |
+LL | W(S).bar(((), (), ()), &[1]);
+ | --- ^^^^ expected an array with a size of 2, found one with a size of 1
+ | |
+ | arguments to this method are incorrect
+ |
+note: method defined here
+ --> $DIR/infer-defaults.rs:71:12
+ |
+LL | fn bar(&self, t: (T, T, T), slice: &[usize; N]) {}
+ | ^^^ ------------------
+
+error[E0107]: method takes 0 generic arguments but 2 generic arguments were supplied
+ --> $DIR/infer-defaults.rs:92:14
+ |
+LL | W(S).bar::<((), ()), 0>(((), (), ()), &[1, 2]);
+ | ^^^--------------- help: remove the unnecessary generics
+ | |
+ | expected 0 generic arguments
+ |
+note: method defined here, with 0 generic parameters
+ --> $DIR/infer-defaults.rs:71:12
+ |
+LL | fn bar(&self, t: (T, T, T), slice: &[usize; N]) {}
+ | ^^^
+
+error[E0277]: the trait bound `T: inherent_impl_to_trait::Trait<'static, (), (), T, N>` is not satisfied
+ --> $DIR/infer-defaults.rs:111:60
+ |
+LL | reuse Trait::<'static, (), (), _, _>::foo as bar { self.0 }
+ | --- ^^^^^^ the trait `inherent_impl_to_trait::Trait<'static, (), (), T, N>` is not implemented for `T`
+ | |
+ | required by a bound introduced by this call
+ |
+help: consider restricting type parameter `T` with trait `Trait`
+ |
+LL | reuse Trait::<'static, (), (), _, _>::foo inherent_impl_to_trait::Trait<'static, (), (), T, N> as bar { self.0 }
+ | ++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0107, E0277, E0308.
+For more information about an error, try `rustc --explain E0107`.