diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/fn | |
parent | Initial commit. (diff) | |
download | rustc-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')
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); +} |