summaryrefslogtreecommitdiffstats
path: root/src/test/ui/fn
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/fn
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/fn')
-rw-r--r--src/test/ui/fn/bad-main.rs1
-rw-r--r--src/test/ui/fn/bad-main.stderr12
-rw-r--r--src/test/ui/fn/dyn-fn-alignment.rs23
-rw-r--r--src/test/ui/fn/expr-fn-panic.rs11
-rw-r--r--src/test/ui/fn/expr-fn.rs62
-rw-r--r--src/test/ui/fn/fn-bad-block-type.rs5
-rw-r--r--src/test/ui/fn/fn-bad-block-type.stderr11
-rw-r--r--src/test/ui/fn/fn-closure-mutable-capture.rs12
-rw-r--r--src/test/ui/fn/fn-closure-mutable-capture.stderr15
-rw-r--r--src/test/ui/fn/fn-compare-mismatch.rs7
-rw-r--r--src/test/ui/fn/fn-compare-mismatch.stderr30
-rw-r--r--src/test/ui/fn/fn-item-type.rs53
-rw-r--r--src/test/ui/fn/fn-item-type.stderr97
-rw-r--r--src/test/ui/fn/fn-recover-return-sign.fixed28
-rw-r--r--src/test/ui/fn/fn-recover-return-sign.rs28
-rw-r--r--src/test/ui/fn/fn-recover-return-sign.stderr26
-rw-r--r--src/test/ui/fn/fn-recover-return-sign2.rs8
-rw-r--r--src/test/ui/fn/fn-recover-return-sign2.stderr14
-rw-r--r--src/test/ui/fn/fn-trait-formatting.rs21
-rw-r--r--src/test/ui/fn/fn-trait-formatting.stderr52
-rw-r--r--src/test/ui/fn/fun-call-variants.rs12
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs22
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs25
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr14
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type.rs23
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr14
-rw-r--r--src/test/ui/fn/issue-80179.rs27
-rw-r--r--src/test/ui/fn/issue-80179.stderr21
-rw-r--r--src/test/ui/fn/keyword-order.rs6
-rw-r--r--src/test/ui/fn/keyword-order.stderr16
-rw-r--r--src/test/ui/fn/nested-function-names-issue-8587.rs42
31 files changed, 738 insertions, 0 deletions
diff --git a/src/test/ui/fn/bad-main.rs b/src/test/ui/fn/bad-main.rs
new file mode 100644
index 000000000..751159961
--- /dev/null
+++ b/src/test/ui/fn/bad-main.rs
@@ -0,0 +1 @@
+fn main(x: isize) { } //~ ERROR: `main` function has wrong type [E0580]
diff --git a/src/test/ui/fn/bad-main.stderr b/src/test/ui/fn/bad-main.stderr
new file mode 100644
index 000000000..675b66d05
--- /dev/null
+++ b/src/test/ui/fn/bad-main.stderr
@@ -0,0 +1,12 @@
+error[E0580]: `main` function has wrong type
+ --> $DIR/bad-main.rs:1:1
+ |
+LL | fn main(x: isize) { }
+ | ^^^^^^^^^^^^^^^^^ incorrect number of function parameters
+ |
+ = note: expected fn pointer `fn()`
+ found fn pointer `fn(isize)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0580`.
diff --git a/src/test/ui/fn/dyn-fn-alignment.rs b/src/test/ui/fn/dyn-fn-alignment.rs
new file mode 100644
index 000000000..cedfd1cf2
--- /dev/null
+++ b/src/test/ui/fn/dyn-fn-alignment.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![allow(dead_code)]
+#[repr(align(256))]
+struct A {
+ v: u8,
+}
+
+impl A {
+ fn f(&self) -> *const A {
+ self
+ }
+}
+
+fn f2(v: u8) -> Box<dyn FnOnce() -> *const A> {
+ let a = A { v };
+ Box::new(move || a.f())
+}
+
+fn main() {
+ let addr = f2(0)();
+ assert_eq!(addr as usize % 256, 0, "addr: {:?}", addr);
+}
diff --git a/src/test/ui/fn/expr-fn-panic.rs b/src/test/ui/fn/expr-fn-panic.rs
new file mode 100644
index 000000000..123b57f97
--- /dev/null
+++ b/src/test/ui/fn/expr-fn-panic.rs
@@ -0,0 +1,11 @@
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
+
+fn f() -> ! {
+ panic!()
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/ui/fn/expr-fn.rs b/src/test/ui/fn/expr-fn.rs
new file mode 100644
index 000000000..253cbfd5d
--- /dev/null
+++ b/src/test/ui/fn/expr-fn.rs
@@ -0,0 +1,62 @@
+// run-pass
+#![allow(unused_braces)]
+
+fn test_int() {
+ fn f() -> isize { 10 }
+ assert_eq!(f(), 10);
+}
+
+fn test_vec() {
+ fn f() -> Vec<isize> { vec![10, 11] }
+ let vect = f();
+ assert_eq!(vect[1], 11);
+}
+
+fn test_generic() {
+ fn f<T>(t: T) -> T { t }
+ assert_eq!(f(10), 10);
+}
+
+fn test_alt() {
+ fn f() -> isize { match true { false => { 10 } true => { 20 } } }
+ assert_eq!(f(), 20);
+}
+
+fn test_if() {
+ fn f() -> isize { if true { 10 } else { 20 } }
+ assert_eq!(f(), 10);
+}
+
+fn test_block() {
+ fn f() -> isize { { 10 } }
+ assert_eq!(f(), 10);
+}
+
+fn test_ret() {
+ fn f() -> isize {
+ return 10 // no semi
+
+ }
+ assert_eq!(f(), 10);
+}
+
+
+// From issue #372
+fn test_372() {
+ fn f() -> isize { let x = { 3 }; x }
+ assert_eq!(f(), 3);
+}
+
+fn test_nil() { () }
+
+pub fn main() {
+ test_int();
+ test_vec();
+ test_generic();
+ test_alt();
+ test_if();
+ test_block();
+ test_ret();
+ test_372();
+ test_nil();
+}
diff --git a/src/test/ui/fn/fn-bad-block-type.rs b/src/test/ui/fn/fn-bad-block-type.rs
new file mode 100644
index 000000000..01dcff058
--- /dev/null
+++ b/src/test/ui/fn/fn-bad-block-type.rs
@@ -0,0 +1,5 @@
+// error-pattern:mismatched types
+
+fn f() -> isize { true }
+
+fn main() { }
diff --git a/src/test/ui/fn/fn-bad-block-type.stderr b/src/test/ui/fn/fn-bad-block-type.stderr
new file mode 100644
index 000000000..13ebfd1e2
--- /dev/null
+++ b/src/test/ui/fn/fn-bad-block-type.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/fn-bad-block-type.rs:3:19
+ |
+LL | fn f() -> isize { true }
+ | ----- ^^^^ expected `isize`, found `bool`
+ | |
+ | expected `isize` because of return type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/fn/fn-closure-mutable-capture.rs b/src/test/ui/fn/fn-closure-mutable-capture.rs
new file mode 100644
index 000000000..97141886f
--- /dev/null
+++ b/src/test/ui/fn/fn-closure-mutable-capture.rs
@@ -0,0 +1,12 @@
+pub fn bar<F: Fn()>(_f: F) {} //~ NOTE change this to accept `FnMut` instead of `Fn`
+
+pub fn foo() {
+ let mut x = 0;
+ bar(move || x = 1);
+ //~^ ERROR cannot assign to `x`, as it is a captured variable in a `Fn` closure
+ //~| NOTE cannot assign
+ //~| NOTE expects `Fn` instead of `FnMut`
+ //~| NOTE in this closure
+}
+
+fn main() {}
diff --git a/src/test/ui/fn/fn-closure-mutable-capture.stderr b/src/test/ui/fn/fn-closure-mutable-capture.stderr
new file mode 100644
index 000000000..03e3d545a
--- /dev/null
+++ b/src/test/ui/fn/fn-closure-mutable-capture.stderr
@@ -0,0 +1,15 @@
+error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
+ --> $DIR/fn-closure-mutable-capture.rs:5:17
+ |
+LL | pub fn bar<F: Fn()>(_f: F) {}
+ | - change this to accept `FnMut` instead of `Fn`
+...
+LL | bar(move || x = 1);
+ | --- ------- ^^^^^ cannot assign
+ | | |
+ | | in this closure
+ | expects `Fn` instead of `FnMut`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/fn/fn-compare-mismatch.rs b/src/test/ui/fn/fn-compare-mismatch.rs
new file mode 100644
index 000000000..d734d54e8
--- /dev/null
+++ b/src/test/ui/fn/fn-compare-mismatch.rs
@@ -0,0 +1,7 @@
+fn main() {
+ fn f() { }
+ fn g() { }
+ let x = f == g;
+ //~^ ERROR binary operation `==` cannot be applied
+ //~| ERROR mismatched types
+}
diff --git a/src/test/ui/fn/fn-compare-mismatch.stderr b/src/test/ui/fn/fn-compare-mismatch.stderr
new file mode 100644
index 000000000..096440225
--- /dev/null
+++ b/src/test/ui/fn/fn-compare-mismatch.stderr
@@ -0,0 +1,30 @@
+error[E0369]: binary operation `==` cannot be applied to type `fn() {f}`
+ --> $DIR/fn-compare-mismatch.rs:4:15
+ |
+LL | let x = f == g;
+ | - ^^ - fn() {g}
+ | |
+ | fn() {f}
+ |
+help: you might have forgotten to call this function
+ |
+LL | let x = f() == g;
+ | ++
+help: you might have forgotten to call this function
+ |
+LL | let x = f == g();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/fn-compare-mismatch.rs:4:18
+ |
+LL | let x = f == g;
+ | ^ expected fn item, found a different fn item
+ |
+ = note: expected fn item `fn() {f}`
+ found fn item `fn() {g}`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0369.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/fn/fn-item-type.rs b/src/test/ui/fn/fn-item-type.rs
new file mode 100644
index 000000000..1831e6cbf
--- /dev/null
+++ b/src/test/ui/fn/fn-item-type.rs
@@ -0,0 +1,53 @@
+// Test that the types of distinct fn items are not compatible by
+// default. See also `run-pass/fn-item-type-*.rs`.
+
+fn foo<T>(x: isize) -> isize { x * 2 }
+fn bar<T>(x: isize) -> isize { x * 4 }
+
+fn eq<T>(x: T, y: T) { }
+
+trait Foo { fn foo() { /* this is a default fn */ } }
+impl<T> Foo for T { /* `foo` is still default here */ }
+
+fn main() {
+ eq(foo::<u8>, bar::<u8>);
+ //~^ ERROR mismatched types
+ //~| expected fn item `fn(_) -> _ {foo::<u8>}`
+ //~| found fn item `fn(_) -> _ {bar::<u8>}`
+ //~| expected fn item, found a different fn item
+ //~| different `fn` items always have unique types, even if their signatures are the same
+ //~| change the expected type to be function pointer
+ //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer
+
+ eq(foo::<u8>, foo::<i8>);
+ //~^ ERROR mismatched types
+ //~| expected `u8`, found `i8`
+ //~| different `fn` items always have unique types, even if their signatures are the same
+ //~| change the expected type to be function pointer
+ //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer
+
+ eq(bar::<String>, bar::<Vec<u8>>);
+ //~^ ERROR mismatched types
+ //~| found fn item `fn(_) -> _ {bar::<Vec<u8>>}`
+ //~| expected struct `String`, found struct `Vec`
+ //~| different `fn` items always have unique types, even if their signatures are the same
+ //~| change the expected type to be function pointer
+ //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer
+
+ // Make sure we distinguish between trait methods correctly.
+ eq(<u8 as Foo>::foo, <u16 as Foo>::foo);
+ //~^ ERROR mismatched types
+ //~| expected `u8`, found `u16`
+ //~| different `fn` items always have unique types, even if their signatures are the same
+ //~| change the expected type to be function pointer
+ //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer
+
+ eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
+ //~^ ERROR mismatched types
+ //~| found fn pointer `fn(_) -> _`
+ //~| expected fn item, found fn pointer
+ //~| change the expected type to be function pointer
+ //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer
+
+ eq(foo::<u8> as fn(isize) -> isize, bar::<u8>); // ok!
+}
diff --git a/src/test/ui/fn/fn-item-type.stderr b/src/test/ui/fn/fn-item-type.stderr
new file mode 100644
index 000000000..ecc6485d6
--- /dev/null
+++ b/src/test/ui/fn/fn-item-type.stderr
@@ -0,0 +1,97 @@
+error[E0308]: mismatched types
+ --> $DIR/fn-item-type.rs:13:19
+ |
+LL | eq(foo::<u8>, bar::<u8>);
+ | -- ^^^^^^^^^ expected fn item, found a different fn item
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn item `fn(_) -> _ {foo::<u8>}`
+ found fn item `fn(_) -> _ {bar::<u8>}`
+ = note: different `fn` items always have unique types, even if their signatures are the same
+ = help: change the expected type to be function pointer `fn(isize) -> isize`
+ = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize`
+note: function defined here
+ --> $DIR/fn-item-type.rs:7:4
+ |
+LL | fn eq<T>(x: T, y: T) { }
+ | ^^ ---- ----
+
+error[E0308]: mismatched types
+ --> $DIR/fn-item-type.rs:22:19
+ |
+LL | eq(foo::<u8>, foo::<i8>);
+ | -- ^^^^^^^^^ expected `u8`, found `i8`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn item `fn(_) -> _ {foo::<u8>}`
+ found fn item `fn(_) -> _ {foo::<i8>}`
+ = note: different `fn` items always have unique types, even if their signatures are the same
+ = help: change the expected type to be function pointer `fn(isize) -> isize`
+ = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize`
+note: function defined here
+ --> $DIR/fn-item-type.rs:7:4
+ |
+LL | fn eq<T>(x: T, y: T) { }
+ | ^^ ---- ----
+
+error[E0308]: mismatched types
+ --> $DIR/fn-item-type.rs:29:23
+ |
+LL | eq(bar::<String>, bar::<Vec<u8>>);
+ | -- ^^^^^^^^^^^^^^ expected struct `String`, found struct `Vec`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn item `fn(_) -> _ {bar::<String>}`
+ found fn item `fn(_) -> _ {bar::<Vec<u8>>}`
+ = note: different `fn` items always have unique types, even if their signatures are the same
+ = help: change the expected type to be function pointer `fn(isize) -> isize`
+ = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `bar::<String> as fn(isize) -> isize`
+note: function defined here
+ --> $DIR/fn-item-type.rs:7:4
+ |
+LL | fn eq<T>(x: T, y: T) { }
+ | ^^ ---- ----
+
+error[E0308]: mismatched types
+ --> $DIR/fn-item-type.rs:38:26
+ |
+LL | eq(<u8 as Foo>::foo, <u16 as Foo>::foo);
+ | -- ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn item `fn() {<u8 as Foo>::foo}`
+ found fn item `fn() {<u16 as Foo>::foo}`
+ = note: different `fn` items always have unique types, even if their signatures are the same
+ = help: change the expected type to be function pointer `fn()`
+ = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `<u8 as Foo>::foo as fn()`
+note: function defined here
+ --> $DIR/fn-item-type.rs:7:4
+ |
+LL | fn eq<T>(x: T, y: T) { }
+ | ^^ ---- ----
+
+error[E0308]: mismatched types
+ --> $DIR/fn-item-type.rs:45:19
+ |
+LL | eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn item `fn(_) -> _ {foo::<u8>}`
+ found fn pointer `fn(_) -> _`
+ = help: change the expected type to be function pointer `fn(isize) -> isize`
+ = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize`
+note: function defined here
+ --> $DIR/fn-item-type.rs:7:4
+ |
+LL | fn eq<T>(x: T, y: T) { }
+ | ^^ ---- ----
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/fn/fn-recover-return-sign.fixed b/src/test/ui/fn/fn-recover-return-sign.fixed
new file mode 100644
index 000000000..076be6a35
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+#![allow(unused)]
+fn a() -> usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn b()-> usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn bar(_: u32) {}
+
+fn baz() -> *const dyn Fn(u32) { unimplemented!() }
+
+fn foo() {
+ match () {
+ _ if baz() == &bar as &dyn Fn(u32) => (),
+ () => (),
+ }
+}
+
+fn main() {
+ let foo = |a: bool| -> bool { a };
+ //~^ ERROR return types are denoted using `->`
+ dbg!(foo(false));
+
+ let bar = |a: bool|-> bool { a };
+ //~^ ERROR return types are denoted using `->`
+ dbg!(bar(false));
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign.rs b/src/test/ui/fn/fn-recover-return-sign.rs
new file mode 100644
index 000000000..0656023c0
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+#![allow(unused)]
+fn a() => usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn b(): usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn bar(_: u32) {}
+
+fn baz() -> *const dyn Fn(u32) { unimplemented!() }
+
+fn foo() {
+ match () {
+ _ if baz() == &bar as &dyn Fn(u32) => (),
+ () => (),
+ }
+}
+
+fn main() {
+ let foo = |a: bool| => bool { a };
+ //~^ ERROR return types are denoted using `->`
+ dbg!(foo(false));
+
+ let bar = |a: bool|: bool { a };
+ //~^ ERROR return types are denoted using `->`
+ dbg!(bar(false));
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign.stderr b/src/test/ui/fn/fn-recover-return-sign.stderr
new file mode 100644
index 000000000..983109730
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign.stderr
@@ -0,0 +1,26 @@
+error: return types are denoted using `->`
+ --> $DIR/fn-recover-return-sign.rs:3:8
+ |
+LL | fn a() => usize { 0 }
+ | ^^ help: use `->` instead
+
+error: return types are denoted using `->`
+ --> $DIR/fn-recover-return-sign.rs:6:7
+ |
+LL | fn b(): usize { 0 }
+ | ^ help: use `->` instead
+
+error: return types are denoted using `->`
+ --> $DIR/fn-recover-return-sign.rs:21:25
+ |
+LL | let foo = |a: bool| => bool { a };
+ | ^^ help: use `->` instead
+
+error: return types are denoted using `->`
+ --> $DIR/fn-recover-return-sign.rs:25:24
+ |
+LL | let bar = |a: bool|: bool { a };
+ | ^ help: use `->` instead
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/fn/fn-recover-return-sign2.rs b/src/test/ui/fn/fn-recover-return-sign2.rs
new file mode 100644
index 000000000..31f56565c
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign2.rs
@@ -0,0 +1,8 @@
+// Separate test file because `Fn() => bool` isn't getting fixed and rustfix complained that
+// even though a fix was applied the code was still incorrect
+
+fn foo() => impl Fn() => bool {
+ //~^ ERROR return types are denoted using `->`
+ //~| ERROR expected one of `+`, `->`, `::`, `where`, or `{`, found `=>`
+ unimplemented!()
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign2.stderr b/src/test/ui/fn/fn-recover-return-sign2.stderr
new file mode 100644
index 000000000..25ee8dd0c
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign2.stderr
@@ -0,0 +1,14 @@
+error: return types are denoted using `->`
+ --> $DIR/fn-recover-return-sign2.rs:4:10
+ |
+LL | fn foo() => impl Fn() => bool {
+ | ^^ help: use `->` instead
+
+error: expected one of `+`, `->`, `::`, `where`, or `{`, found `=>`
+ --> $DIR/fn-recover-return-sign2.rs:4:23
+ |
+LL | fn foo() => impl Fn() => bool {
+ | ^^ expected one of `+`, `->`, `::`, `where`, or `{`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/fn/fn-trait-formatting.rs b/src/test/ui/fn/fn-trait-formatting.rs
new file mode 100644
index 000000000..636ac7107
--- /dev/null
+++ b/src/test/ui/fn/fn-trait-formatting.rs
@@ -0,0 +1,21 @@
+fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
+
+
+
+fn main() {
+ let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
+ //~^ ERROR mismatched types
+ //~| expected unit type `()`
+ //~| found struct `Box<dyn FnOnce(isize)>`
+ let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
+ //~^ ERROR mismatched types
+ //~| expected unit type `()`
+ //~| found struct `Box<dyn Fn(isize, isize)>`
+ let _: () = Box::new(|| -> isize { unimplemented!() }) as Box<dyn FnMut() -> isize>;
+ //~^ ERROR mismatched types
+ //~| expected unit type `()`
+ //~| found struct `Box<dyn FnMut() -> isize>`
+
+ needs_fn(1);
+ //~^ ERROR expected a `Fn<(isize,)>` closure, found `{integer}`
+}
diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr
new file mode 100644
index 000000000..ea88e401b
--- /dev/null
+++ b/src/test/ui/fn/fn-trait-formatting.stderr
@@ -0,0 +1,52 @@
+error[E0308]: mismatched types
+ --> $DIR/fn-trait-formatting.rs:6:17
+ |
+LL | let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found struct `Box<dyn FnOnce(isize)>`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-trait-formatting.rs:10:17
+ |
+LL | let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found struct `Box<dyn Fn(isize, isize)>`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-trait-formatting.rs:14:17
+ |
+LL | let _: () = Box::new(|| -> isize { unimplemented!() }) as Box<dyn FnMut() -> isize>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found struct `Box<dyn FnMut() -> isize>`
+
+error[E0277]: expected a `Fn<(isize,)>` closure, found `{integer}`
+ --> $DIR/fn-trait-formatting.rs:19:14
+ |
+LL | needs_fn(1);
+ | -------- ^ expected an `Fn<(isize,)>` closure, found `{integer}`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Fn<(isize,)>` is not implemented for `{integer}`
+note: required by a bound in `needs_fn`
+ --> $DIR/fn-trait-formatting.rs:1:31
+ |
+LL | fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
+ | ^^^^^^^^^^^^^^^^^^ required by this bound in `needs_fn`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/fn/fun-call-variants.rs b/src/test/ui/fn/fun-call-variants.rs
new file mode 100644
index 000000000..5b83e2620
--- /dev/null
+++ b/src/test/ui/fn/fun-call-variants.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+fn ho<F>(f: F) -> isize where F: FnOnce(isize) -> isize { let n: isize = f(3); return n; }
+
+fn direct(x: isize) -> isize { return x + 1; }
+
+pub fn main() {
+ let a: isize = direct(3); // direct
+ let b: isize = ho(direct); // indirect unbound
+
+ assert_eq!(a, b);
+}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs
new file mode 100644
index 000000000..5a92bcd37
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+trait Trait {
+ type Type;
+}
+
+impl<T> Trait for T {
+ type Type = ();
+}
+
+fn f<'a, 'b>(_: <&'a &'b () as Trait>::Type)
+where
+ 'a: 'a,
+ 'b: 'b,
+{
+}
+
+fn g<'a, 'b>() {
+ f::<'a, 'b>(());
+}
+
+fn main() {}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs
new file mode 100644
index 000000000..dc25ac086
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs
@@ -0,0 +1,25 @@
+// check-fail
+// See issue #91899. If we treat unnormalized args as WF, `Self` can also be a
+// source of unsoundness.
+
+pub trait Yokeable<'a>: 'static {
+ type Output: 'a;
+}
+
+impl<'a, T: 'static + ?Sized> Yokeable<'a> for &'static T {
+ type Output = &'a T;
+}
+
+pub trait ZeroCopyFrom<C: ?Sized>: for<'a> Yokeable<'a> {
+ /// Clone the cart `C` into a [`Yokeable`] struct, which may retain references into `C`.
+ fn zero_copy_from<'b>(cart: &'b C) -> <Self as Yokeable<'b>>::Output;
+}
+
+impl<T> ZeroCopyFrom<[T]> for &'static [T] {
+ fn zero_copy_from<'b>(cart: &'b [T]) -> &'b [T] {
+ //~^ the parameter
+ cart
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr
new file mode 100644
index 000000000..95cf4fb16
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/implied-bounds-unnorm-associated-type-3.rs:19:5
+ |
+LL | fn zero_copy_from<'b>(cart: &'b [T]) -> &'b [T] {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `[T]` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<T: 'static> ZeroCopyFrom<[T]> for &'static [T] {
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
new file mode 100644
index 000000000..04b6f4dd8
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
@@ -0,0 +1,23 @@
+// check-fail
+// See issue #91068. Types in the substs of an associated type can't be implied
+// to be WF, since they don't actually have to be constructed.
+
+trait Trait {
+ type Type;
+}
+
+impl<T> Trait for T {
+ type Type = ();
+}
+
+fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
+ s
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {
+ let x = String::from("Hello World!");
+ let y = f(&x, ());
+ drop(x);
+ println!("{}", y);
+}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
new file mode 100644
index 000000000..8096f0838
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+ --> $DIR/implied-bounds-unnorm-associated-type.rs:14:5
+ |
+LL | fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | s
+ | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/fn/issue-80179.rs b/src/test/ui/fn/issue-80179.rs
new file mode 100644
index 000000000..fcef6f1b6
--- /dev/null
+++ b/src/test/ui/fn/issue-80179.rs
@@ -0,0 +1,27 @@
+// Functions with a type placeholder `_` as the return type should
+// show a function pointer suggestion when given a function item
+// and suggest how to return closures correctly from a function.
+// This is a regression test of #80179
+
+fn returns_i32() -> i32 {
+ 0
+}
+
+fn returns_fn_ptr() -> _ {
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
+//~| NOTE not allowed in type signatures
+//~| HELP replace with the correct return type
+//~| SUGGESTION fn() -> i32
+ returns_i32
+}
+
+fn returns_closure() -> _ {
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
+//~| NOTE not allowed in type signatures
+//~| HELP consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
+//~| NOTE for more information on `Fn` traits and closure types, see
+// https://doc.rust-lang.org/book/ch13-01-closures.html
+ || 0
+}
+
+fn main() {}
diff --git a/src/test/ui/fn/issue-80179.stderr b/src/test/ui/fn/issue-80179.stderr
new file mode 100644
index 000000000..2ca4ae982
--- /dev/null
+++ b/src/test/ui/fn/issue-80179.stderr
@@ -0,0 +1,21 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+ --> $DIR/issue-80179.rs:10:24
+ |
+LL | fn returns_fn_ptr() -> _ {
+ | ^
+ | |
+ | not allowed in type signatures
+ | help: replace with the correct return type: `fn() -> i32`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+ --> $DIR/issue-80179.rs:18:25
+ |
+LL | fn returns_closure() -> _ {
+ | ^ not allowed in type signatures
+ |
+ = help: consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
+ = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/fn/keyword-order.rs b/src/test/ui/fn/keyword-order.rs
new file mode 100644
index 000000000..8a21db673
--- /dev/null
+++ b/src/test/ui/fn/keyword-order.rs
@@ -0,0 +1,6 @@
+// edition:2018
+
+default pub const async unsafe extern fn err() {} //~ ERROR `default` is not followed by an item
+//~^ ERROR expected item, found keyword `pub`
+
+pub default const async unsafe extern fn ok() {}
diff --git a/src/test/ui/fn/keyword-order.stderr b/src/test/ui/fn/keyword-order.stderr
new file mode 100644
index 000000000..d3b140c85
--- /dev/null
+++ b/src/test/ui/fn/keyword-order.stderr
@@ -0,0 +1,16 @@
+error: `default` is not followed by an item
+ --> $DIR/keyword-order.rs:3:1
+ |
+LL | default pub const async unsafe extern fn err() {}
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: expected item, found keyword `pub`
+ --> $DIR/keyword-order.rs:3:9
+ |
+LL | default pub const async unsafe extern fn err() {}
+ | ^^^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/fn/nested-function-names-issue-8587.rs b/src/test/ui/fn/nested-function-names-issue-8587.rs
new file mode 100644
index 000000000..8fafd41d9
--- /dev/null
+++ b/src/test/ui/fn/nested-function-names-issue-8587.rs
@@ -0,0 +1,42 @@
+// run-pass
+// Make sure nested functions are separate, even if they have
+// equal name.
+//
+// Issue #8587
+
+
+pub struct X;
+
+impl X {
+ fn f(&self) -> isize {
+ #[inline(never)]
+ fn inner() -> isize {
+ 0
+ }
+ inner()
+ }
+
+ fn g(&self) -> isize {
+ #[inline(never)]
+ fn inner_2() -> isize {
+ 1
+ }
+ inner_2()
+ }
+
+ fn h(&self) -> isize {
+ #[inline(never)]
+ fn inner() -> isize {
+ 2
+ }
+ inner()
+ }
+}
+
+pub fn main() {
+ let n = X;
+ assert_eq!(n.f(), 0);
+ assert_eq!(n.g(), 1);
+ // This test `h` used to fail.
+ assert_eq!(n.h(), 2);
+}