infcx: &InferCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
body: &Body<'tcx>,
+ promoted: &IndexVec<Promoted, Body<'tcx>>,
mir_def_id: DefId,
universal_regions: &Rc<UniversalRegions<'tcx>>,
location_table: &LocationTable,
mir_def_id,
param_env,
body,
+ promoted,
®ion_bound_pairs,
implicit_region_bound,
&mut borrowck_context,
mir_def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
body: &'a Body<'tcx>,
+ promoted: &'a IndexVec<Promoted, Body<'tcx>>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
universal_region_relations,
);
let errors_reported = {
- let mut verifier = TypeVerifier::new(&mut checker, body);
+ let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
verifier.visit_body(body);
verifier.errors_reported
};
struct TypeVerifier<'a, 'b, 'tcx> {
cx: &'a mut TypeChecker<'b, 'tcx>,
body: &'b Body<'tcx>,
+ promoted: &'b IndexVec<Promoted, Body<'tcx>>,
last_span: Span,
mir_def_id: DefId,
errors_reported: bool,
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);
+ self.sanitize_type(constant, constant.literal.ty);
if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
- constant.ty,
+ constant.literal.ty,
ty::Variance::Invariant,
&UserTypeProjection { base: annotation_index, projs: vec![], },
location.to_locations(),
constant,
"bad constant user type {:?} vs {:?}: {:?}",
annotation,
- constant.ty,
+ constant.literal.ty,
terr,
);
}
location.to_locations(),
ConstraintCategory::Boring,
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
- constant.ty, def_id, UserSubsts { substs, user_self_ty: None },
+ constant.literal.ty, def_id, UserSubsts { substs, user_self_ty: None },
)),
) {
span_mirbug!(
}
impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
- fn new(cx: &'a mut TypeChecker<'b, 'tcx>, body: &'b Body<'tcx>) -> Self {
+ fn new(
+ cx: &'a mut TypeChecker<'b, 'tcx>,
+ body: &'b Body<'tcx>,
+ promoted: &'b IndexVec<Promoted, Body<'tcx>>,
+ ) -> Self {
TypeVerifier {
body,
+ promoted,
mir_def_id: cx.mir_def_id,
cx,
last_span: body.span,
}
}
- /// Checks that the constant's `ty` field matches up with what would be
- /// expected from its literal. Unevaluated constants and well-formed
- /// constraints are checked by `visit_constant`.
- fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
- debug!(
- "sanitize_constant(constant={:?}, location={:?})",
- constant, location
- );
-
- let literal = constant.literal;
-
- if let ConstValue::Unevaluated(..) = literal.val {
- return;
- }
-
- debug!("sanitize_constant: expected_ty={:?}", literal.ty);
-
- if let Err(terr) = self.cx.eq_types(
- literal.ty,
- constant.ty,
- location.to_locations(),
- ConstraintCategory::Boring,
- ) {
- span_mirbug!(
- self,
- constant,
- "constant {:?} should have type {:?} but has {:?} ({:?})",
- constant,
- literal.ty,
- constant.ty,
- terr,
- );
- }
- }
-
/// Checks that the types internal to the `place` match up with
/// what would be expected.
fn sanitize_place(
let mut place_ty = match place_base {
PlaceBase::Local(index) =>
PlaceTy::from_ty(self.body.local_decls[*index].ty),
- PlaceBase::Static(box Static { kind, ty: sty }) => {
+ PlaceBase::Static(box Static { kind, ty: sty, def_id }) => {
let sty = self.sanitize_type(place, sty);
let check_err =
|verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
};
};
match kind {
- StaticKind::Promoted(promoted) => {
+ StaticKind::Promoted(promoted, _) => {
if !self.errors_reported {
- let promoted_body = &self.body.promoted[*promoted];
+ let promoted_body = &self.promoted[*promoted];
self.sanitize_promoted(promoted_body, location);
let promoted_ty = promoted_body.return_ty();
check_err(self, place, promoted_ty, sty);
}
}
- StaticKind::Static(def_id) => {
+ StaticKind::Static => {
let ty = self.tcx().type_of(*def_id);
let ty = self.cx.normalize(ty, location);
let is_promoted = match place {
Place {
base: PlaceBase::Static(box Static {
- kind: StaticKind::Promoted(_),
+ kind: StaticKind::Promoted(..),
..
}),
projection: None,
ProjectionElem::Subslice { from, to } => PlaceTy::from_ty(
match base_ty.sty {
ty::Array(inner, size) => {
- let size = size.unwrap_usize(tcx);
+ let size = size.eval_usize(tcx, self.cx.param_env);
let min_size = (from as u64) + (to as u64);
if let Some(rest_size) = size.checked_sub(min_size) {
tcx.mk_array(inner, rest_size)
let tcx = self.infcx.tcx;
for proj in &user_ty.projs {
- let projected_ty = curr_projected_ty.projection_ty_core(tcx, proj, |this, field, &()| {
- let ty = this.field_ty(tcx, field);
- self.normalize(ty, locations)
- });
+ let projected_ty = curr_projected_ty.projection_ty_core(
+ tcx,
+ self.param_env,
+ proj,
+ |this, field, &()| {
+ let ty = this.field_ty(tcx, field);
+ self.normalize(ty, locations)
+ },
+ );
curr_projected_ty = projected_ty;
}
debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",