renumber types in ty::Const
and relate them to mir::Constant
This commit is contained in:
parent
7b637b778d
commit
e5dc4ba280
4 changed files with 61 additions and 1 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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={:?})",
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
Loading…
Add table
Reference in a new issue