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`.
|
/// Borrows current value of the `region_bound_pairs`.
|
||||||
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
|
pub fn region_bound_pairs_map(&self) -> &FxHashMap<ast::NodeId, RegionBoundPairs<'tcx>> {
|
||||||
&self.region_bound_pairs_accum
|
&self.region_bound_pairs_map
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns ownership of the `free_region_map`.
|
/// Returns ownership of the `free_region_map`.
|
||||||
|
|
|
@ -70,8 +70,9 @@
|
||||||
//! imply that `'b: 'a`.
|
//! imply that `'b: 'a`.
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
|
|
||||||
use infer::outlives::env::RegionBoundPairs;
|
use infer::outlives::env::RegionBoundPairs;
|
||||||
|
use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use traits::{self, ObligationCause};
|
use traits::{self, ObligationCause};
|
||||||
use ty::outlives::Component;
|
use ty::outlives::Component;
|
||||||
|
@ -159,10 +160,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||||
/// processed.
|
/// processed.
|
||||||
pub fn process_registered_region_obligations(
|
pub fn process_registered_region_obligations(
|
||||||
&self,
|
&self,
|
||||||
region_bound_pairs: &RegionBoundPairs<'tcx>,
|
region_bound_pairs_map: &FxHashMap<ast::NodeId, RegionBoundPairs<'tcx>>,
|
||||||
implicit_region_bound: Option<ty::Region<'tcx>>,
|
implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body_id: ast::NodeId,
|
|
||||||
) {
|
) {
|
||||||
assert!(
|
assert!(
|
||||||
!self.in_snapshot.get(),
|
!self.in_snapshot.get(),
|
||||||
|
@ -171,28 +171,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||||
|
|
||||||
debug!("process_registered_region_obligations()");
|
debug!("process_registered_region_obligations()");
|
||||||
|
|
||||||
// pull out the region obligations with the given `body_id` (leaving the rest)
|
let my_region_obligations = self.take_registered_region_obligations();
|
||||||
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 outlives = &mut TypeOutlives::new(
|
for (
|
||||||
self,
|
body_id,
|
||||||
self.tcx,
|
RegionObligation {
|
||||||
region_bound_pairs,
|
sup_type,
|
||||||
implicit_region_bound,
|
sub_region,
|
||||||
param_env,
|
origin,
|
||||||
);
|
},
|
||||||
|
) in my_region_obligations
|
||||||
for RegionObligation {
|
|
||||||
sup_type,
|
|
||||||
sub_region,
|
|
||||||
origin,
|
|
||||||
} in my_region_obligations
|
|
||||||
{
|
{
|
||||||
debug!(
|
debug!(
|
||||||
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
|
"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);
|
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::hash_map::Entry;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|
||||||
|
|
||||||
use infer::region_constraints::{Constraint, RegionConstraintData};
|
use infer::region_constraints::{Constraint, RegionConstraintData};
|
||||||
use infer::InferCtxt;
|
use infer::InferCtxt;
|
||||||
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use ty::fold::TypeFolder;
|
use ty::fold::TypeFolder;
|
||||||
use ty::{Region, RegionVid};
|
use ty::{Region, RegionVid};
|
||||||
|
@ -231,16 +230,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let body_ids: FxHashSet<_> = infcx
|
let body_id_map: FxHashMap<_, _> = infcx
|
||||||
.region_obligations
|
.region_obligations
|
||||||
.borrow()
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(id, _)| id)
|
.map(|&(id, _)| (id, vec![]))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for id in body_ids {
|
infcx.process_registered_region_obligations(&body_id_map, None, full_env.clone());
|
||||||
infcx.process_registered_region_obligations(&vec![], None, full_env.clone(), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
let region_data = infcx
|
let region_data = infcx
|
||||||
.borrow_region_constraints()
|
.borrow_region_constraints()
|
||||||
|
|
|
@ -88,7 +88,7 @@ use middle::mem_categorization as mc;
|
||||||
use middle::mem_categorization::Categorization;
|
use middle::mem_categorization::Categorization;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use rustc::hir::def_id::DefId;
|
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::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc::ty::adjustment;
|
use rustc::ty::adjustment;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
|
@ -390,16 +390,15 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||||
// which, when processed, might generate new region
|
// which, when processed, might generate new region
|
||||||
// obligations. So make sure we process those.
|
// obligations. So make sure we process those.
|
||||||
self.select_all_obligations_or_error();
|
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) {
|
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.fcx.resolve_regions_and_report_errors(
|
||||||
self.subject_def_id,
|
self.subject_def_id,
|
||||||
&self.region_scope_tree,
|
&self.region_scope_tree,
|
||||||
|
@ -1042,13 +1041,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
) {
|
) {
|
||||||
self.infcx.type_must_outlive(
|
self.infcx.register_region_obligation(
|
||||||
self.outlives_environment.region_bound_pairs(),
|
self.body_id,
|
||||||
self.implicit_region_bound,
|
RegionObligation {
|
||||||
self.param_env,
|
sub_region: region,
|
||||||
origin,
|
sup_type: ty,
|
||||||
ty,
|
origin,
|
||||||
region,
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
LL | fn foo<T: Any>(value: &T) -> Box<Any> {
|
||||||
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
|
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
|
||||||
LL | Box::new(value) as Box<Any>
|
LL | Box::new(value) as Box<Any>
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
|
| ^^^^^^^^^^^^^^^ lifetime `'static` required
|
||||||
|
|
||||||
error: aborting due to previous error
|
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 {
|
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
|
--> $DIR/object-lifetime-default-elision.rs:81:5
|
||||||
|
|
|
|
||||||
LL | ss
|
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 () {
|
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
|
--> $DIR/region-object-lifetime-2.rs:20:5
|
||||||
|
|
|
|
||||||
LL | x.borrowed() //~ ERROR cannot infer
|
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 {
|
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
|
--> $DIR/regions-trait-object-subtyping.rs:25:5
|
||||||
|
|
|
|
||||||
LL | x //~ ERROR lifetime bound not satisfied
|
LL | x //~ ERROR lifetime bound not satisfied
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue