From e5dc4ba2808ac81d7b3a1abab303e6d9eda5d9d6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 22 Nov 2017 17:29:55 -0500 Subject: [PATCH] renumber types in `ty::Const` and relate them to `mir::Constant` --- src/librustc_mir/borrow_check/nll/mod.rs | 5 ++ src/librustc_mir/borrow_check/nll/renumber.rs | 5 ++ .../nll/subtype_constraint_generation.rs | 5 +- src/librustc_mir/transform/type_check.rs | 47 +++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 804f5e26875..6d9e24bbb87 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -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 } diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 371419da024..bb32cf88c75 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -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={:?})", diff --git a/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs b/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs index dbae40be6fe..e93f29f9bc8 100644 --- a/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs @@ -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)) } } } diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index f0b62e28a0d..f24aa51eb25 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -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>,