-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #74509 - matthewjasper:empty-verify, r=nikomatsakis
Use `ReEmpty(U0)` as the implicit region bound in typeck Fixes #74429 r? @nikomatsakis
- Loading branch information
Showing
4 changed files
with
102 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Regression test for #74429, where we didn't think that a type parameter | ||
// outlived `ReEmpty`. | ||
|
||
// check-pass | ||
|
||
use std::marker::PhantomData; | ||
use std::ptr::NonNull; | ||
|
||
pub unsafe trait RawData { | ||
type Elem; | ||
} | ||
|
||
unsafe impl<A> RawData for OwnedRepr<A> { | ||
type Elem = A; | ||
} | ||
|
||
unsafe impl<'a, A> RawData for ViewRepr<&'a A> { | ||
type Elem = A; | ||
} | ||
|
||
pub struct OwnedRepr<A> { | ||
ptr: PhantomData<A>, | ||
} | ||
|
||
// these Copy impls are not necessary for the repro, but allow the code to compile without error | ||
// on 1.44.1 | ||
#[derive(Copy, Clone)] | ||
pub struct ViewRepr<A> { | ||
life: PhantomData<A>, | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct ArrayBase<S> | ||
where | ||
S: RawData, | ||
{ | ||
ptr: NonNull<S::Elem>, | ||
} | ||
|
||
pub type Array<A> = ArrayBase<OwnedRepr<A>>; | ||
|
||
pub type ArrayView<'a, A> = ArrayBase<ViewRepr<&'a A>>; | ||
|
||
impl<A, S> ArrayBase<S> | ||
where | ||
S: RawData<Elem = A>, | ||
{ | ||
pub fn index_axis(&self) -> ArrayView<'_, A> { | ||
unimplemented!() | ||
} | ||
|
||
pub fn axis_iter<'a>(&'a self) -> std::iter::Empty<&'a A> { | ||
unimplemented!() | ||
} | ||
} | ||
|
||
pub fn x<T: Copy>(a: Array<T>) { | ||
// drop just avoids a must_use warning | ||
drop((0..1).filter(|_| true)); | ||
let y = a.index_axis(); | ||
a.axis_iter().for_each(|_| { | ||
drop(y); | ||
}); | ||
} | ||
|
||
fn main() {} |
35 changes: 35 additions & 0 deletions
35
src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Regression test for #74429, where we didn't think that a type parameter | ||
// outlived `ReEmpty`. | ||
|
||
// check-pass | ||
|
||
use std::marker::PhantomData; | ||
|
||
fn apply<T, F: FnOnce(T)>(_: T, _: F) {} | ||
|
||
#[derive(Clone, Copy)] | ||
struct Invariant<T> { | ||
t: T, | ||
p: PhantomData<fn(T) -> T>, | ||
} | ||
|
||
fn verify_reempty<T>(x: T) { | ||
// r is inferred to have type `Invariant<&ReEmpty(U0) T>` | ||
let r = Invariant { t: &x, p: PhantomData }; | ||
// Creates a new universe, all variables from now on are in `U1`, say. | ||
let _: fn(&()) = |_| {}; | ||
// Closure parameter is of type `&ReEmpty(U1) T`, so the closure has an implied | ||
// bound of `T: ReEmpty(U1)` | ||
apply(&x, |_| { | ||
// Requires `typeof(r)` is well-formed, i.e. `T: ReEmpty(U0)`. If we | ||
// only have the implied bound from the closure parameter to use this | ||
// requires `ReEmpty(U1): ReEmpty(U0)`, which isn't true so we reported | ||
// an error. | ||
// | ||
// This doesn't happen any more because we ensure that `T: ReEmpty(U0)` | ||
// is an implicit bound for all type parameters. | ||
drop(r); | ||
}); | ||
} | ||
|
||
fn main() {} |