Skip to content

Commit b02f298

Browse files
committed
Remove regionck member constraint handling and leave it to mir borrowck
1 parent 38b9e6a commit b02f298

20 files changed

+77
-482
lines changed

compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

+1-162
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use crate::infer::region_constraints::Constraint;
44
use crate::infer::region_constraints::GenericKind;
5-
use crate::infer::region_constraints::MemberConstraint;
65
use crate::infer::region_constraints::RegionConstraintData;
76
use crate::infer::region_constraints::VarInfos;
87
use crate::infer::region_constraints::VerifyBound;
@@ -150,12 +149,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
150149

151150
let graph = self.construct_graph();
152151
self.expand_givens(&graph);
153-
loop {
154-
self.expansion(&mut var_data);
155-
if !self.enforce_member_constraints(&graph, &mut var_data) {
156-
break;
157-
}
158-
}
152+
self.expansion(&mut var_data);
159153
self.collect_errors(&mut var_data, errors);
160154
self.collect_var_errors(&var_data, &graph, errors);
161155
var_data
@@ -233,133 +227,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
233227
}
234228
}
235229

236-
/// Enforce all member constraints and return true if anything
237-
/// changed. See `enforce_member_constraint` for more details.
238-
fn enforce_member_constraints(
239-
&self,
240-
graph: &RegionGraph<'tcx>,
241-
var_values: &mut LexicalRegionResolutions<'tcx>,
242-
) -> bool {
243-
// Note: we don't use the `any` combinator because we don't
244-
// want to stop at the first constraint that makes a change.
245-
let mut any_changed = false;
246-
for member_constraint in &self.data.member_constraints {
247-
any_changed |= self.enforce_member_constraint(graph, member_constraint, var_values);
248-
}
249-
any_changed
250-
}
251-
252-
/// Enforce a constraint like
253-
///
254-
/// ```
255-
/// 'r member of ['c...]
256-
/// ```
257-
///
258-
/// We look for all choice regions from the list `'c...` that:
259-
///
260-
/// (a) are greater than the current value of `'r` (which is a lower bound)
261-
///
262-
/// and
263-
///
264-
/// (b) are compatible with the upper bounds of `'r` that we can
265-
/// find by traversing the graph.
266-
///
267-
/// From that list, we look for a *minimal* option `'c_min`. If we
268-
/// find one, then we can enforce that `'r: 'c_min`.
269-
#[instrument(level = "debug", skip(self, graph, member_constraint, var_values))]
270-
fn enforce_member_constraint(
271-
&self,
272-
graph: &RegionGraph<'tcx>,
273-
member_constraint: &MemberConstraint<'tcx>,
274-
var_values: &mut LexicalRegionResolutions<'tcx>,
275-
) -> bool {
276-
debug!("member_constraint={:#?}", member_constraint);
277-
278-
// The constraint is some inference variable (`vid`) which
279-
// must be equal to one of the options.
280-
let member_vid = match member_constraint.member_region {
281-
ty::ReVar(vid) => *vid,
282-
_ => return false,
283-
};
284-
285-
// The current value of `vid` is a lower bound LB -- i.e., we
286-
// know that `LB <= vid` must be true.
287-
let member_lower_bound: ty::Region<'tcx> = match var_values.value(member_vid) {
288-
VarValue::ErrorValue => return false,
289-
VarValue::Value(r) => r,
290-
};
291-
292-
// Find all the "upper bounds" -- that is, each region `b` such that
293-
// `r0 <= b` must hold.
294-
let (member_upper_bounds, ..) =
295-
self.collect_bounding_regions(graph, member_vid, OUTGOING, None);
296-
297-
// Get an iterator over the *available choice* -- that is,
298-
// each choice region `c` where `lb <= c` and `c <= ub` for all the
299-
// upper bounds `ub`.
300-
debug!("upper_bounds={:#?}", member_upper_bounds);
301-
let mut options = member_constraint
302-
.choice_regions
303-
.iter()
304-
// If any of the regions are inference vars, resolve them, as far
305-
// as possible.
306-
.filter_map(|option| match option {
307-
ty::ReVar(vid) => match var_values.value(*vid) {
308-
VarValue::ErrorValue => None,
309-
VarValue::Value(r) => Some(r),
310-
},
311-
r => Some(r),
312-
})
313-
.filter(|option| {
314-
self.sub_concrete_regions(member_lower_bound, option)
315-
&& member_upper_bounds
316-
.iter()
317-
.all(|upper_bound| self.sub_concrete_regions(option, upper_bound.region))
318-
});
319-
320-
// If there is more than one option, we only make a choice if
321-
// there is a single *least* choice -- i.e., some available
322-
// region that is `<=` all the others.
323-
let mut least_choice: ty::Region<'tcx> = match options.next() {
324-
Some(&r) => r,
325-
None => return false,
326-
};
327-
debug!(?least_choice);
328-
for &option in options {
329-
debug!(?option);
330-
if !self.sub_concrete_regions(least_choice, option) {
331-
if self.sub_concrete_regions(option, least_choice) {
332-
debug!("new least choice");
333-
least_choice = option;
334-
} else {
335-
debug!("no least choice");
336-
return false;
337-
}
338-
}
339-
}
340-
341-
// (#72087) Different `ty::Regions` can be known to be equal, for
342-
// example, we know that `'a` and `'static` are equal in a function
343-
// with a parameter of type `&'static &'a ()`.
344-
//
345-
// When we have two equal regions like this `expansion` will use
346-
// `lub_concrete_regions` to pick a canonical representative. The same
347-
// choice is needed here so that we don't end up in a cycle of
348-
// `expansion` changing the region one way and the code here changing
349-
// it back.
350-
let lub = self.lub_concrete_regions(least_choice, member_lower_bound);
351-
debug!(
352-
"enforce_member_constraint: final least choice = {:?}\nlub = {:?}",
353-
least_choice, lub
354-
);
355-
if lub != member_lower_bound {
356-
*var_values.value_mut(member_vid) = VarValue::Value(least_choice);
357-
true
358-
} else {
359-
false
360-
}
361-
}
362-
363230
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
364231
let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
365232
let mut changes = Vec::new();
@@ -632,34 +499,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
632499
}
633500
}
634501

