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.
This commit is contained in:
parent
9e305a8a23
commit
b2e0215a1f
9 changed files with 52 additions and 64 deletions
|
@ -97,8 +97,8 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
|
|||
}
|
||||
|
||||
/// Borrows current value of the `region_bound_pairs`.
|
||||
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
|
||||
&self.region_bound_pairs_accum
|
||||
pub fn region_bound_pairs_map(&self) -> &FxHashMap<ast::NodeId, RegionBoundPairs<'tcx>> {
|
||||
&self.region_bound_pairs_map
|
||||
}
|
||||
|
||||
/// Returns ownership of the `free_region_map`.
|
||||
|
|
|
@ -70,8 +70,9 @@
|
|||
//! imply that `'b: 'a`.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
|
||||
use infer::outlives::env::RegionBoundPairs;
|
||||
use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use syntax::ast;
|
||||
use traits::{self, ObligationCause};
|
||||
use ty::outlives::Component;
|
||||
|
@ -159,10 +160,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// processed.
|
||||
pub fn process_registered_region_obligations(
|
||||
&self,
|
||||
region_bound_pairs: &RegionBoundPairs<'tcx>,
|
||||
region_bound_pairs_map: &FxHashMap<ast::NodeId, RegionBoundPairs<'tcx>>,
|
||||
implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body_id: ast::NodeId,
|
||||
) {
|
||||
assert!(
|
||||
!self.in_snapshot.get(),
|
||||
|
@ -171,28 +171,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
debug!("process_registered_region_obligations()");
|
||||
|
||||
// pull out the region obligations with the given `body_id` (leaving the rest)
|
||||
let mut my_region_obligations = Vec::with_capacity(self.region_obligations.borrow().len());
|
||||
{
|
||||
let mut r_o = self.region_obligations.borrow_mut();
|
||||
my_region_obligations.extend(r_o.drain_filter(|(ro_body_id, _)| {
|
||||
*ro_body_id == body_id
|
||||
}).map(|(_, obligation)| obligation));
|
||||
}
|
||||
let my_region_obligations = self.take_registered_region_obligations();
|
||||
|
||||
let outlives = &mut TypeOutlives::new(
|
||||
self,
|
||||
self.tcx,
|
||||
region_bound_pairs,
|
||||
implicit_region_bound,
|
||||
param_env,
|
||||
);
|
||||
|
||||
for RegionObligation {
|
||||
sup_type,
|
||||
sub_region,
|
||||
origin,
|
||||
} in my_region_obligations
|
||||
for (
|
||||
body_id,
|
||||
RegionObligation {
|
||||
sup_type,
|
||||
sub_region,
|
||||
origin,
|
||||
},
|
||||
) in my_region_obligations
|
||||
{
|
||||
debug!(
|
||||
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
|
||||
|
@ -200,7 +188,22 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
);
|
||||
|
||||
let sup_type = self.resolve_type_vars_if_possible(&sup_type);
|
||||
outlives.type_must_outlive(origin, sup_type, sub_region);
|
||||
|
||||
if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
|
||||
let outlives = &mut TypeOutlives::new(
|
||||
self,
|
||||
self.tcx,
|
||||
®ion_bound_pairs,
|
||||
implicit_region_bound,
|
||||
param_env,
|
||||
);
|
||||
outlives.type_must_outlive(origin, sup_type, sub_region);
|
||||
} else {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
origin.span(),
|
||||
&format!("no region-bound-pairs for {:?}", body_id),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,9 @@ use super::*;
|
|||
use std::collections::hash_map::Entry;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
|
||||
use infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use infer::InferCtxt;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
|
||||
use ty::fold::TypeFolder;
|
||||
use ty::{Region, RegionVid};
|
||||
|
@ -231,16 +230,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let body_ids: FxHashSet<_> = infcx
|
||||
let body_id_map: FxHashMap<_, _> = infcx
|
||||
.region_obligations
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|&(id, _)| id)
|
||||
.map(|&(id, _)| (id, vec![]))
|
||||
.collect();
|
||||
|
||||
for id in body_ids {
|
||||
infcx.process_registered_region_obligations(&vec![], None, full_env.clone(), id);
|
||||
}
|
||||
infcx.process_registered_region_obligations(&body_id_map, None, full_env.clone());
|
||||
|
||||
let region_data = infcx
|
||||
.borrow_region_constraints()
|
||||
|
|
|
@ -88,7 +88,7 @@ use middle::mem_categorization as mc;
|
|||
use middle::mem_categorization::Categorization;
|
||||
use middle::region;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::{self, UnlessNll};
|
||||
use rustc::infer::{self, RegionObligation, UnlessNll};
|
||||
use rustc::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc::ty::adjustment;
|
||||
use rustc::ty::subst::Substs;
|
||||
|
@ -390,16 +390,15 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
// which, when processed, might generate new region
|
||||
// obligations. So make sure we process those.
|
||||
self.select_all_obligations_or_error();
|
||||
|
||||
self.infcx.process_registered_region_obligations(
|
||||
self.outlives_environment.region_bound_pairs(),
|
||||
self.implicit_region_bound,
|
||||
self.param_env,
|
||||
self.body_id,
|
||||
);
|
||||
}
|
||||
|
||||
fn resolve_regions_and_report_errors(&self, unless_nll: UnlessNll) {
|
||||
self.infcx.process_registered_region_obligations(
|
||||
self.outlives_environment.region_bound_pairs_map(),
|
||||
self.implicit_region_bound,
|
||||
self.param_env,
|
||||
);
|
||||
|
||||
self.fcx.resolve_regions_and_report_errors(
|
||||
self.subject_def_id,
|
||||
&self.region_scope_tree,
|
||||
|
@ -1042,13 +1041,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
region: ty::Region<'tcx>,
|
||||
) {
|
||||
self.infcx.type_must_outlive(
|
||||
self.outlives_environment.region_bound_pairs(),
|
||||
self.implicit_region_bound,
|
||||
self.param_env,
|
||||
origin,
|
||||
ty,
|
||||
region,
|
||||
self.infcx.register_region_obligation(
|
||||
self.body_id,
|
||||
RegionObligation {
|
||||
sub_region: region,
|
||||
sup_type: ty,
|
||||
origin,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
error[E0621]: explicit lifetime required in the type of `value`
|
||||
--> $DIR/issue-16922.rs:14:5
|
||||
|
|
||||
LL | fn foo<T: Any>(value: &T) -> Box<Any> {
|
||||
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
|
||||
LL | Box::new(value) as Box<Any>
|
||||
| ^^^^^^^^^^^^^^^ lifetime `'static` required
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0621`.
|
|
@ -4,7 +4,7 @@ error[E0621]: explicit lifetime required in the type of `value`
|
|||
LL | fn foo<T: Any>(value: &T) -> Box<Any> {
|
||||
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
|
||||
LL | Box::new(value) as Box<Any>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
|
||||
| ^^^^^^^^^^^^^^^ lifetime `'static` required
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
|
|||
|
|
||||
LL | fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
|
||||
| ^^
|
||||
note: ...so that the type `(dyn SomeTrait + 'a)` is not borrowed for too long
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/object-lifetime-default-elision.rs:81:5
|
||||
|
|
||||
LL | ss
|
||||
|
|
|
@ -9,7 +9,7 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
|
|||
|
|
||||
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
|
||||
| ^^
|
||||
note: ...so that the type `(dyn Foo + 'a)` is not borrowed for too long
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/region-object-lifetime-2.rs:20:5
|
||||
|
|
||||
LL | x.borrowed() //~ ERROR cannot infer
|
||||
|
|
|
@ -26,7 +26,7 @@ note: first, the lifetime cannot outlive the lifetime 'a as defined on the funct
|
|||
|
|
||||
LL | fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
|
||||
| ^^
|
||||
note: ...so that the type `(dyn Dummy + 'a)` is not borrowed for too long
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/regions-trait-object-subtyping.rs:25:5
|
||||
|
|
||||
LL | x //~ ERROR lifetime bound not satisfied
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue