From dc0db358abe19481e475e10c32149b53370f1a1c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:57:31 +0200 Subject: Merging upstream version 1.72.1+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs | 99 ++++++++++++++++++++++++++ tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr | 39 ++++++++++ tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs | 14 ++++ tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr | 35 +++++++++ tests/ui/rfcs/rfc-1623-static/rfc1623.rs | 75 +++++++++++++++++++ 5 files changed, 262 insertions(+) create mode 100644 tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs create mode 100644 tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr create mode 100644 tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs create mode 100644 tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr create mode 100644 tests/ui/rfcs/rfc-1623-static/rfc1623.rs (limited to 'tests/ui/rfcs/rfc-1623-static') diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs new file mode 100644 index 000000000..c0e13a5f5 --- /dev/null +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs @@ -0,0 +1,99 @@ +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { + a +} + +// The incorrect case without `for<'a>` is tested for in `rfc1623-2.rs` +static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = + &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); + +struct SomeStruct<'x, 'y, 'z: 'x> { + foo: &'x Foo<'z>, + bar: &'x Bar<'z>, + f: &'y dyn for<'a, 'b> Fn(&'a Foo<'b>) -> &'a Foo<'b>, +} + +// Without this, the wf-check will fail early so we'll never see the +// error in SOME_STRUCT's body. +unsafe impl<'x, 'y, 'z: 'x> Sync for SomeStruct<'x, 'y, 'z> {} + +fn id(t: T) -> T { + t +} + +static SOME_STRUCT: &SomeStruct = &SomeStruct { + foo: &Foo { bools: &[false, true] }, + bar: &Bar { bools: &[true, true] }, + f: &id, + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough +}; + +// very simple test for a 'static static with default lifetime +static STATIC_STR: &'static str = "&'static str"; +const CONST_STR: &'static str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR: &'static str = "&'static str"; +const EXPLICIT_CONST_STR: &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { + arg +} + +// one with a function, argument elided +static STATIC_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) {} + +static STATIC_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool], +} + +static STATIC_FOO: Foo<'static> = Foo { bools: &[true, false] }; +const CONST_FOO: Foo<'static> = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR: Bar<'static> = Bar { bools: &[true, false] }; +const CONST_BAR: Bar<'static> = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { + e.first().map(|x| *x) +} + +static STATIC_BAZ: &'static Baz<'static> = &(baz as Baz); +const CONST_BAZ: &'static Baz<'static> = &(baz as Baz); + +static BYTES: &'static [u8] = &[1, 2, 3]; + +fn main() { + let x = &[1u8, 2, 3]; + let y = x; + + // this works, so lifetime < `'static` is valid + assert_eq!(Some(1), STATIC_BAZ(y)); + assert_eq!(Some(1), CONST_BAZ(y)); + + let y = &[1u8, 2, 3]; + + STATIC_BAZ(BYTES); // BYTES has static lifetime + CONST_BAZ(y); // interestingly this does not get reported +} diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr new file mode 100644 index 000000000..d183eaaa6 --- /dev/null +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/rfc1623-2.rs:28:8 + | +LL | f: &id, + | ^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> Fn<(&'a Foo<'b>,)>` + found trait `Fn<(&Foo<'_>,)>` + +error[E0308]: mismatched types + --> $DIR/rfc1623-2.rs:28:8 + | +LL | f: &id, + | ^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> Fn<(&'a Foo<'b>,)>` + found trait `Fn<(&Foo<'_>,)>` + +error: implementation of `FnOnce` is not general enough + --> $DIR/rfc1623-2.rs:28:8 + | +LL | f: &id, + | ^^^ implementation of `FnOnce` is not general enough + | + = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` + +error: implementation of `FnOnce` is not general enough + --> $DIR/rfc1623-2.rs:28:8 + | +LL | f: &id, + | ^^^ implementation of `FnOnce` is not general enough + | + = note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&'a Foo<'1>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs new file mode 100644 index 000000000..26fa6fdb5 --- /dev/null +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { + a +} + +// the boundaries of elision +static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = +//~^ ERROR missing lifetime specifier [E0106] + &(non_elidable as fn(&u8, &u8) -> &u8); + //~^ ERROR missing lifetime specifier [E0106] + //~| ERROR non-primitive cast + +fn main() {} diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr new file mode 100644 index 000000000..77fc3f041 --- /dev/null +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr @@ -0,0 +1,35 @@ +error[E0106]: missing lifetime specifier + --> $DIR/rfc1623-3.rs:8:42 + | +LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = + | --- --- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = + | +++++++ ++ ++ ++ + +error[E0106]: missing lifetime specifier + --> $DIR/rfc1623-3.rs:10:39 + | +LL | &(non_elidable as fn(&u8, &u8) -> &u8); + | --- --- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); + | +++++++ ++ ++ ++ + +error[E0605]: non-primitive cast: `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {non_elidable}` as `for<'a, 'b> fn(&'a u8, &'b u8) -> &u8` + --> $DIR/rfc1623-3.rs:10:6 + | +LL | &(non_elidable as fn(&u8, &u8) -> &u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0106, E0605. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623.rs b/tests/ui/rfcs/rfc-1623-static/rfc1623.rs new file mode 100644 index 000000000..adaf25c6b --- /dev/null +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623.rs @@ -0,0 +1,75 @@ +// run-pass +#![allow(unused_variables)] +#![allow(non_upper_case_globals)] + +#![allow(dead_code)] + +// very simple test for a 'static static with default lifetime +static STATIC_STR: &str = "&'static str"; +const CONST_STR: &str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR: &'static str = "&'static str"; +const EXPLICIT_CONST_STR: &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { + arg +} + +// one with a function, argument elided +static STATIC_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) {} + +static STATIC_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool], +} + +static STATIC_FOO: Foo = Foo { bools: &[true, false] }; +const CONST_FOO: Foo = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR: Bar = Bar { bools: &[true, false] }; +const CONST_BAR: Bar = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { + e.first().map(|x| *x) +} + +static STATIC_BAZ: &Baz = &(baz as Baz); +const CONST_BAZ: &Baz = &(baz as Baz); + +static BYTES: &[u8] = &[1, 2, 3]; + +fn main() { + // make sure that the lifetime is actually elided (and not defaulted) + let x = &[1u8, 2, 3]; + STATIC_SIMPLE_FN(x); + CONST_SIMPLE_FN(x); + + STATIC_BAZ(BYTES); // neees static lifetime + CONST_BAZ(BYTES); + + // make sure this works with different lifetimes + let a = &1; + { + let b = &2; + let c = &3; + CONST_MULTI_FN(a, b, c); + } +} -- cgit v1.2.3