diff options
| author | bors <bors@rust-lang.org> | 2020-07-23 13:43:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-23 13:43:42 +0000 |
| commit | 39a295f52637817ba8584cb9bcebef91fd0a9f4f (patch) | |
| tree | 3d9c987feb7802589db52babccb901dcd31a34e6 /src | |
| parent | 371917ab218de72a625227ba6eed7e84e610a058 (diff) | |
| parent | 45c01edaf21f9052eec8d04cb32c7724eb627e03 (diff) | |
| download | rust-39a295f52637817ba8584cb9bcebef91fd0a9f4f.tar.gz rust-39a295f52637817ba8584cb9bcebef91fd0a9f4f.zip | |
Auto merge of #74509 - matthewjasper:empty-verify, r=nikomatsakis
Use `ReEmpty(U0)` as the implicit region bound in typeck Fixes #74429 r? @nikomatsakis
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc_typeck/check/regionck.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs | 66 | ||||
| -rw-r--r-- | src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs | 35 |
4 files changed, 102 insertions, 10 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 04e02704296..6e77aba3050 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<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, } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index b72152d1911..221e5f72dc9 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 00000000000..a65c17e0efc --- /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<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() {} 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 00000000000..d463f311c34 --- /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: 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() {} |
