diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 04e02704296de..6e77aba30506a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -256,14 +256,6 @@ pub struct Inherited<'a, 'tcx> { /// opaque type. opaque_types_vars: RefCell, 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>, - body_id: Option, } @@ -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, } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index b72152d1911f7..221e5f72dc977 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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, ); diff --git a/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs new file mode 100644 index 0000000000000..a65c17e0efc3c --- /dev/null +++ b/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs @@ -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 RawData for OwnedRepr { + type Elem = A; +} + +unsafe impl<'a, A> RawData for ViewRepr<&'a A> { + type Elem = A; +} + +pub struct OwnedRepr { + ptr: PhantomData, +} + +// 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 { + life: PhantomData, +} + +#[derive(Copy, Clone)] +pub struct ArrayBase +where + S: RawData, +{ + ptr: NonNull, +} + +pub type Array = ArrayBase>; + +pub type ArrayView<'a, A> = ArrayBase>; + +impl ArrayBase +where + S: RawData, +{ + pub fn index_axis(&self) -> ArrayView<'_, A> { + unimplemented!() + } + + pub fn axis_iter<'a>(&'a self) -> std::iter::Empty<&'a A> { + unimplemented!() + } +} + +pub fn x(a: Array) { + // 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() {} diff --git a/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs b/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs new file mode 100644 index 0000000000000..d463f311c34e9 --- /dev/null +++ b/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs @@ -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) {} + +#[derive(Clone, Copy)] +struct Invariant { + t: T, + p: PhantomData T>, +} + +fn verify_reempty(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() {}