635-
// Check that all member constraints are satisfied.
636-
for member_constraint in &self.data.member_constraints {
637-
let member_region = var_data.normalize(self.tcx(), member_constraint.member_region);
638-
let choice_regions = member_constraint
639-
.choice_regions
640-
.iter()
641-
.map(|&choice_region| var_data.normalize(self.tcx(), choice_region));
642-
let fr = &self.region_rels.free_regions;
643-
let sub = |a, b| {
644-
fr.is_free_or_static(a)
645-
&& fr.is_free_or_static(b)
646-
&& fr.sub_free_regions(self.tcx(), a, b)
647-
};
648-
if !choice_regions.clone().any(|choice_region| {
649-
// This is really checking if the regions are equal. After member constraint
650-
// resolution, one region must be equal, or a lifetime has been leaked into
651-
// the hidden type, but does not appear in the corresponding impl trait.
652-
sub(member_region, choice_region) && sub(choice_region, member_region)
653-
}) {
654-
let span = self.tcx().def_span(member_constraint.opaque_type_def_id);
655-
errors.push(RegionResolutionError::MemberConstraintFailure {
656-
span,
657-
hidden_ty: member_constraint.hidden_ty,
658-
member_region,
659-
});
660-
}
661-
}
662-
663502
for verify in &self.data.verifys {
664503
debug!("collect_errors: verify={:?}", verify);
665504
let sub = var_data.normalize(self.tcx(), verify.region);

src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> +
1515
// Only `'a` permitted in return type, not `'b`.
1616
async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
1717
//~^ ERROR captures lifetime that does not appear in bounds
18-
//~| ERROR captures lifetime that does not appear in bounds
1918
(a, b)
2019
}
2120

src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr

+2-15
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,14 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
1414
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
1515
| -- ^^^^^^^^^^^^^^
1616
| |
17-
| hidden type `(&u8, &u8)` captures the lifetime `'b` as defined here
17+
| hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here
1818
|
1919
help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
2020
|
2121
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
2222
| ++++
2323

