/// 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,
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,
}
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
// 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);
.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();
).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
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!(
// 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 =
mir_def_id,
dummy_body_id,
param_env,
- &output_ty,
+ &normalized_output_ty,
));
debug!(
"equate_inputs_and_outputs: instantiated output_ty={:?}",
self,
Location::START,
"equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
- output_ty,
+ normalized_output_ty,
mir_output_ty,
terr
);
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;
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,
mir_def_id,
universal_regions,
&universal_region_relations,
+ &normalized_inputs_and_output,
);
},
);