Use ReEmpty(U0) as the implicit region bound in typeck

This commit is contained in:
Matthew Jasper 2020-07-19 12:31:42 +01:00
parent 0701419e96
commit 45c01edaf2
4 changed files with 102 additions and 10 deletions

View file

@ -256,14 +256,6 @@ pub struct Inherited<'a, 'tcx> {
/// opaque type.
opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
/// Each type parameter has an implicit region bound that
/// indicates it must outlive at least the function body (the user
/// may specify stronger requirements). This field indicates the
/// region of the callee. If it is `None`, then the parameter
/// environment is for an item or something where the "callee" is
/// not clear.
implicit_region_bound: Option<ty::Region<'tcx>>,
body_id: Option<hir::BodyId>,
}
@ -684,7 +676,6 @@ impl Inherited<'a, 'tcx> {
deferred_generator_interiors: RefCell::new(Vec::new()),
opaque_types: RefCell::new(Default::default()),
opaque_types_vars: RefCell::new(Default::default()),
implicit_region_bound: None,
body_id,
}
}

View file

@ -309,7 +309,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
self.infcx.process_registered_region_obligations(
self.outlives_environment.region_bound_pairs_map(),
self.implicit_region_bound,
Some(self.tcx.lifetimes.re_root_empty),
self.param_env,
);

View file

@ -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() {}

View file

@ -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() {}