Skip to content

Add tests for two untested cases of placeholder relations #139960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions tests/ui/borrowck/static-trait-bound-lost.rs
Original file line number Diff line number Diff line change
@@ -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() {}
31 changes: 31 additions & 0 deletions tests/ui/nll/relate_tys/placeholder-outlives-existential.rs
Original file line number Diff line number Diff line change
@@ -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() {}
25 changes: 25 additions & 0 deletions tests/ui/nll/relate_tys/placeholder-outlives-existential.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading