Skip to content

Commit b2e0215

Browse files
committed
apply process_registered_region_obligations at the end of regionck
We used to apply it repeatedly as we went, relying on the current value of the `region_bound_pairs_accum` vector. But now we save those values into a map, so we can just process all the registered region obligations at the end.
1 parent 9e305a8 commit b2e0215

File tree

9 files changed

+49
-61
lines changed

9 files changed

+49
-61
lines changed

src/librustc/infer/outlives/env.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
9797
}
9898

9999
/// Borrows current value of the `region_bound_pairs`.
100-
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
101-
&self.region_bound_pairs_accum
100+
pub fn region_bound_pairs_map(&self) -> &FxHashMap<ast::NodeId, RegionBoundPairs<'tcx>> {
101+
&self.region_bound_pairs_map
102102
}
103103

104104
/// Returns ownership of the `free_region_map`.

src/librustc/infer/outlives/obligations.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@
7070
//! imply that `'b: 'a`.
7171
7272
use hir::def_id::DefId;
73-
use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
7473
use infer::outlives::env::RegionBoundPairs;
74+
use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
75+
use rustc_data_structures::fx::FxHashMap;
7576
use syntax::ast;
7677
use traits::{self, ObligationCause};
7778
use ty::outlives::Component;
@@ -159,10 +160,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
159160
/// processed.
160161
pub fn process_registered_region_obligations(
161162
&self,
162-
region_bound_pairs: &RegionBoundPairs<'tcx>,
163+
region_bound_pairs_map: &FxHashMap<ast::NodeId, RegionBoundPairs<'tcx>>,
163164
implicit_region_bound: Option<ty::Region<'tcx>>,
164165
param_env: ty::ParamEnv<'tcx>,
165-
body_id: ast::NodeId,
166166
) {
167167
assert!(
168168
!self.in_snapshot.get(),
@@ -171,36 +171,39 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
171171

172172
debug!("process_registered_region_obligations()");
173173

174-
// pull out the region obligations with the given `body_id` (leaving the rest)
175-
let mut my_region_obligations = Vec::with_capacity(self.region_obligations.borrow().len());
176-
{
177-
let mut r_o = self.region_obligations.borrow_mut();
178-
my_region_obligations.extend(r_o.drain_filter(|(ro_body_id, _)| {
179-
*ro_body_id == body_id
180-
}).map(|(_, obligation)| obligation));
181-
}
174+
let my_region_obligations = self.take_registered_region_obligations();
182175

183-
let outlives = &mut TypeOutlives::new(
184-
self,
185-
self.tcx,
186-
region_bound_pairs,
187-
implicit_region_bound,
188-
param_env,
189-
);
190-
191-
for RegionObligation {
192-
sup_type,
193-
sub_region,
194-
origin,
195-
} in my_region_obligations
176+
for (
177+
body_id,
178+
RegionObligation {
179+
sup_type,
180+
sub_region,
181+
origin,
182+
},
183+
) in my_region_obligations
196184
{
197185
debug!(
198186
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
199187
sup_type, sub_region, origin
200188
);
201189

202190
let sup_type = self.resolve_type_vars_if_possible(&sup_type);
203-
outlives.type_must_outlive(origin, sup_type, sub_region);
191+
192+
if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
193+
let outlives = &mut TypeOutlives::new(
194+
self,
195+
self.tcx,
196+
&region_bound_pairs,
197+
implicit_region_bound,
198+
param_env,
199+
);
200+
outlives.type_must_outlive(origin, sup_type, sub_region);
201+
} else {
202+
self.tcx.sess.delay_span_bug(
203+
origin.span(),
204+
&format!("no region-bound-pairs for {:?}", body_id),
205+
)
206+
}
204207
}
205208
}
206209

src/librustc/traits/auto_trait.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ use super::*;
1616
use std::collections::hash_map::Entry;
1717
use std::collections::VecDeque;
1818

19-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
20-
2119
use infer::region_constraints::{Constraint, RegionConstraintData};
2220
use infer::InferCtxt;
21+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2322

2423
use ty::fold::TypeFolder;
2524
use ty::{Region, RegionVid};
@@ -231,16 +230,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
231230
})
232231
.collect();
233232

