diff options
| author | Amanda Stjerna <amanda.stjerna@it.uu.se> | 2025-04-17 10:36:37 +0200 |
|---|---|---|
| committer | Amanda Stjerna <amanda.stjerna@it.uu.se> | 2025-04-22 12:07:53 +0200 |
| commit | e9d374c6573a413f598c9b52f938a8abd5e041cf (patch) | |
| tree | c53f2acb268911c63749aa0c903ce9f5972e7998 | |
| parent | c4b38a596767c9c6275c937cf3a2d4b9612b4875 (diff) | |
| download | rust-e9d374c6573a413f598c9b52f938a8abd5e041cf.tar.gz rust-e9d374c6573a413f598c9b52f938a8abd5e041cf.zip | |
Add tests for two untested cases of placeholder relations
During work on #130227, I discovered several situations not covered by any previously existing UI test. This commit introudces tests to cover that.
3 files changed, 110 insertions, 0 deletions
diff --git a/tests/ui/borrowck/static-trait-bound-lost.rs b/tests/ui/borrowck/static-trait-bound-lost.rs new file mode 100644 index 00000000000..0288acea0f6 --- /dev/null +++ b/tests/ui/borrowck/static-trait-bound-lost.rs @@ -0,0 +1,54 @@ +// This test is a reduced version of a bug introduced during work on type-tests for Polonius. +// The underlying problem is that the 'static bound is lost for a type parameter that is +// threaded deeply enough, causing an error. +// The bug was first observed in exr-1.4.1/src/image/read/mod.rs:124:5 during perf test. + +//@ check-pass + +use std::marker::PhantomData; + +struct ReadAllLayers<ReadChannels> { + px: PhantomData<ReadChannels>, +} + +trait ReadLayers<'s> {} + +impl<'s, C> ReadLayers<'s> for ReadAllLayers<C> where C: ReadChannels<'s> {} + +fn make_builder<A, Set, Pixels>( + _: Set, +) -> ReadAllLayers<CollectPixels<A, Pixels, Set>> +where + Set: Fn(&mut Pixels), +{ + todo!() +} + +struct CollectPixels<Pixel, PixelStorage, SetPixel> { + px: PhantomData<(SetPixel, Pixel, PixelStorage)>, +} + +impl<'s, PixelStorage, SetPixel: 's> ReadChannels<'s> + for CollectPixels<usize, PixelStorage, SetPixel> +where + SetPixel: Fn(&mut PixelStorage), +{ +} + +trait ReadChannels<'s> {} + +fn from_file<L>(_: L) +where + for<'s> L: ReadLayers<'s>, +{ +} + +pub fn read_all_rgba_layers_from_file<Set: 'static, Pixels: 'static>( + set_pixel: Set, +) where + Set: Fn(&mut Pixels), +{ + from_file(make_builder(set_pixel)); // Error triggered. +} + +pub fn main() {} diff --git a/tests/ui/nll/relate_tys/placeholder-outlives-existential.rs b/tests/ui/nll/relate_tys/placeholder-outlives-existential.rs new file mode 100644 index 00000000000..3f22e9a313a --- /dev/null +++ b/tests/ui/nll/relate_tys/placeholder-outlives-existential.rs @@ -0,0 +1,31 @@ +// Test that we correctly handle some cases of placeholder leaks. +// +//@ compile-flags:-Zno-leak-check + + +struct Co<'a>(&'a ()); +struct Inv<'a>(*mut &'a ()); +struct Contra<'a>(fn(&'a ())); + +// `exists<'e> forall<'p> 'p: 'e` -> ERROR +fn p_outlives_e( + x: for<'e> fn(for<'p> fn(fn(fn(Contra<'e>, Co<'p>)))), +) -> fn(fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) { + x //~ ERROR mismatched types [E0308] +} + +// `exists<'e> forall<'p> 'e: 'p` -> Ok, 'e: 'static +fn e_outlives_p_static( + x: for<'e> fn(Inv<'e>, for<'p> fn(fn(fn(Contra<'p>, Co<'e>)))), +) -> fn(Inv<'static>, fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) { + x +} + +// `exists<'e> forall<'p> 'e: 'p` -> Ok, 'e: 'static -> ERROR +fn e_outlives_p_static_err<'not_static>( + x: for<'e> fn(Inv<'e>, for<'p> fn(fn(fn(Contra<'p>, Co<'e>)))), +) -> fn(Inv<'not_static>, fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) { + x //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/relate_tys/placeholder-outlives-existential.stderr b/tests/ui/nll/relate_tys/placeholder-outlives-existential.stderr new file mode 100644 index 00000000000..80ab5c8d6e9 --- /dev/null +++ b/tests/ui/nll/relate_tys/placeholder-outlives-existential.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/placeholder-outlives-existential.rs:14:5 + | +LL | x + | ^ one type is more general than the other + | + = note: expected fn pointer `fn(fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>))))` + found fn pointer `for<'e> fn(for<'e, 'p> fn(for<'e, 'p> fn(for<'e, 'p> fn(Contra<'e>, Co<'p>))))` + +error: lifetime may not live long enough + --> $DIR/placeholder-outlives-existential.rs:28:5 + | +LL | fn e_outlives_p_static_err<'not_static>( + | ----------- lifetime `'not_static` defined here +... +LL | x + | ^ returning this value requires that `'not_static` must outlive `'static` + | + = 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 <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. |
