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 --- ...subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr | 17 ++++ .../subtype/hr-subtype.bound_a_vs_free_x.stderr | 17 ++++ .../hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr | 31 ++++++ .../hr-subtype.free_inv_x_vs_free_inv_y.stderr | 42 ++++++++ .../subtype/hr-subtype.free_x_vs_free_y.stderr | 19 ++++ tests/ui/higher-ranked/subtype/hr-subtype.rs | 111 +++++++++++++++++++++ .../subtype/placeholder-pattern-fail.rs | 25 +++++ .../subtype/placeholder-pattern-fail.stderr | 12 +++ .../higher-ranked/subtype/placeholder-pattern.rs | 18 ++++ tests/ui/higher-ranked/subtype/return-static.rs | 13 +++ 10 files changed, 305 insertions(+) create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.rs create mode 100644 tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs create mode 100644 tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr create mode 100644 tests/ui/higher-ranked/subtype/placeholder-pattern.rs create mode 100644 tests/ui/higher-ranked/subtype/return-static.rs (limited to 'tests/ui/higher-ranked/subtype') diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr new file mode 100644 index 000000000..b7264c7e9 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, +LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) } + | |_____________________________________________- in this macro invocation + | + = note: expected enum `Option fn(&'a u32, &'b u32) -> &'a u32>` + found enum `Option fn(&'a u32, &'a u32) -> &'a u32>` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr new file mode 100644 index 000000000..2355979b0 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), +LL | | fn(&'x u32)) } + | |______________- in this macro invocation + | + = note: expected enum `Option fn(&'a u32)>` + found enum `Option` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr new file mode 100644 index 000000000..a73c03feb --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } + | |__________________________________- in this macro invocation + | + = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` + found enum `Option fn(Inv<'a>, Inv<'a>)>` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } + | |__________________________________- in this macro invocation + | + = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` + found enum `Option fn(Inv<'a>, Inv<'a>)>` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr new file mode 100644 index 000000000..31d36d716 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr @@ -0,0 +1,42 @@ +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:48:13 + | +LL | fn subtype<'x, 'y: 'x, 'z: 'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t2>(None::<$t1>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +LL | | fn(Inv<'y>)) } + | |______________- in this macro invocation + | + = help: consider adding the following bound: `'x: 'y` + = note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Inv<'a>` is invariant over the parameter `'a` + = help: see for more information about variance + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:54:13 + | +LL | fn supertype<'x, 'y: 'x, 'z: 'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +LL | | fn(Inv<'y>)) } + | |______________- in this macro invocation + | + = help: consider adding the following bound: `'x: 'y` + = note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Inv<'a>` is invariant over the parameter `'a` + = help: see for more information about variance + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr new file mode 100644 index 000000000..269cde54c --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr @@ -0,0 +1,19 @@ +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:54:13 + | +LL | fn supertype<'x, 'y: 'x, 'z: 'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_x_vs_free_y: (fn(&'x u32), +LL | | fn(&'y u32)) } + | |______________- in this macro invocation + | + = help: consider adding the following bound: `'x: 'y` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.rs b/tests/ui/higher-ranked/subtype/hr-subtype.rs new file mode 100644 index 000000000..c770e0de8 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.rs @@ -0,0 +1,111 @@ +// Targeted tests for the higher-ranked subtyping code. + +#![allow(dead_code)] + +// revisions: bound_a_vs_bound_a +// revisions: bound_a_vs_bound_b +// revisions: bound_inv_a_vs_bound_inv_b +// revisions: bound_co_a_vs_bound_co_b +// revisions: bound_a_vs_free_x +// revisions: free_x_vs_free_x +// revisions: free_x_vs_free_y +// revisions: free_inv_x_vs_free_inv_y +// revisions: bound_a_b_vs_bound_a +// revisions: bound_co_a_b_vs_bound_co_a +// revisions: bound_contra_a_contra_b_ret_co_a +// revisions: bound_co_a_co_b_ret_contra_a +// revisions: bound_inv_a_b_vs_bound_inv_a +// revisions: bound_a_b_ret_a_vs_bound_a_ret_a + +//[bound_a_vs_bound_a] check-pass +//[bound_a_vs_bound_b] check-pass +//[bound_inv_a_vs_bound_inv_b] check-pass +//[bound_co_a_vs_bound_co_b] check-pass +//[free_x_vs_free_x] check-pass +//[bound_co_a_b_vs_bound_co_a] check-pass +//[bound_co_a_co_b_ret_contra_a] check-pass +//[bound_a_b_vs_bound_a] check-pass +//[bound_contra_a_contra_b_ret_co_a] check-pass + +fn gimme(_: Option) {} + +struct Inv<'a> { + x: *mut &'a u32, +} + +struct Co<'a> { + x: fn(&'a u32), +} + +struct Contra<'a> { + x: &'a u32, +} + +macro_rules! check { + ($rev:ident: ($t1:ty, $t2:ty)) => { + #[cfg($rev)] + fn subtype<'x, 'y: 'x, 'z: 'y>() { + gimme::<$t2>(None::<$t1>); + //[free_inv_x_vs_free_inv_y]~^ ERROR + } + + #[cfg($rev)] + fn supertype<'x, 'y: 'x, 'z: 'y>() { + gimme::<$t1>(None::<$t2>); + //[bound_a_vs_free_x]~^ ERROR + //[free_x_vs_free_y]~^^ ERROR + //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR + //[bound_inv_a_b_vs_bound_inv_a]~| ERROR + //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^^ ERROR + //[free_inv_x_vs_free_inv_y]~^^^^^^ ERROR + } + }; +} + +// If both have bound regions, they are equivalent, regardless of +// variant. +check! { bound_a_vs_bound_a: (for<'a> fn(&'a u32), +for<'a> fn(&'a u32)) } +check! { bound_a_vs_bound_b: (for<'a> fn(&'a u32), +for<'b> fn(&'b u32)) } +check! { bound_inv_a_vs_bound_inv_b: (for<'a> fn(Inv<'a>), +for<'b> fn(Inv<'b>)) } +check! { bound_co_a_vs_bound_co_b: (for<'a> fn(Co<'a>), +for<'b> fn(Co<'b>)) } + +// Bound is a subtype of free. +check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), +fn(&'x u32)) } + +// Two free regions are relatable if subtyping holds. +check! { free_x_vs_free_x: (fn(&'x u32), +fn(&'x u32)) } +check! { free_x_vs_free_y: (fn(&'x u32), +fn(&'y u32)) } +check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +fn(Inv<'y>)) } + +// Somewhat surprisingly, a fn taking two distinct bound lifetimes and +// a fn taking one bound lifetime can be interchangeable, but only if +// we are co- or contra-variant with respect to both lifetimes. +// +// The reason is: +// - if we are covariant, then 'a and 'b can be set to the call-site +// intersection; +// - if we are contravariant, then 'a can be inferred to 'static. +check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), +for<'a> fn(&'a u32, &'a u32)) } +check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), +for<'a> fn(Co<'a>, Co<'a>)) } +check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, +for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } +check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, +for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } + +// If we make those lifetimes invariant, then the two types are not interchangeable. +check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +for<'a> fn(Inv<'a>, Inv<'a>)) } +check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, +for<'a> fn(&'a u32, &'a u32) -> &'a u32) } + +fn main() {} diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs new file mode 100644 index 000000000..bd4533e04 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs @@ -0,0 +1,25 @@ +// Check that incorrect higher ranked subtyping +// causes an error. +struct Inv<'a>(fn(&'a ()) -> &'a ()); +fn hr_subtype<'c>(f: for<'a, 'b> fn(Inv<'a>, Inv<'a>)) { + // ok + let _: for<'a> fn(Inv<'a>, Inv<'a>) = f; + let sub: for<'a> fn(Inv<'a>, Inv<'a>) = f; + // no + let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; + //~^ ERROR mismatched types +} + +fn simple1<'c>(x: (&'c i32,)) { + let _x: (&'static i32,) = x; +} + +fn simple2<'c>(x: (&'c i32,)) { + let _: (&'static i32,) = x; +} + +fn main() { + hr_subtype(|_, _| {}); + simple1((&3,)); + simple2((&3,)); +} diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr new file mode 100644 index 000000000..73b0a3173 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/placeholder-pattern-fail.rs:9:47 + | +LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; + | ^^^ one type is more general than the other + | + = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)` + found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern.rs new file mode 100644 index 000000000..061e66e54 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/placeholder-pattern.rs @@ -0,0 +1,18 @@ +// check-pass +// Check that higher ranked subtyping correctly works when using +// placeholder patterns. +fn hr_subtype<'c>(f: for<'a, 'b> fn(&'a (), &'b ())) { + let _: for<'a> fn(&'a (), &'a ()) = f; + let _: for<'a, 'b> fn(&'a (), &'b ()) = f; + let _: for<'a> fn(&'a (), &'c ()) = f; + let _: fn(&'c (), &'c ()) = f; +} + +fn simple<'c>(x: (&'static i32,)) { + let _: (&'c i32,) = x; +} + +fn main() { + hr_subtype(|_, _| {}); + simple((&3,)); +} diff --git a/tests/ui/higher-ranked/subtype/return-static.rs b/tests/ui/higher-ranked/subtype/return-static.rs new file mode 100644 index 000000000..6455854f3 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/return-static.rs @@ -0,0 +1,13 @@ +// check-pass + +fn make() -> T { + panic!() +} + +fn take(x: T) {} + +fn main() { + let x: for<'a> fn(&'a u32) -> _ = make(); + let y: &'static u32 = x(&22); + take:: fn(&'b u32) -> &'b u32>(x); +} -- cgit v1.2.3