234-
let body_ids: FxHashSet<_> = infcx
233+
let body_id_map: FxHashMap<_, _> = infcx
235234
.region_obligations
236235
.borrow()
237236
.iter()
238-
.map(|&(id, _)| id)
237+
.map(|&(id, _)| (id, vec![]))
239238
.collect();
240239

241-
for id in body_ids {
242-
infcx.process_registered_region_obligations(&vec![], None, full_env.clone(), id);
243-
}
240+
infcx.process_registered_region_obligations(&body_id_map, None, full_env.clone());
244241

245242
let region_data = infcx
246243
.borrow_region_constraints()

src/librustc_typeck/check/regionck.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ use middle::mem_categorization as mc;
8888
use middle::mem_categorization::Categorization;
8989
use middle::region;
9090
use rustc::hir::def_id::DefId;
91-
use rustc::infer::{self, UnlessNll};
91+
use rustc::infer::{self, RegionObligation, UnlessNll};
9292
use rustc::infer::outlives::env::OutlivesEnvironment;
9393
use rustc::ty::adjustment;
9494
use rustc::ty::subst::Substs;
@@ -390,16 +390,15 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
390390
// which, when processed, might generate new region
391391
// obligations. So make sure we process those.
392392
self.select_all_obligations_or_error();
393+
}
393394

395+
fn resolve_regions_and_report_errors(&self, unless_nll: UnlessNll) {
394396
self.infcx.process_registered_region_obligations(
395-
self.outlives_environment.region_bound_pairs(),
397+
self.outlives_environment.region_bound_pairs_map(),
396398
self.implicit_region_bound,
397399
self.param_env,
398-
self.body_id,
399400
);
400-
}
401401

402-
fn resolve_regions_and_report_errors(&self, unless_nll: UnlessNll) {
403402
self.fcx.resolve_regions_and_report_errors(
404403
self.subject_def_id,
405404
&self.region_scope_tree,
@@ -1042,13 +1041,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
10421041
ty: Ty<'tcx>,
10431042
region: ty::Region<'tcx>,
10441043
) {
1045-
self.infcx.type_must_outlive(
1046-
self.outlives_environment.region_bound_pairs(),
1047-
self.implicit_region_bound,
1048-
self.param_env,
1049-
origin,
1050-
ty,
1051-
region,
1044+
self.infcx.register_region_obligation(
1045+
self.body_id,
1046+
RegionObligation {
1047+
sub_region: region,
1048+
sup_type: ty,
1049+
origin,
1050+
},
10521051
);
10531052
}
10541053

src/test/ui/issues/issue-16922.nll.stderr

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/test/ui/issues/issue-16922.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0621]: explicit lifetime required in the type of `value`
44
LL | fn foo<T: Any>(value: &T) -> Box<Any> {
55
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
66
LL | Box::new(value) as Box<Any>
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
7+
| ^^^^^^^^^^^^^^^ lifetime `'static` required
88

99
error: aborting due to previous error
1010

src/test/ui/object-lifetime/object-lifetime-default-elision.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
99
|
1010
LL | fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
1111
| ^^
12-
note: ...so that the type `(dyn SomeTrait + 'a)` is not borrowed for too long
12+
note: ...so that reference does not outlive borrowed content
1313
--> $DIR/object-lifetime-default-elision.rs:81:5
1414
|
1515
LL | ss

src/test/ui/regions/region-object-lifetime-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
99
|
1010
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
1111
| ^^
12-
note: ...so that the type `(dyn Foo + 'a)` is not borrowed for too long
12+
note: ...so that reference does not outlive borrowed content
1313
--> $DIR/region-object-lifetime-2.rs:20:5
1414
|
1515
LL | x.borrowed() //~ ERROR cannot infer

src/test/ui/regions/regions-trait-object-subtyping.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
2626
|
2727
LL | fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
2828
| ^^
29-
note: ...so that the type `(dyn Dummy + 'a)` is not borrowed for too long
29+
note: ...so that reference does not outlive borrowed content
3030
--> $DIR/regions-trait-object-subtyping.rs:25:5
3131
|
3232
LL | x //~ ERROR lifetime bound not satisfied

0 commit comments

Comments
 (0)