free RegionBoundPairs earlier and avoid normalizing twice
Normalization results are memoized, so this may not be worth it, but it seems easy enough to do.
This commit is contained in:
parent
490928f709
commit
68c2a39a72
3 changed files with 41 additions and 24 deletions
|
|
@ -53,6 +53,18 @@ crate struct UniversalRegionRelations<'tcx> {
|
|||
/// our special inference variable there, we would mess that up.
|
||||
type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
|
||||
|
||||
/// As part of computing the free region relations, we also have to
|
||||
/// normalize the input-output types, which we then need later. So we
|
||||
/// return those. This vector consists of first the input types and
|
||||
/// then the output type as the last element.
|
||||
type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
|
||||
|
||||
crate struct CreateResult<'tcx> {
|
||||
crate universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
|
||||
crate region_bound_pairs: RegionBoundPairs<'tcx>,
|
||||
crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
|
||||
}
|
||||
|
||||
crate fn create(
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir_def_id: DefId,
|
||||
|
|
@ -62,7 +74,7 @@ crate fn create(
|
|||
universal_regions: &Rc<UniversalRegions<'tcx>>,
|
||||
constraints: &mut MirTypeckRegionConstraints<'tcx>,
|
||||
all_facts: &mut Option<AllFacts>,
|
||||
) -> (Rc<UniversalRegionRelations<'tcx>>, RegionBoundPairs<'tcx>) {
|
||||
) -> CreateResult<'tcx> {
|
||||
let mir_node_id = infcx.tcx.hir.as_local_node_id(mir_def_id).unwrap();
|
||||
UniversalRegionRelationsBuilder {
|
||||
infcx,
|
||||
|
|
@ -215,7 +227,7 @@ struct UniversalRegionRelationsBuilder<'this, 'gcx: 'tcx, 'tcx: 'this> {
|
|||
}
|
||||
|
||||
impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
|
||||
crate fn create(mut self) -> (Rc<UniversalRegionRelations<'tcx>>, RegionBoundPairs<'tcx>) {
|
||||
crate fn create(mut self) -> CreateResult<'tcx> {
|
||||
let unnormalized_input_output_tys = self
|
||||
.universal_regions
|
||||
.unnormalized_input_tys
|
||||
|
|
@ -231,6 +243,8 @@ impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
|
|||
// the `region_bound_pairs` and so forth.
|
||||
// - After this is done, we'll process the constraints, once
|
||||
// the `relations` is built.
|
||||
let mut normalized_inputs_and_output =
|
||||
Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
|
||||
let constraint_sets: Vec<_> = unnormalized_input_output_tys
|
||||
.flat_map(|ty| {
|
||||
debug!("build: input_or_output={:?}", ty);
|
||||
|
|
@ -240,6 +254,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
|
|||
.fully_perform(self.infcx)
|
||||
.unwrap_or_else(|_| bug!("failed to normalize {:?}", ty));
|
||||
self.add_implied_bounds(ty);
|
||||
normalized_inputs_and_output.push(ty);
|
||||
constraints
|
||||
})
|
||||
.collect();
|
||||
|
|
@ -280,7 +295,11 @@ impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
|
|||
).convert_all(&data);
|
||||
}
|
||||
|
||||
(Rc::new(self.relations), self.region_bound_pairs)
|
||||
CreateResult {
|
||||
universal_region_relations: Rc::new(self.relations),
|
||||
region_bound_pairs: self.region_bound_pairs,
|
||||
normalized_inputs_and_output,
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the type of a single local, which should represent
|
||||
|
|
|
|||
|
|
@ -39,22 +39,24 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
mir_def_id: DefId,
|
||||
universal_regions: &UniversalRegions<'tcx>,
|
||||
universal_region_relations: &UniversalRegionRelations<'tcx>,
|
||||
normalized_inputs_and_output: &[Ty<'tcx>],
|
||||
) {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
let &UniversalRegions {
|
||||
unnormalized_output_ty,
|
||||
unnormalized_input_tys,
|
||||
..
|
||||
} = universal_regions;
|
||||
let (&normalized_output_ty, normalized_input_tys) =
|
||||
normalized_inputs_and_output.split_last().unwrap();
|
||||
let infcx = self.infcx;
|
||||
|
||||
// Equate expected input tys with those in the MIR.
|
||||
let argument_locals = (1..).map(Local::new);
|
||||
for (&unnormalized_input_ty, local) in unnormalized_input_tys.iter().zip(argument_locals) {
|
||||
let input_ty = self.normalize(unnormalized_input_ty, Locations::All);
|
||||
for (&normalized_input_ty, local) in normalized_input_tys.iter().zip(argument_locals) {
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: normalized_input_ty = {:?}",
|
||||
normalized_input_ty
|
||||
);
|
||||
|
||||
let mir_input_ty = mir.local_decls[local].ty;
|
||||
self.equate_normalized_input_or_output(input_ty, mir_input_ty);
|
||||
self.equate_normalized_input_or_output(normalized_input_ty, mir_input_ty);
|
||||
}
|
||||
|
||||
assert!(
|
||||
|
|
@ -68,15 +70,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
|
||||
// Return types are a bit more complex. They may contain existential `impl Trait`
|
||||
// types.
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: unnormalized_output_ty={:?}",
|
||||
unnormalized_output_ty
|
||||
);
|
||||
let output_ty = self.normalize(unnormalized_output_ty, Locations::All);
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: normalized output_ty={:?}",
|
||||
output_ty
|
||||
);
|
||||
let param_env = self.param_env;
|
||||
let mir_output_ty = mir.local_decls[RETURN_PLACE].ty;
|
||||
let anon_type_map =
|
||||
|
|
@ -92,7 +85,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
mir_def_id,
|
||||
dummy_body_id,
|
||||
param_env,
|
||||
&output_ty,
|
||||
&normalized_output_ty,
|
||||
));
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: instantiated output_ty={:?}",
|
||||
|
|
@ -146,7 +139,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
self,
|
||||
Location::START,
|
||||
"equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
|
||||
output_ty,
|
||||
normalized_output_ty,
|
||||
mir_output_ty,
|
||||
terr
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
|
|||
use borrow_check::nll::facts::AllFacts;
|
||||
use borrow_check::nll::region_infer::values::{RegionValueElements, LivenessValues};
|
||||
use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
|
||||
use borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
|
||||
use borrow_check::nll::type_check::free_region_relations::{CreateResult, UniversalRegionRelations};
|
||||
use borrow_check::nll::universal_regions::UniversalRegions;
|
||||
use borrow_check::nll::LocalWithRegion;
|
||||
use borrow_check::nll::ToRegionVid;
|
||||
|
|
@ -132,7 +132,11 @@ pub(crate) fn type_check<'gcx, 'tcx>(
|
|||
type_tests: Vec::default(),
|
||||
};
|
||||
|
||||
let (universal_region_relations, region_bound_pairs) = free_region_relations::create(
|
||||
let CreateResult {
|
||||
universal_region_relations,
|
||||
region_bound_pairs,
|
||||
normalized_inputs_and_output,
|
||||
} = free_region_relations::create(
|
||||
infcx,
|
||||
mir_def_id,
|
||||
param_env,
|
||||
|
|
@ -168,6 +172,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
|
|||
mir_def_id,
|
||||
universal_regions,
|
||||
&universal_region_relations,
|
||||
&normalized_inputs_and_output,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue