about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/pretty/delegation.rs25
-rw-r--r--tests/ui/delegation/bad-resolve.rs47
-rw-r--r--tests/ui/delegation/bad-resolve.stderr102
-rw-r--r--tests/ui/delegation/explicit-paths-in-traits-pass.rs27
-rw-r--r--tests/ui/delegation/explicit-paths-in-traits-pass.stderr11
-rw-r--r--tests/ui/delegation/explicit-paths-pass.rs64
-rw-r--r--tests/ui/delegation/explicit-paths-pass.stderr11
-rw-r--r--tests/ui/delegation/explicit-paths-signature-pass.rs39
-rw-r--r--tests/ui/delegation/explicit-paths-signature-pass.stderr11
-rw-r--r--tests/ui/delegation/explicit-paths.rs25
-rw-r--r--tests/ui/delegation/explicit-paths.stderr38
-rw-r--r--tests/ui/delegation/not-supported.rs111
-rw-r--r--tests/ui/delegation/not-supported.stderr184
-rw-r--r--tests/ui/delegation/parse.rs42
-rw-r--r--tests/ui/delegation/parse.stderr11
-rw-r--r--tests/ui/delegation/target-expr-pass.rs37
-rw-r--r--tests/ui/delegation/target-expr-pass.stderr11
-rw-r--r--tests/ui/feature-gates/feature-gate-fn_delegation.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-fn_delegation.stderr15
19 files changed, 809 insertions, 9 deletions
diff --git a/tests/pretty/delegation.rs b/tests/pretty/delegation.rs
new file mode 100644
index 00000000000..6a46437f7d6
--- /dev/null
+++ b/tests/pretty/delegation.rs
@@ -0,0 +1,25 @@
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+// pp-exact
+
+trait Trait {
+    fn bar(&self, x: i32) -> i32 { x }
+}
+
+struct F;
+impl Trait for F {}
+
+struct S(F);
+impl Trait for S {
+    reuse Trait::bar { &self.0 }
+}
+
+mod to_reuse {
+    pub fn foo() {}
+}
+
+#[inline]
+pub reuse to_reuse::foo;
+
+fn main() {}
diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs
new file mode 100644
index 00000000000..df456f94507
--- /dev/null
+++ b/tests/ui/delegation/bad-resolve.rs
@@ -0,0 +1,47 @@
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+trait Trait {
+    const C: u32 = 0;
+    type Type;
+    fn bar() {}
+    fn foo(&self, x: i32) -> i32 { x }
+}
+
+struct F;
+impl Trait for F {
+    type Type = i32;
+}
+
+impl F {
+    fn foo(&self, x: i32) -> i32 { x }
+}
+
+struct S(F);
+
+impl Trait for S {
+//~^ ERROR not all trait items implemented, missing: `Type`
+    reuse <F as Trait>::C;
+    //~^ ERROR item `C` is an associated method, which doesn't match its trait `Trait`
+    //~| ERROR expected function, found associated constant `Trait::C`
+    reuse <F as Trait>::Type;
+    //~^ ERROR item `Type` is an associated method, which doesn't match its trait `Trait`
+    //~| ERROR expected method or associated constant, found associated type `Trait::Type`
+    reuse <F as Trait>::baz;
+    //~^ ERROR method `baz` is not a member of trait `Trait`
+    //~| ERROR cannot find method or associated constant `baz` in trait `Trait`
+    reuse <F as Trait>::bar;
+
+    reuse foo { &self.0 }
+    //~^ ERROR cannot find function `foo` in this scope
+    reuse F::foo { &self.0 }
+    //~^ ERROR cannot find function `foo` in `F`
+    //~| ERROR duplicate definitions with name `foo`
+}
+
+impl S {
+    reuse F::foo { &self.0 }
+    //~^ ERROR cannot find function `foo` in `F`
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr
new file mode 100644
index 00000000000..d5206637310
--- /dev/null
+++ b/tests/ui/delegation/bad-resolve.stderr
@@ -0,0 +1,102 @@
+error[E0324]: item `C` is an associated method, which doesn't match its trait `Trait`
+  --> $DIR/bad-resolve.rs:24:5
+   |
+LL |     const C: u32 = 0;
+   |     ----------------- item in trait
+...
+LL |     reuse <F as Trait>::C;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ does not match trait
+
+error[E0324]: item `Type` is an associated method, which doesn't match its trait `Trait`
+  --> $DIR/bad-resolve.rs:27:5
+   |
+LL |     type Type;
+   |     ---------- item in trait
+...
+LL |     reuse <F as Trait>::Type;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait
+
+error[E0407]: method `baz` is not a member of trait `Trait`
+  --> $DIR/bad-resolve.rs:30:5
+   |
+LL |     reuse <F as Trait>::baz;
+   |     ^^^^^^^^^^^^^^^^^^^^---^
+   |     |                   |
+   |     |                   help: there is an associated function with a similar name: `bar`
+   |     not a member of trait `Trait`
+
+error[E0201]: duplicate definitions with name `foo`:
+  --> $DIR/bad-resolve.rs:37:5
+   |
+LL |     fn foo(&self, x: i32) -> i32 { x }
+   |     ---------------------------------- item in trait
+...
+LL |     reuse foo { &self.0 }
+   |     --------------------- previous definition here
+LL |
+LL |     reuse F::foo { &self.0 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
+
+error[E0423]: expected function, found associated constant `Trait::C`
+  --> $DIR/bad-resolve.rs:24:11
+   |
+LL |     reuse <F as Trait>::C;
+   |           ^^^^^^^^^^^^^^^ not a function
+
+error[E0575]: expected method or associated constant, found associated type `Trait::Type`
+  --> $DIR/bad-resolve.rs:27:11
+   |
+LL |     reuse <F as Trait>::Type;
+   |           ^^^^^^^^^^^^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0576]: cannot find method or associated constant `baz` in trait `Trait`
+  --> $DIR/bad-resolve.rs:30:25
+   |
+LL |     fn bar() {}
+   |     -------- similarly named associated function `bar` defined here
+...
+LL |     reuse <F as Trait>::baz;
+   |                         ^^^ help: an associated function with a similar name exists: `bar`
+
+error[E0425]: cannot find function `foo` in this scope
+  --> $DIR/bad-resolve.rs:35:11
+   |
+LL |     reuse foo { &self.0 }
+   |           ^^^ not found in this scope
+
+error[E0425]: cannot find function `foo` in `F`
+  --> $DIR/bad-resolve.rs:37:14
+   |
+LL |     reuse F::foo { &self.0 }
+   |              ^^^ not found in `F`
+
+error[E0425]: cannot find function `foo` in `F`
+  --> $DIR/bad-resolve.rs:43:14
+   |
+LL |     reuse F::foo { &self.0 }
+   |              ^^^ not found in `F`
+
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/bad-resolve.rs:1:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0046]: not all trait items implemented, missing: `Type`
+  --> $DIR/bad-resolve.rs:22:1
+   |
+LL |     type Type;
+   |     --------- `Type` from trait
+...
+LL | impl Trait for S {
+   | ^^^^^^^^^^^^^^^^ missing `Type` in implementation
+
+error: aborting due to 11 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0046, E0201, E0324, E0407, E0423, E0425, E0575, E0576.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/delegation/explicit-paths-in-traits-pass.rs b/tests/ui/delegation/explicit-paths-in-traits-pass.rs
new file mode 100644
index 00000000000..5c41c2ff49c
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths-in-traits-pass.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+trait ToReuse {
+    fn foo(&self, x: i32) -> i32 { x }
+    fn foo1(x: i32) -> i32 { x }
+}
+
+fn foo2() -> i32 { 42 }
+
+trait Trait: ToReuse {
+    reuse ToReuse::foo;
+    reuse <Self as ToReuse>::foo1;
+    reuse foo2;
+}
+
+struct S;
+impl ToReuse for S {}
+impl Trait for S {}
+
+fn main() {
+    assert_eq!(<S as Trait>::foo(&S, 1), 1);
+    assert_eq!(<S as Trait>::foo1(1), 1);
+    assert_eq!(<S as Trait>::foo2(), 42);
+}
diff --git a/tests/ui/delegation/explicit-paths-in-traits-pass.stderr b/tests/ui/delegation/explicit-paths-in-traits-pass.stderr
new file mode 100644
index 00000000000..8a320b44e63
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths-in-traits-pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/explicit-paths-in-traits-pass.rs:3:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/delegation/explicit-paths-pass.rs b/tests/ui/delegation/explicit-paths-pass.rs
new file mode 100644
index 00000000000..331e06d9a88
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths-pass.rs
@@ -0,0 +1,64 @@
+// run-pass
+
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+trait Trait {
+    fn bar(&self, x: i32) -> i32 { x }
+    fn description(&self) -> &str {
+        "hello world!"
+    }
+    fn static_method(x: i32) -> i32 { x }
+    fn static_method2(x: i32, y: i32) -> i32 { x + y }
+    fn baz<'a>(&self, x: &'a i32) -> &'a i32 { x }
+}
+
+struct F;
+impl Trait for F {}
+
+mod to_reuse {
+    pub fn foo(x: i32) -> i32 { x + 1 }
+    pub fn zero_args() -> i32 { 15 }
+}
+
+reuse to_reuse::zero_args { self }
+
+struct S(F);
+impl Trait for S {
+    reuse Trait::bar { &self.0 }
+    reuse Trait::description { &self.0 }
+    reuse <F as Trait>::static_method;
+    reuse <F as Trait>::static_method2 { S::static_method(self) }
+    reuse Trait::baz { &self.0 }
+}
+
+impl S {
+    reuse Trait::baz { &self.0 }
+    reuse <F as Trait>::static_method { to_reuse::foo(self) }
+}
+
+impl std::fmt::Display for S {
+    reuse <str as std::fmt::Display>::fmt { self.description() }
+}
+
+fn main() {
+    let s = S(F);
+    assert_eq!(42, s.bar(42));
+    assert_eq!("hello world!", format!("{s}"));
+    assert_eq!(43, S::static_method(42));
+    assert_eq!(42, <S as Trait>::static_method(42));
+    assert_eq!(21, S::static_method2(10, 10));
+
+    reuse <S as Trait>::static_method;
+    reuse <S as Trait>::static_method2 { static_method(self) }
+    #[inline]
+    reuse to_reuse::foo;
+    assert_eq!(42, static_method(42));
+    assert_eq!(21, static_method2(10, 10));
+    assert_eq!(43, foo(42));
+    assert_eq!(15, zero_args());
+
+    let x: i32 = 15;
+    assert_eq!(&x, <S as Trait>::baz(&s, &x));
+    assert_eq!(&x, S::baz(&s, &x));
+}
diff --git a/tests/ui/delegation/explicit-paths-pass.stderr b/tests/ui/delegation/explicit-paths-pass.stderr
new file mode 100644
index 00000000000..6d25fb4a5a5
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths-pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/explicit-paths-pass.rs:3:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/delegation/explicit-paths-signature-pass.rs b/tests/ui/delegation/explicit-paths-signature-pass.rs
new file mode 100644
index 00000000000..826107130eb
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths-signature-pass.rs
@@ -0,0 +1,39 @@
+// run-pass
+
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+mod to_reuse {
+    use crate::S;
+
+    pub fn foo<'a>(#[cfg(FALSE)] a: u8, _b: &'a S) -> u32 {
+        1
+    }
+}
+
+reuse to_reuse::foo;
+
+trait Trait {
+    fn foo(&self) -> u32 { 0 }
+    fn bar(self: Box<Self>) -> u32 { 2 }
+    fn baz(a: (i32, i32)) -> i32 { a.0 + a.1 }
+}
+
+struct F;
+impl Trait for F {}
+
+struct S(F);
+
+impl Trait for S {
+    reuse to_reuse::foo { self }
+    reuse Trait::bar { Box::new(self.0) }
+    reuse <F as Trait>::baz;
+}
+
+fn main() {
+    let s = S(F);
+    assert_eq!(1, foo(&s));
+    assert_eq!(1, s.foo());
+    assert_eq!(2, Box::new(s).bar());
+    assert_eq!(4, S::baz((2, 2)));
+}
diff --git a/tests/ui/delegation/explicit-paths-signature-pass.stderr b/tests/ui/delegation/explicit-paths-signature-pass.stderr
new file mode 100644
index 00000000000..6c81a2ea0af
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths-signature-pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/explicit-paths-signature-pass.rs:3:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/delegation/explicit-paths.rs b/tests/ui/delegation/explicit-paths.rs
new file mode 100644
index 00000000000..1feaaa73f79
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths.rs
@@ -0,0 +1,25 @@
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+trait Trait {
+    fn bar(&self) -> i32 { 42 }
+}
+
+struct F;
+impl Trait for F {}
+
+struct S(F);
+
+impl Trait for S {
+    reuse <F as Trait>::bar;
+    //~^ ERROR mismatched types
+}
+
+struct S2(F);
+
+impl Trait for S2 {
+    reuse <S2 as Trait>::bar { &self.0 }
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr
new file mode 100644
index 00000000000..2994b2390de
--- /dev/null
+++ b/tests/ui/delegation/explicit-paths.stderr
@@ -0,0 +1,38 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/explicit-paths.rs:1:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/explicit-paths.rs:14:25
+   |
+LL |     reuse <F as Trait>::bar;
+   |           --------------^^^
+   |           |             |
+   |           |             expected `&F`, found `&S`
+   |           arguments to this function are incorrect
+   |
+   = note: expected reference `&F`
+              found reference `&S`
+note: method defined here
+  --> $DIR/explicit-paths.rs:5:8
+   |
+LL |     fn bar(&self) -> i32 { 42 }
+   |        ^^^ -----
+
+error[E0308]: mismatched types
+  --> $DIR/explicit-paths.rs:21:32
+   |
+LL |     reuse <S2 as Trait>::bar { &self.0 }
+   |                                ^^^^^^^ expected `&S2`, found `&F`
+   |
+   = note: expected reference `&S2`
+              found reference `&F`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/delegation/not-supported.rs b/tests/ui/delegation/not-supported.rs
new file mode 100644
index 00000000000..23081b1e1fc
--- /dev/null
+++ b/tests/ui/delegation/not-supported.rs
@@ -0,0 +1,111 @@
+#![feature(c_variadic)]
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+mod generics {
+    trait GenericTrait<T> {
+        fn bar(&self, x: T) -> T { x }
+        fn bar1() {}
+    }
+    trait Trait {
+        fn foo(&self, x: i32) -> i32 { x }
+        fn foo1<'a>(&self, x: &'a i32) -> &'a i32 { x }
+        fn foo2<T>(&self, x: T) -> T { x }
+        fn foo3<'a: 'a>(_: &'a u32) {}
+
+        reuse GenericTrait::bar;
+        //~^ delegation with early bound generics is not supported yet
+        reuse GenericTrait::bar1;
+        //~^ delegation with early bound generics is not supported yet
+    }
+
+    struct F;
+    impl Trait for F {}
+    impl<T> GenericTrait<T> for F {}
+
+    struct S(F);
+
+    impl<T> GenericTrait<T> for S {
+        reuse <F as GenericTrait<T>>::bar { &self.0 }
+        //~^ ERROR delegation with early bound generics is not supported yet
+        reuse GenericTrait::<T>::bar1;
+        //~^ ERROR delegation with early bound generics is not supported yet
+    }
+
+    impl GenericTrait<()> for () {
+        reuse GenericTrait::bar { &F }
+        //~^ ERROR delegation with early bound generics is not supported yet
+        reuse GenericTrait::bar1;
+        //~^ ERROR delegation with early bound generics is not supported yet
+    }
+
+    impl Trait for &S {
+        reuse Trait::foo;
+        //~^ ERROR delegation with early bound generics is not supported yet
+    }
+
+    impl Trait for S {
+        reuse Trait::foo1 { &self.0 }
+        reuse Trait::foo2 { &self.0 }
+        //~^ ERROR delegation with early bound generics is not supported yet
+        //~| ERROR method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
+        reuse <F as Trait>::foo3;
+        //~^ ERROR delegation with early bound generics is not supported yet
+        //~| ERROR lifetime parameters or bounds on method `foo3` do not match the trait declaration
+    }
+
+    struct GenericS<T>(T);
+    impl<T> Trait for GenericS<T> {
+        reuse Trait::foo { &self.0 }
+        //~^ ERROR delegation with early bound generics is not supported yet
+    }
+}
+
+mod opaque {
+    trait Trait {}
+    impl Trait for () {}
+
+    mod to_reuse {
+        use super::Trait;
+
+        pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
+        pub fn opaque_ret() -> impl Trait { unimplemented!() }
+    }
+    reuse to_reuse::opaque_arg;
+    //~^ ERROR delegation with early bound generics is not supported yet
+    reuse to_reuse::opaque_ret;
+    //~^ ERROR delegation to a function with opaque type is not supported yet
+}
+
+mod fn_header {
+    mod to_reuse {
+        pub unsafe fn unsafe_fn() {}
+        pub extern "C" fn extern_fn() {}
+        pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {}
+        pub const fn const_fn() {}
+    }
+
+    reuse to_reuse::unsafe_fn;
+    //~^ ERROR delegation to unsafe functions is not supported yet
+    reuse to_reuse::extern_fn;
+    //~^ ERROR delegation to non Rust ABI functions is not supported yet
+    reuse to_reuse::variadic_fn;
+    //~^ ERROR delegation to variadic functions is not supported yet
+    reuse to_reuse::const_fn;
+    //~^ ERROR delegation to const functions is not supported yet
+}
+
+mod recursive {
+    mod to_reuse1 {
+        pub mod to_reuse2 {
+            pub fn foo() {}
+        }
+
+        pub reuse to_reuse2::foo;
+    }
+
+    reuse to_reuse1::foo;
+    //~^ ERROR recursive delegation is not supported yet
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr
new file mode 100644
index 00000000000..f235767d50a
--- /dev/null
+++ b/tests/ui/delegation/not-supported.stderr
@@ -0,0 +1,184 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/not-supported.rs:2:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:16:29
+   |
+LL |         fn bar(&self, x: T) -> T { x }
+   |         ------------------------ callee defined here
+...
+LL |         reuse GenericTrait::bar;
+   |                             ^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:18:29
+   |
+LL |         fn bar1() {}
+   |         --------- callee defined here
+...
+LL |         reuse GenericTrait::bar1;
+   |                             ^^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:29:39
+   |
+LL |         fn bar(&self, x: T) -> T { x }
+   |         ------------------------ callee defined here
+...
+LL |         reuse <F as GenericTrait<T>>::bar { &self.0 }
+   |                                       ^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:31:34
+   |
+LL |         fn bar1() {}
+   |         --------- callee defined here
+...
+LL |         reuse GenericTrait::<T>::bar1;
+   |                                  ^^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:36:29
+   |
+LL |         fn bar(&self, x: T) -> T { x }
+   |         ------------------------ callee defined here
+...
+LL |         reuse GenericTrait::bar { &F }
+   |                             ^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:38:29
+   |
+LL |         fn bar1() {}
+   |         --------- callee defined here
+...
+LL |         reuse GenericTrait::bar1;
+   |                             ^^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:43:22
+   |
+LL |         fn foo(&self, x: i32) -> i32 { x }
+   |         ---------------------------- callee defined here
+...
+LL |         reuse Trait::foo;
+   |                      ^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:49:22
+   |
+LL |         fn foo2<T>(&self, x: T) -> T { x }
+   |         ---------------------------- callee defined here
+...
+LL |         reuse Trait::foo2 { &self.0 }
+   |                      ^^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:52:29
+   |
+LL |         fn foo3<'a: 'a>(_: &'a u32) {}
+   |         --------------------------- callee defined here
+...
+LL |         reuse <F as Trait>::foo3;
+   |                             ^^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:59:22
+   |
+LL |         fn foo(&self, x: i32) -> i32 { x }
+   |         ---------------------------- callee defined here
+...
+LL |         reuse Trait::foo { &self.0 }
+   |                      ^^^
+
+error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:74:21
+   |
+LL |         pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
+   |         --------------------------------------- callee defined here
+...
+LL |     reuse to_reuse::opaque_arg;
+   |                     ^^^^^^^^^^
+
+error: delegation to a function with opaque type is not supported yet
+  --> $DIR/not-supported.rs:76:21
+   |
+LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
+   |         --------------------------------- callee defined here
+...
+LL |     reuse to_reuse::opaque_ret;
+   |                     ^^^^^^^^^^
+
+error: delegation to unsafe functions is not supported yet
+  --> $DIR/not-supported.rs:88:21
+   |
+LL |         pub unsafe fn unsafe_fn() {}
+   |         ------------------------- callee defined here
+...
+LL |     reuse to_reuse::unsafe_fn;
+   |                     ^^^^^^^^^
+
+error: delegation to non Rust ABI functions is not supported yet
+  --> $DIR/not-supported.rs:90:21
+   |
+LL |         pub extern "C" fn extern_fn() {}
+   |         ----------------------------- callee defined here
+...
+LL |     reuse to_reuse::extern_fn;
+   |                     ^^^^^^^^^
+
+error: delegation to variadic functions is not supported yet
+  --> $DIR/not-supported.rs:92:21
+   |
+LL |         pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {}
+   |         ------------------------------------------------------------- callee defined here
+...
+LL |     reuse to_reuse::variadic_fn;
+   |                     ^^^^^^^^^^^
+
+error: delegation to const functions is not supported yet
+  --> $DIR/not-supported.rs:94:21
+   |
+LL |         pub const fn const_fn() {}
+   |         ----------------------- callee defined here
+...
+LL |     reuse to_reuse::const_fn;
+   |                     ^^^^^^^^
+
+error: recursive delegation is not supported yet
+  --> $DIR/not-supported.rs:107:22
+   |
+LL |         pub reuse to_reuse2::foo;
+   |                              --- callee defined here
+...
+LL |     reuse to_reuse1::foo;
+   |                      ^^^
+
+error[E0049]: method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
+  --> $DIR/not-supported.rs:49:22
+   |
+LL |         fn foo2<T>(&self, x: T) -> T { x }
+   |                 - expected 1 type parameter
+...
+LL |         reuse Trait::foo2 { &self.0 }
+   |                      ^^^^ found 0 type parameters
+
+error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration
+  --> $DIR/not-supported.rs:52:29
+   |
+LL |         fn foo3<'a: 'a>(_: &'a u32) {}
+   |                -------- lifetimes in impl do not match this method in trait
+...
+LL |         reuse <F as Trait>::foo3;
+   |                             ^^^^ lifetimes do not match method in trait
+
+error: aborting due to 19 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0049, E0195.
+For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/delegation/parse.rs b/tests/ui/delegation/parse.rs
new file mode 100644
index 00000000000..791cc1630ff
--- /dev/null
+++ b/tests/ui/delegation/parse.rs
@@ -0,0 +1,42 @@
+// check-pass
+
+#![feature(decl_macro)]
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+macro_rules! reuse { {} => {} }
+
+mod reuse {
+    pub fn to_unsafe(x: i32) -> i32 { x + 1 }
+    pub fn to_pub() {}
+    pub fn to_pub2() {}
+
+    mod inner {
+        #[allow(non_camel_case_types)]
+        struct reuse {
+            a: i32,
+            b: i32,
+            c: i32,
+        }
+
+        impl reuse {
+            reuse!();
+        }
+
+        fn baz() {
+            let (a, b, c) = (0, 0, 0);
+            reuse {a, b, c};
+        }
+    }
+
+    pub macro my_macro() {}
+}
+
+reuse!();
+reuse::my_macro!();
+
+#[inline]
+pub reuse reuse::to_pub;
+pub reuse crate::reuse::to_pub2;
+
+fn main() {}
diff --git a/tests/ui/delegation/parse.stderr b/tests/ui/delegation/parse.stderr
new file mode 100644
index 00000000000..1e420ceeec7
--- /dev/null
+++ b/tests/ui/delegation/parse.stderr
@@ -0,0 +1,11 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/parse.rs:4:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/delegation/target-expr-pass.rs b/tests/ui/delegation/target-expr-pass.rs
new file mode 100644
index 00000000000..56068dfce01
--- /dev/null
+++ b/tests/ui/delegation/target-expr-pass.rs
@@ -0,0 +1,37 @@
+// run-pass
+
+#![feature(fn_delegation)]
+//~^ WARN the feature `fn_delegation` is incomplete
+
+mod to_reuse {
+    pub fn foo(x: i32) -> i32 { x }
+    pub mod inner {}
+}
+
+reuse to_reuse::foo {{
+    use self::to_reuse::foo;
+    let x = foo(12);
+    x + self
+}}
+
+trait Trait {
+    fn bar(&self, x: i32) -> i32 { x }
+}
+
+struct F;
+impl Trait for F {}
+
+struct S(F);
+impl Trait for S {
+    reuse <F as Trait>::bar {
+        #[allow(unused_imports)]
+        use self::to_reuse::{foo, inner::self};
+        let x = foo(12);
+        assert_eq!(x, 12);
+        &self.0
+    }
+}
+
+fn main() {
+    assert_eq!(foo(12), 24);
+}
diff --git a/tests/ui/delegation/target-expr-pass.stderr b/tests/ui/delegation/target-expr-pass.stderr
new file mode 100644
index 00000000000..ea594f8a26a
--- /dev/null
+++ b/tests/ui/delegation/target-expr-pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/target-expr-pass.rs:3:12
+   |
+LL | #![feature(fn_delegation)]
+   |            ^^^^^^^^^^^^^
+   |
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/feature-gates/feature-gate-fn_delegation.rs b/tests/ui/feature-gates/feature-gate-fn_delegation.rs
index 6ac36712090..5352b2d8cad 100644
--- a/tests/ui/feature-gates/feature-gate-fn_delegation.rs
+++ b/tests/ui/feature-gates/feature-gate-fn_delegation.rs
@@ -1,3 +1,8 @@
-todo!(); //~ ERROR
+mod to_reuse {
+    pub fn foo() {}
+}
+
+reuse to_reuse::foo;
+//~^ ERROR functions delegation is not yet fully implemented
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-fn_delegation.stderr b/tests/ui/feature-gates/feature-gate-fn_delegation.stderr
index 14d85c5263e..9b62e4ecff4 100644
--- a/tests/ui/feature-gates/feature-gate-fn_delegation.stderr
+++ b/tests/ui/feature-gates/feature-gate-fn_delegation.stderr
@@ -1,13 +1,12 @@
-error: expected one of `!` or `::`, found `(`
-  --> $DIR/feature-gate-fn_delegation.rs:1:1
+error[E0658]: functions delegation is not yet fully implemented
+  --> $DIR/feature-gate-fn_delegation.rs:5:1
    |
-LL | todo!();
-   | ^^^^^^^
-   | |
-   | expected one of `!` or `::`
-   | in this macro invocation
+LL | reuse to_reuse::foo;
+   | ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
+   = help: add `#![feature(fn_delegation)]` to the crate attributes to enable
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0658`.