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.
This commit is contained in:
parent
c4b38a5967
commit
e9d374c657
3 changed files with 110 additions and 0 deletions
54
tests/ui/borrowck/static-trait-bound-lost.rs
Normal file
54
tests/ui/borrowck/static-trait-bound-lost.rs
Normal file
|
@ -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
tests/ui/nll/relate_tys/placeholder-outlives-existential.rs
Normal file
31
tests/ui/nll/relate_tys/placeholder-outlives-existential.rs
Normal file
|
@ -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() {}
|
|
@ -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…
Add table
Add a link
Reference in a new issue