24-
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
25-
--> $DIR/ret-impl-trait-one.rs:16:65
26-
|
27-
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
28-
| -- ^^^^^^^^^^^^^^
29-
| |
30-
| hidden type `(&u8, &u8)` captures the lifetime `'b` as defined here
31-
|
32-
help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
33-
|
34-
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
35-
| ++++
36-
37-
error: aborting due to 3 previous errors
24+
error: aborting due to 2 previous errors
3825

3926
Some errors have detailed explanations: E0623, E0700.
4027
For more information about an error, try `rustc --explain E0623`.

src/test/ui/impl-trait/hidden-lifetimes.nll.stderr

-29
This file was deleted.

src/test/ui/impl-trait/hidden-lifetimes.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
44
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
55
| -- ^^^^^^^^^^^^^^
66
| |
7-
| hidden type `&mut &'b T` captures the lifetime `'b` as defined here
7+
| hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here
88
|
99
help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
1010
|

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr

-16
This file was deleted.

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
22
--> $DIR/ordinary-bounds-unrelated.rs:16:74
33
|
44
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
5-
| ^^^^^^^^^^^^^^^^^^
5+
| -- ^^^^^^^^^^^^^^^^^^
6+
| |
7+
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
68
|
7-
note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body
8-
--> $DIR/ordinary-bounds-unrelated.rs:16:74
9+
help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
910
|
10-
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
11-
| ^^^^^^^^^^^^^^^^^^
11+
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b
12+
| ++++
1213

1314
error: aborting due to previous error
1415

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr

-16
This file was deleted.

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
22
--> $DIR/ordinary-bounds-unsuited.rs:18:62
33
|
44
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
5-
| ^^^^^^^^^^^^^^^^^^
5+
| -- ^^^^^^^^^^^^^^^^^^
6+
| |
7+
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
68
|
7-
note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body
8-
--> $DIR/ordinary-bounds-unsuited.rs:18:62
9+
help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
910
|
10-
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
11-
| ^^^^^^^^^^^^^^^^^^
11+
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + 'b
12+
| ++++
1213

1314
error: aborting due to previous error
1415

src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,28 @@ LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
5959
| let's call the lifetime of this reference `'1`
6060

6161
error: lifetime may not live long enough
62-
--> $DIR/must_outlive_least_region_or_bound.rs:30:69
62+
--> $DIR/must_outlive_least_region_or_bound.rs:29:69
6363
|
6464
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
6565
| -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static`
6666
|
6767
= help: consider replacing `'a` with `'static`
6868

6969
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
70-
--> $DIR/must_outlive_least_region_or_bound.rs:34:61
70+
--> $DIR/must_outlive_least_region_or_bound.rs:33:61
7171
|
7272
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
7373
| -- ^^^^^^^^^^^^^^^^
7474
| |
75-
| hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:37:5: 37:31]` captures the lifetime `'b` as defined here
75+
| hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here
7676
|
7777
help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
7878
|
7979
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) + 'b {
8080
| ++++
8181

8282
error[E0310]: the parameter type `T` may not live long enough
83-
--> $DIR/must_outlive_least_region_or_bound.rs:40:51
83+
--> $DIR/must_outlive_least_region_or_bound.rs:38:51
8484
|
8585
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
8686
| ^^^^^^^^^^^^^^^^^^^^

src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs

-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
2222
fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
2323

2424
fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) } //~ ERROR E0759
25-
//~^ ERROR: captures lifetime that does not appear in bounds
2625

2726
trait LifetimeTrait<'a> {}
2827
impl<'a> LifetimeTrait<'a> for &'a i32 {}
@@ -33,7 +32,6 @@ fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } //~ ERRO
3332
// only 'a was expected.
3433
fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
3534
//~^ ERROR: captures lifetime that does not appear in bounds
36-
//~| ERROR: captures lifetime that does not appear in bounds
3735
move |_| println!("{}", y)
3836
}
3937

0 commit comments

Comments
 (0)