Skip to content

Commit 39a295f

Browse files
committed
Auto merge of #74509 - matthewjasper:empty-verify, r=nikomatsakis
Use `ReEmpty(U0)` as the implicit region bound in typeck Fixes #74429 r? @nikomatsakis
2 parents 371917a + 45c01ed commit 39a295f

File tree

4 files changed

+102
-10
lines changed

4 files changed

+102
-10
lines changed

src/librustc_typeck/check/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,6 @@ pub struct Inherited<'a, 'tcx> {
256256
/// opaque type.
257257
opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
258258

259-
/// Each type parameter has an implicit region bound that
260-
/// indicates it must outlive at least the function body (the user
261-
/// may specify stronger requirements). This field indicates the
262-
/// region of the callee. If it is `None`, then the parameter
263-
/// environment is for an item or something where the "callee" is
264-
/// not clear.
265-
implicit_region_bound: Option<ty::Region<'tcx>>,
266-
267259
body_id: Option<hir::BodyId>,
268260
}
269261

@@ -684,7 +676,6 @@ impl Inherited<'a, 'tcx> {
684676
deferred_generator_interiors: RefCell::new(Vec::new()),
685677
opaque_types: RefCell::new(Default::default()),
686678
opaque_types_vars: RefCell::new(Default::default()),
687-
implicit_region_bound: None,
688679
body_id,
689680
}
690681
}

src/librustc_typeck/check/regionck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
309309
fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
310310
self.infcx.process_registered_region_obligations(
311311
self.outlives_environment.region_bound_pairs_map(),
312-
self.implicit_region_bound,
312+
Some(self.tcx.lifetimes.re_root_empty),
313313
self.param_env,
314314
);
315315

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Regression test for #74429, where we didn't think that a type parameter
2+
// outlived `ReEmpty`.
3+
4+
// check-pass
5+
6+
use std::marker::PhantomData;
7+
use std::ptr::NonNull;
8+
9+
pub unsafe trait RawData {
10+
type Elem;
11+
}
12+
13+
unsafe impl<A> RawData for OwnedRepr<A> {
14+
type Elem = A;
15+
}
16+
17+
unsafe impl<'a, A> RawData for ViewRepr<&'a A> {
18+
type Elem = A;
19+
}
20+
21+
pub struct OwnedRepr<A> {
22+
ptr: PhantomData<A>,
23+
}
24+
25+
// these Copy impls are not necessary for the repro, but allow the code to compile without error
26+
// on 1.44.1
27+
#[derive(Copy, Clone)]
28+
pub struct ViewRepr<A> {
29+
life: PhantomData<A>,
30+
}
31+
32+
#[derive(Copy, Clone)]
33+
pub struct ArrayBase<S>
34+
where
35+
S: RawData,
36+
{
37+
ptr: NonNull<S::Elem>,
38+
}
39+
40+
pub type Array<A> = ArrayBase<OwnedRepr<A>>;
41+
42+
pub type ArrayView<'a, A> = ArrayBase<ViewRepr<&'a A>>;
43+
44+
impl<A, S> ArrayBase<S>
45+
where
46+
S: RawData<Elem = A>,
47+
{
48+
pub fn index_axis(&self) -> ArrayView<'_, A> {
49+
unimplemented!()
50+
}
51+
52+
pub fn axis_iter<'a>(&'a self) -> std::iter::Empty<&'a A> {
53+
unimplemented!()
54+
}
55+
}
56+
57+
pub fn x<T: Copy>(a: Array<T>) {
58+
// drop just avoids a must_use warning
59+
drop((0..1).filter(|_| true));
60+
let y = a.index_axis();
61+
a.axis_iter().for_each(|_| {
62+
drop(y);
63+
});
64+
}
65+
66+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Regression test for #74429, where we didn't think that a type parameter
2+
// outlived `ReEmpty`.
3+
4+
// check-pass
5+
6+
use std::marker::PhantomData;
7+
8+
fn apply<T, F: FnOnce(T)>(_: T, _: F) {}
9+
10+
#[derive(Clone, Copy)]
11+
struct Invariant<T> {
12+
t: T,
13+
p: PhantomData<fn(T) -> T>,
14+
}
15+
16+
fn verify_reempty<T>(x: T) {
17+
// r is inferred to have type `Invariant<&ReEmpty(U0) T>`
18+
let r = Invariant { t: &x, p: PhantomData };
19+
// Creates a new universe, all variables from now on are in `U1`, say.
20+
let _: fn(&()) = |_| {};
21+
// Closure parameter is of type `&ReEmpty(U1) T`, so the closure has an implied
22+
// bound of `T: ReEmpty(U1)`
23+
apply(&x, |_| {
24+
// Requires `typeof(r)` is well-formed, i.e. `T: ReEmpty(U0)`. If we
25+
// only have the implied bound from the closure parameter to use this
26+
// requires `ReEmpty(U1): ReEmpty(U0)`, which isn't true so we reported
27+
// an error.
28+
//
29+
// This doesn't happen any more because we ensure that `T: ReEmpty(U0)`
30+
// is an implicit bound for all type parameters.
31+
drop(r);
32+
});
33+
}
34+
35+
fn main() {}

0 commit comments

Comments
 (0)