renumber types in ty::Const and relate them to mir::Constant

This commit is contained in:
Niko Matsakis 2017-11-22 17:29:55 -05:00
parent 7b637b778d
commit e5dc4ba280
4 changed files with 61 additions and 1 deletions

View file

@ -43,12 +43,17 @@ pub(in borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
def_id: DefId,
mir: &mut Mir<'tcx>,
) -> UniversalRegions<'tcx> {
debug!("replace_regions_in_mir(def_id={:?})", def_id);
// Compute named region information.
let universal_regions = universal_regions::universal_regions(infcx, def_id);
// Replace all regions with fresh inference variables.
renumber::renumber_mir(infcx, &universal_regions, mir);
let source = MirSource::item(def_id);
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, mir, |_, _| Ok(()));
universal_regions
}

View file

@ -138,6 +138,11 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
debug!("visit_region: region={:?}", region);
}
fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, location: Location) {
let ty_context = TyContext::Location(location);
*constant = self.renumber_regions(ty_context, &*constant);
}
fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: Location) {
debug!(
"visit_closure_substs(substs={:?}, location={:?})",

View file

@ -106,7 +106,10 @@ impl<'cx, 'tcx> SubtypeConstraintGenerator<'cx, 'tcx> {
if let ty::ReVar(vid) = r {
*vid
} else {
self.universal_regions.indices[&r]
*self.universal_regions
.indices
.get(&r)
.unwrap_or_else(|| bug!("to_region_vid: bad region {:?}", r))
}
}
}

View file

@ -110,6 +110,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
self.sanitize_constant(constant, location);
self.sanitize_type(constant, constant.ty);
}
@ -159,6 +160,52 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
}
}
/// Checks that the constant's `ty` field matches up with what
/// would be expected from its literal.
fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
debug!(
"sanitize_constant(constant={:?}, location={:?})",
constant,
location
);
let expected_ty = match constant.literal {
Literal::Value { value } => value.ty,
Literal::Promoted { .. } => {
// FIXME -- promoted MIR return types reference
// various "free regions" (e.g., scopes and things)
// that they ought not to do. We have to figure out
// how best to handle that -- probably we want treat
// promoted MIR much like closures, renumbering all
// their free regions and propagating constraints
// upwards. We have the same acyclic guarantees, so
// that should be possible. But for now, ignore them.
//
// let promoted_mir = &self.mir.promoted[index];
// promoted_mir.return_ty()
return;
}
};
debug!("sanitize_constant: expected_ty={:?}", expected_ty);
if let Err(terr) = self.cx
.eq_types(expected_ty, constant.ty, location.at_self())
{
span_mirbug!(
self,
constant,
"constant {:?} should have type {:?} but has {:?} ({:?})",
constant,
expected_ty,
constant.ty,
terr,
);
}
}
/// Checks that the types internal to the `place` match up with
/// what would be expected.
fn sanitize_place(
&mut self,
place: &Place<'tcx>,