// except according to those terms.
//! This pass type-checks the MIR to ensure it is not broken.
+
#![allow(unreachable_code)]
use borrow_check::borrow_set::BorrowSet;
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc::ty::layout::VariantIdx;
use std::rc::Rc;
use std::{fmt, iter};
use syntax_pos::{Span, DUMMY_SP};
/// - `liveness` -- results of a liveness computation on the MIR; used to create liveness
/// constraints for the regions in the types of variables
/// - `flow_inits` -- results of a maybe-init dataflow analysis
-/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysiss
+/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
pub(crate) fn type_check<'gcx, 'tcx>(
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'gcx>,
},
ProjectionElem::Downcast(adt_def1, index) => match base_ty.sty {
ty::Adt(adt_def, substs) if adt_def.is_enum() && adt_def == adt_def1 => {
- if index >= adt_def.variants.len() {
+ if index.as_usize() >= adt_def.variants.len() {
PlaceTy::Ty {
ty: span_mirbug_and_err!(
self,
variant_index,
} => (&adt_def.variants[variant_index], substs),
PlaceTy::Ty { ty } => match ty.sty {
- ty::Adt(adt_def, substs) if !adt_def.is_enum() => (&adt_def.variants[0], substs),
+ ty::Adt(adt_def, substs) if !adt_def.is_enum() =>
+ (&adt_def.variants[VariantIdx::new(0)], substs),
ty::Closure(def_id, substs) => {
return match substs.upvar_tys(def_id, tcx).nth(field.index()) {
Some(ty) => Ok(ty),
fn placeholder_region(
&mut self,
infcx: &InferCtxt<'_, '_, 'tcx>,
- placeholder: ty::Placeholder,
+ placeholder: ty::PlaceholderRegion,
) -> ty::Region<'tcx> {
let placeholder_index = self.placeholder_indices.insert(placeholder);
match self.placeholder_index_to_region.get(placeholder_index) {
let v1 = ty::Contravariant.xform(v);
let tcx = self.infcx.tcx;
- let mut projected_ty = PlaceTy::from_ty(ty);
+ let ty = self.normalize(ty, locations);
+
+ // We need to follow any provided projetions into the type.
+ //
+ // if we hit a ty var as we descend, then just skip the
+ // attempt to relate the mir local with any type.
+ #[derive(Debug)] struct HitTyVar;
+ let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+
+ curr_projected_ty = Ok(PlaceTy::from_ty(ty));
for proj in &user_ty.projs {
- projected_ty = projected_ty.projection_ty_core(
+ let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+ projected_ty
+ } else {
+ break;
+ };
+ curr_projected_ty = projected_ty.projection_ty_core(
tcx, proj, |this, field, &()| {
- let ty = this.field_ty(tcx, field);
- self.normalize(ty, locations)
+ if this.to_ty(tcx).is_ty_var() {
+ Err(HitTyVar)
+ } else {
+ let ty = this.field_ty(tcx, field);
+ Ok(self.normalize(ty, locations))
+ }
});
}
debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
- user_ty.base, ty, user_ty.projs, projected_ty);
+ user_ty.base, ty, user_ty.projs, curr_projected_ty);
- let ty = projected_ty.to_ty(tcx);
-
- self.relate_types(ty, v1, a, locations, category)?;
+ if let Ok(projected_ty) = curr_projected_ty {
+ let ty = projected_ty.to_ty(tcx);
+ self.relate_types(ty, v1, a, locations, category)?;
+ }
}
UserTypeAnnotation::TypeOf(def_id, canonical_substs) => {
let (
);
}
};
- if variant_index >= adt.variants.len() {
+ if variant_index.as_usize() >= adt.variants.len() {
span_bug!(
stmt.source_info.span,
"bad set discriminant ({:?} = {:?}): value of of range",
}
}
StatementKind::FakeRead(..)
- | StatementKind::StorageLive(_)
- | StatementKind::StorageDead(_)
+ | StatementKind::StorageLive(..)
+ | StatementKind::StorageDead(..)
| StatementKind::InlineAsm { .. }
- | StatementKind::EndRegion(_)
| StatementKind::Retag { .. }
+ | StatementKind::EscapeToRaw { .. }
| StatementKind::Nop => {}
}
}
return;
}
};
- let (sig, map) = self.infcx.replace_late_bound_regions_with_fresh_var(
+ let (sig, map) = self.infcx.replace_bound_vars_with_fresh_vars(
term.source_info.span,
LateBoundRegionConversionTime::FnCall,
&sig,
value_ty,
ty,
term_location.to_locations(),
- ConstraintCategory::Return,
+ ConstraintCategory::Yield,
) {
span_mirbug!(
self,
}
}
None => {
- // FIXME(canndrew): This is_never should probably be an is_uninhabited
- if !sig.output().is_never() {
+ if !sig.output().conservative_is_uninhabited() {
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
}
}