//! This pass type-checks the MIR to ensure it is not broken.
-use std::{fmt, iter, mem};
use std::rc::Rc;
+use std::{fmt, iter, mem};
use either::Either;
-use rustc::hir;
-use rustc::hir::def_id::DefId;
-use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
use rustc::infer::canonical::QueryRegionConstraints;
use rustc::infer::outlives::env::RegionBoundPairs;
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc::mir::*;
+use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
use rustc::mir::interpret::PanicInfo;
use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
-use rustc::traits::{self, ObligationCause, PredicateObligations};
-use rustc::traits::query::{Fallible, NoSolution};
+use rustc::mir::*;
use rustc::traits::query::type_op;
use rustc::traits::query::type_op::custom::CustomTypeOp;
-use rustc::ty::{
- self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
- TyCtxt, UserType,
- UserTypeAnnotationIndex,
-};
+use rustc::traits::query::{Fallible, NoSolution};
+use rustc::traits::{self, ObligationCause, PredicateObligations};
use rustc::ty::adjustment::PointerCast;
use rustc::ty::cast::CastTy;
use rustc::ty::fold::TypeFoldable;
use rustc::ty::layout::VariantIdx;
use rustc::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
+use rustc::ty::{
+ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
+ TyCtxt, UserType, UserTypeAnnotationIndex,
+};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_error_codes::*;
+use rustc_errors::struct_span_err;
+use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};
-use syntax_pos::{DUMMY_SP, Span};
+use rustc_span::{Span, DUMMY_SP};
+use crate::dataflow::move_paths::MoveData;
use crate::dataflow::FlowAtLocation;
use crate::dataflow::MaybeInitializedPlaces;
-use crate::dataflow::move_paths::MoveData;
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
use crate::borrow_check::{
borrow_set::BorrowSet,
+ constraints::{OutlivesConstraint, OutlivesConstraintSet},
+ facts::AllFacts,
location::LocationTable,
- constraints::{OutlivesConstraintSet, OutlivesConstraint},
member_constraints::MemberConstraintSet,
- facts::AllFacts,
+ nll::ToRegionVid,
region_infer::values::{
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
},
region_infer::{ClosureRegionRequirementsExt, TypeTest},
- type_check::free_region_relations::{
- CreateResult, UniversalRegionRelations,
- },
- universal_regions::{DefiningTy, UniversalRegions},
- nll::ToRegionVid,
renumber,
+ type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
+ universal_regions::{DefiningTy, UniversalRegions},
};
macro_rules! span_mirbug {
&mut borrowck_context,
&universal_region_relations,
|mut cx| {
- cx.equate_inputs_and_outputs(
- &body,
- universal_regions,
- &normalized_inputs_and_output);
- liveness::generate(
- &mut cx,
- body,
- elements,
- flow_inits,
- move_data,
- location_table);
+ cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
+ liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
translate_outlives_facts(&mut cx);
},
);
- MirTypeckResults {
- constraints,
- universal_region_relations,
- }
+ MirTypeckResults { constraints, universal_region_relations }
}
fn type_check_internal<'a, 'tcx, R>(
if let Some(facts) = cx.all_facts {
let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
let location_table = cx.location_table;
- facts
- .outlives
- .extend(cx.constraints.outlives_constraints.outlives().iter().flat_map(
- |constraint: &OutlivesConstraint| {
- if let Some(from_location) = constraint.locations.from_location() {
- Either::Left(iter::once((
- constraint.sup,
- constraint.sub,
- location_table.mid_index(from_location),
- )))
- } else {
- Either::Right(
- location_table
- .all_points()
- .map(move |location| (constraint.sup, constraint.sub, location)),
- )
- }
- },
- ));
+ facts.outlives.extend(cx.constraints.outlives_constraints.outlives().iter().flat_map(
+ |constraint: &OutlivesConstraint| {
+ if let Some(from_location) = constraint.locations.from_location() {
+ Either::Left(iter::once((
+ constraint.sup,
+ constraint.sub,
+ location_table.mid_index(from_location),
+ )))
+ } else {
+ Either::Right(
+ location_table
+ .all_points()
+ .map(move |location| (constraint.sup, constraint.sub, location)),
+ )
+ }
+ },
+ ));
}
}
if let Err(terr) = self.cx.relate_type_and_user_type(
constant.literal.ty,
ty::Variance::Invariant,
- &UserTypeProjection { base: annotation_index, projs: vec![], },
+ &UserTypeProjection { base: annotation_index, projs: vec![] },
location.to_locations(),
ConstraintCategory::Boring,
) {
);
}
} else {
- if let ty::ConstKind::Unevaluated(def_id, substs) = constant.literal.val {
- if let Err(terr) = self.cx.fully_perform_op(
- location.to_locations(),
- ConstraintCategory::Boring,
- self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
- constant.literal.ty, def_id, UserSubsts { substs, user_self_ty: None },
- )),
- ) {
- span_mirbug!(
- self,
- constant,
- "bad constant type {:?} ({:?})",
- constant,
- terr
- );
+ if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val {
+ if let Some(promoted) = promoted {
+ let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
+ promoted: &ReadOnlyBodyAndCache<'_, 'tcx>,
+ ty,
+ san_ty| {
+ if let Err(terr) = verifier.cx.eq_types(
+ san_ty,
+ ty,
+ location.to_locations(),
+ ConstraintCategory::Boring,
+ ) {
+ span_mirbug!(
+ verifier,
+ promoted,
+ "bad promoted type ({:?}: {:?}): {:?}",
+ ty,
+ san_ty,
+ terr
+ );
+ };
+ };
+
+ if !self.errors_reported {
+ let promoted_body = self.promoted[promoted];
+ self.sanitize_promoted(promoted_body, location);
+
+ let promoted_ty = promoted_body.return_ty();
+ check_err(self, &promoted_body, ty, promoted_ty);
+ }
+ } else {
+ if let Err(terr) = self.cx.fully_perform_op(
+ location.to_locations(),
+ ConstraintCategory::Boring,
+ self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
+ constant.literal.ty,
+ def_id,
+ UserSubsts { substs, user_self_ty: None },
+ )),
+ ) {
+ span_mirbug!(
+ self,
+ constant,
+ "bad constant type {:?} ({:?})",
+ constant,
+ terr
+ );
+ }
}
}
if let ty::FnDef(def_id, substs) = constant.literal.ty.kind {
let tcx = self.tcx();
- let instantiated_predicates = tcx
- .predicates_of(def_id)
- .instantiate(tcx, substs);
+ let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
self.cx.normalize_and_prove_instantiated_predicates(
instantiated_predicates,
location.to_locations(),
debug!("sanitize_place: {:?}", place);
let mut place_ty = match &place.base {
- PlaceBase::Local(index) =>
- PlaceTy::from_ty(self.body.local_decls[*index].ty),
+ PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty),
PlaceBase::Static(box Static { kind, ty, def_id }) => {
let san_ty = self.sanitize_type(place, ty);
let check_err =
- |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
- place: &Place<'tcx>,
- ty,
- san_ty| {
+ |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, place: &Place<'tcx>, ty, san_ty| {
if let Err(terr) = verifier.cx.eq_types(
san_ty,
ty,
ConstraintCategory::Boring,
) {
span_mirbug!(
- verifier,
- place,
- "bad promoted type ({:?}: {:?}): {:?}",
- ty,
- san_ty,
- terr
- );
+ verifier,
+ place,
+ "bad promoted type ({:?}: {:?}): {:?}",
+ ty,
+ san_ty,
+ terr
+ );
};
};
match kind {
- StaticKind::Promoted(promoted, _) => {
- if !self.errors_reported {
- let promoted_body_cache = self.promoted[*promoted];
- self.sanitize_promoted(promoted_body_cache, location);
-
- let promoted_ty = promoted_body_cache.return_ty();
- check_err(self, place, promoted_ty, san_ty);
- }
- }
StaticKind::Static => {
let ty = self.tcx().type_of(*def_id);
let ty = self.cx.normalize(ty, location);
if place.projection.is_empty() {
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
- let is_promoted = match place.as_ref() {
- PlaceRef {
- base: &PlaceBase::Static(box Static {
- kind: StaticKind::Promoted(..),
- ..
- }),
- projection: &[],
- } => true,
- _ => false,
+ let tcx = self.tcx();
+ let trait_ref = ty::TraitRef {
+ def_id: tcx.lang_items().copy_trait().unwrap(),
+ substs: tcx.mk_substs_trait(place_ty.ty, &[]),
};
- if !is_promoted {
- let tcx = self.tcx();
- let trait_ref = ty::TraitRef {
- def_id: tcx.lang_items().copy_trait().unwrap(),
- substs: tcx.mk_substs_trait(place_ty.ty, &[]),
- };
-
- // To have a `Copy` operand, the type `T` of the
- // value must be `Copy`. Note that we prove that `T: Copy`,
- // rather than using the `is_copy_modulo_regions`
- // test. This is important because
- // `is_copy_modulo_regions` ignores the resulting region
- // obligations and assumes they pass. This can result in
- // bounds from `Copy` impls being unsoundly ignored (e.g.,
- // #29149). Note that we decide to use `Copy` before knowing
- // whether the bounds fully apply: in effect, the rule is
- // that if a value of some type could implement `Copy`, then
- // it must.
- self.cx.prove_trait_ref(
- trait_ref,
- location.to_locations(),
- ConstraintCategory::CopyBound,
- );
- }
+ // To have a `Copy` operand, the type `T` of the
+ // value must be `Copy`. Note that we prove that `T: Copy`,
+ // rather than using the `is_copy_modulo_regions`
+ // test. This is important because
+ // `is_copy_modulo_regions` ignores the resulting region
+ // obligations and assumes they pass. This can result in
+ // bounds from `Copy` impls being unsoundly ignored (e.g.,
+ // #29149). Note that we decide to use `Copy` before knowing
+ // whether the bounds fully apply: in effect, the rule is
+ // that if a value of some type could implement `Copy`, then
+ // it must.
+ self.cx.prove_trait_ref(
+ trait_ref,
+ location.to_locations(),
+ ConstraintCategory::CopyBound,
+ );
}
}
fn sanitize_promoted(
&mut self,
promoted_body: ReadOnlyBodyAndCache<'b, 'tcx>,
- location: Location
+ location: Location,
) {
// Determine the constraints from the promoted MIR by running the type
// checker on the promoted MIR, then transfer the constraints back to
let all_facts = &mut None;
let mut constraints = Default::default();
let mut closure_bounds = Default::default();
- let mut liveness_constraints = LivenessValues::new(
- Rc::new(RegionValueElements::new(&promoted_body)),
- );
+ let mut liveness_constraints =
+ LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body)));
// Don't try to add borrow_region facts for the promoted MIR
let mut swap_constraints = |this: &mut Self| {
mem::swap(this.cx.borrowck_context.all_facts, all_facts);
mem::swap(
&mut this.cx.borrowck_context.constraints.outlives_constraints,
- &mut constraints
+ &mut constraints,
);
mem::swap(
&mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
- &mut closure_bounds
+ &mut closure_bounds,
);
mem::swap(
&mut this.cx.borrowck_context.constraints.liveness_constraints,
- &mut liveness_constraints
+ &mut liveness_constraints,
);
};
self.visit_body(promoted_body);
-
if !self.errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
self.cx.typeck_mir(promoted_body);
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
}
for live_region in liveness_constraints.rows() {
- self.cx.borrowck_context.constraints.liveness_constraints
+ self.cx
+ .borrowck_context
+ .constraints
+ .liveness_constraints
.add_element(live_region, location);
}
if !closure_bounds.is_empty() {
- let combined_bounds_mapping = closure_bounds
- .into_iter()
- .flat_map(|(_, value)| value)
- .collect();
- let existing = self.cx.borrowck_context
+ let combined_bounds_mapping =
+ closure_bounds.into_iter().flat_map(|(_, value)| value).collect();
+ let existing = self
+ .cx
+ .borrowck_context
.constraints
.closure_bounds_mapping
.insert(location, combined_bounds_mapping);
- assert!(
- existing.is_none(),
- "Multiple promoteds/closures at the same location."
- );
+ assert!(existing.is_none(), "Multiple promoteds/closures at the same location.");
}
}
match *pi {
ProjectionElem::Deref => {
let deref_ty = base_ty.builtin_deref(true);
- PlaceTy::from_ty(
- deref_ty.map(|t| t.ty).unwrap_or_else(|| {
- span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty)
- })
- )
+ PlaceTy::from_ty(deref_ty.map(|t| t.ty).unwrap_or_else(|| {
+ span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty)
+ }))
}
ProjectionElem::Index(i) => {
let index_ty = Place::from(i).ty(self.body, tcx).ty;
if index_ty != tcx.types.usize {
- PlaceTy::from_ty(
- span_mirbug_and_err!(self, i, "index by non-usize {:?}", i),
- )
+ PlaceTy::from_ty(span_mirbug_and_err!(self, i, "index by non-usize {:?}", i))
} else {
- PlaceTy::from_ty(
- base_ty.builtin_index().unwrap_or_else(|| {
- span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
- }),
- )
+ PlaceTy::from_ty(base_ty.builtin_index().unwrap_or_else(|| {
+ span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
+ }))
}
}
ProjectionElem::ConstantIndex { .. } => {
// consider verifying in-bounds
- PlaceTy::from_ty(
- base_ty.builtin_index().unwrap_or_else(|| {
- span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
- }),
- )
+ PlaceTy::from_ty(base_ty.builtin_index().unwrap_or_else(|| {
+ span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
+ }))
}
- ProjectionElem::Subslice { from, to, from_end } => PlaceTy::from_ty(
- match base_ty.kind {
+ ProjectionElem::Subslice { from, to, from_end } => {
+ PlaceTy::from_ty(match base_ty.kind {
ty::Array(inner, _) => {
assert!(!from_end, "array subslices should not use from_end");
tcx.mk_array(inner, (to - from) as u64)
ty::Slice(..) => {
assert!(from_end, "slice subslices should use from_end");
base_ty
- },
+ }
_ => span_mirbug_and_err!(self, place, "slice of non-array {:?}", base_ty),
- },
- ),
+ })
+ }
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind {
ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
if index.as_usize() >= adt_def.variants.len() {
- PlaceTy::from_ty(
- span_mirbug_and_err!(
- self,
- place,
- "cast to variant #{:?} but enum only has {:?}",
- index,
- adt_def.variants.len()
- ),
- )
+ PlaceTy::from_ty(span_mirbug_and_err!(
+ self,
+ place,
+ "cast to variant #{:?} but enum only has {:?}",
+ index,
+ adt_def.variants.len()
+ ))
} else {
- PlaceTy {
- ty: base_ty,
- variant_index: Some(index),
- }
+ PlaceTy { ty: base_ty, variant_index: Some(index) }
}
}
// We do not need to handle generators here, because this runs
span_mirbug_and_err!(self, place, "can't downcast {:?}", base_ty)
};
PlaceTy::from_ty(ty)
- },
+ }
},
ProjectionElem::Field(field, fty) => {
let fty = self.sanitize_type(place, fty);
match self.field_ty(place, base, field, location) {
- Ok(ty) => if let Err(terr) = self.cx.eq_types(
- ty,
- fty,
- location.to_locations(),
- ConstraintCategory::Boring,
- ) {
- span_mirbug!(
- self,
- place,
- "bad field access ({:?}: {:?}): {:?}",
+ Ok(ty) => {
+ if let Err(terr) = self.cx.eq_types(
ty,
fty,
- terr
- );
- },
+ location.to_locations(),
+ ConstraintCategory::Boring,
+ ) {
+ span_mirbug!(
+ self,
+ place,
+ "bad field access ({:?}: {:?}): {:?}",
+ ty,
+ fty,
+ terr
+ );
+ }
+ }
Err(FieldAccessError::OutOfRange { field_count }) => span_mirbug!(
self,
place,
let mut variants = substs.as_generator().state_tys(def_id, tcx);
let mut variant = match variants.nth(variant_index.into()) {
Some(v) => v,
- None => {
- bug!("variant_index of generator out of range: {:?}/{:?}",
- variant_index,
- substs.as_generator().state_tys(def_id, tcx).count())
- }
+ None => bug!(
+ "variant_index of generator out of range: {:?}/{:?}",
+ variant_index,
+ substs.as_generator().state_tys(def_id, tcx).count()
+ ),
};
return match variant.nth(field.index()) {
Some(ty) => Ok(ty),
- None => Err(FieldAccessError::OutOfRange {
- field_count: variant.count(),
- }),
- }
+ None => Err(FieldAccessError::OutOfRange { field_count: variant.count() }),
+ };
}
_ => bug!("can't have downcast of non-adt non-generator type"),
- }
+ },
PlaceTy { ty, variant_index: None } => match ty.kind {
- ty::Adt(adt_def, substs) if !adt_def.is_enum() =>
- (&adt_def.variants[VariantIdx::new(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.as_closure().upvar_tys(def_id, tcx).nth(field.index()) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys(def_id, tcx).count(),
}),
- }
+ };
}
ty::Generator(def_id, substs, _) => {
// Only prefix fields (upvars and current state) are
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys(def_id, tcx).count(),
}),
- }
+ };
}
ty::Tuple(tys) => {
return match tys.get(field.index()) {
Some(&ty) => Ok(ty.expect_ty()),
- None => Err(FieldAccessError::OutOfRange {
- field_count: tys.len(),
- }),
- }
+ None => Err(FieldAccessError::OutOfRange { field_count: tys.len() }),
+ };
}
_ => {
return Ok(span_mirbug_and_err!(
parent,
"can't project out of {:?}",
base_ty
- ))
+ ));
}
},
};
if let Some(field) = variant.fields.get(field.index()) {
Ok(self.cx.normalize(&field.ty(tcx, substs), location))
} else {
- Err(FieldAccessError::OutOfRange {
- field_count: variant.fields.len(),
- })
+ Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
}
}
}
fn check_user_type_annotations(&mut self) {
debug!(
"check_user_type_annotations: user_type_annotations={:?}",
- self.user_type_annotations
+ self.user_type_annotations
);
for user_annotation in self.user_type_annotations {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
- let (annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
- span, user_ty
- );
+ let (annotation, _) =
+ self.infcx.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
match annotation {
UserType::Ty(mut ty) => {
ty = self.normalize(ty, Locations::All(span));
Locations::All(span),
ConstraintCategory::TypeAnnotation,
);
- },
+ }
UserType::TypeOf(def_id, user_substs) => {
if let Err(terr) = self.fully_perform_op(
Locations::All(span),
ConstraintCategory::BoringNoLocation,
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
- inferred_ty, def_id, user_substs,
+ inferred_ty,
+ def_id,
+ user_substs,
)),
) {
span_mirbug!(
terr
);
}
- },
+ }
}
}
}
category: ConstraintCategory,
data: &QueryRegionConstraints<'tcx>,
) {
- debug!(
- "push_region_constraints: constraints generated at {:?} are {:#?}",
- locations, data
- );
+ debug!("push_region_constraints: constraints generated at {:?} are {:#?}", locations, data);
constraint_conversion::ConstraintConversion::new(
self.infcx,
locations,
category,
&mut self.borrowck_context.constraints,
- ).convert_all(data);
+ )
+ .convert_all(data);
}
/// Convenient wrapper around `relate_tys::relate_types` -- see
);
curr_projected_ty = projected_ty;
}
- debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
- user_ty.base, annotated_type, user_ty.projs, curr_projected_ty);
+ debug!(
+ "user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
+ user_ty.base, annotated_type, user_ty.projs, curr_projected_ty
+ );
let ty = curr_projected_ty.ty;
self.relate_types(a, v, ty, locations, category)?;
revealed_ty={:?}",
output_ty, opaque_type_map, revealed_ty
);
- obligations.add(infcx
- .at(&ObligationCause::dummy(), param_env)
- .eq(output_ty, revealed_ty)?);
+ obligations.add(
+ infcx
+ .at(&ObligationCause::dummy(), param_env)
+ .eq(output_ty, revealed_ty)?,
+ );
for (&opaque_def_id, opaque_decl) in &opaque_type_map {
let opaque_defn_ty = tcx.type_of(opaque_def_id);
let opaque_defn_ty = opaque_defn_ty.subst(tcx, opaque_decl.substs);
let opaque_defn_ty = renumber::renumber_regions(infcx, &opaque_defn_ty);
let concrete_is_opaque = infcx
- .resolve_vars_if_possible(&opaque_decl.concrete_ty).is_impl_trait();
+ .resolve_vars_if_possible(&opaque_decl.concrete_ty)
+ .is_impl_trait();
debug!(
"eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?} \
// gets 'revealed' into
if !concrete_is_opaque {
- obligations.add(infcx
- .at(&ObligationCause::dummy(), param_env)
- .eq(opaque_decl.concrete_ty, opaque_defn_ty)?);
+ obligations.add(
+ infcx
+ .at(&ObligationCause::dummy(), param_env)
+ .eq(opaque_decl.concrete_ty, opaque_defn_ty)?,
+ );
}
}
&opaque_decl,
universal_region_relations,
);
- Ok(InferOk {
- value: (),
- obligations: vec![],
- })
+ Ok(InferOk { value: (), obligations: vec![] })
},
|| "opaque_type_map".to_string(),
),
&mut self,
body: ReadOnlyBodyAndCache<'_, 'tcx>,
stmt: &Statement<'tcx>,
- location: Location)
- {
+ location: Location,
+ ) {
debug!("check_stmt: {:?}", stmt);
let tcx = self.tcx();
match stmt.kind {
- StatementKind::Assign(box(ref place, ref rv)) => {
+ StatementKind::Assign(box (ref place, ref rv)) => {
// Assignments to temporaries are not "interesting";
// they are not caused by the user, but rather artifacts
// of lowering. Assignments to other sorts of places *are* interesting
// though.
let category = match place.as_local() {
- Some(RETURN_PLACE) => if let BorrowCheckContext {
- universal_regions:
- UniversalRegions {
- defining_ty: DefiningTy::Const(def_id, _),
- ..
- },
- ..
- } = self.borrowck_context {
- if tcx.is_static(*def_id) {
- ConstraintCategory::UseAsStatic
+ Some(RETURN_PLACE) => {
+ if let BorrowCheckContext {
+ universal_regions:
+ UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
+ ..
+ } = self.borrowck_context
+ {
+ if tcx.is_static(*def_id) {
+ ConstraintCategory::UseAsStatic
+ } else {
+ ConstraintCategory::UseAsConst
+ }
} else {
- ConstraintCategory::UseAsConst
+ ConstraintCategory::Return
}
- } else {
- ConstraintCategory::Return
- },
+ }
Some(l) if !body.local_decls[l].is_user_variable() => {
ConstraintCategory::Boring
}
if let Err(terr) = self.relate_type_and_user_type(
rv_ty,
ty::Variance::Invariant,
- &UserTypeProjection { base: annotation_index, projs: vec![], },
+ &UserTypeProjection { base: annotation_index, projs: vec![] },
location.to_locations(),
ConstraintCategory::Boring,
) {
);
}
}
- StatementKind::SetDiscriminant {
- ref place,
- variant_index,
- } => {
+ StatementKind::SetDiscriminant { ref place, variant_index } => {
let place_type = place.ty(*body, tcx).ty;
let adt = match place_type.kind {
ty::Adt(adt, _) if adt.is_enum() => adt,
);
};
}
- StatementKind::AscribeUserType(box(ref place, ref projection), variance) => {
+ StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
let place_ty = place.ty(*body, tcx).ty;
if let Err(terr) = self.relate_type_and_user_type(
place_ty,
// no checks needed for these
}
- TerminatorKind::DropAndReplace {
- ref location,
- ref value,
- target: _,
- unwind: _,
- } => {
+ TerminatorKind::DropAndReplace { ref location, ref value, target: _, unwind: _ } => {
let place_ty = location.ty(body, tcx).ty;
let rv_ty = value.ty(body, tcx);
);
}
}
- TerminatorKind::SwitchInt {
- ref discr,
- switch_ty,
- ..
- } => {
+ TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
let discr_ty = discr.ty(body, tcx);
if let Err(terr) = self.sub_types(
discr_ty,
}
// FIXME: check the values
}
- TerminatorKind::Call {
- ref func,
- ref args,
- ref destination,
- from_hir_call,
- ..
- } => {
+ TerminatorKind::Call { ref func, ref args, ref destination, from_hir_call, .. } => {
let func_ty = func.ty(body, tcx);
debug!("check_terminator: call, func_ty={:?}", func_ty);
let sig = match func_ty.kind {
// output) types in the signature must be live, since
// all the inputs that fed into it were live.
for &late_bound_region in map.values() {
- let region_vid = self.borrowck_context
- .universal_regions
- .to_region_vid(late_bound_region);
+ let region_vid =
+ self.borrowck_context.universal_regions.to_region_vid(late_bound_region);
self.borrowck_context
.constraints
.liveness_constraints
self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
}
- TerminatorKind::Assert {
- ref cond, ref msg, ..
- } => {
+ TerminatorKind::Assert { ref cond, ref msg, .. } => {
let cond_ty = cond.ty(body, tcx);
if cond_ty != tcx.types.bool {
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
Some(RETURN_PLACE) => {
if let BorrowCheckContext {
universal_regions:
- UniversalRegions {
- defining_ty: DefiningTy::Const(def_id, _),
- ..
- },
+ UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
..
} = self.borrowck_context
{
TerminatorKind::Goto { target } => {
self.assert_iscleanup(body, block_data, target, is_cleanup)
}
- TerminatorKind::SwitchInt { ref targets, .. } => for target in targets {
- self.assert_iscleanup(body, block_data, *target, is_cleanup);
- },
- TerminatorKind::Resume => if !is_cleanup {
- span_mirbug!(self, block_data, "resume on non-cleanup block!")
- },
- TerminatorKind::Abort => if !is_cleanup {
- span_mirbug!(self, block_data, "abort on non-cleanup block!")
- },
- TerminatorKind::Return => if is_cleanup {
- span_mirbug!(self, block_data, "return on cleanup block")
- },
- TerminatorKind::GeneratorDrop { .. } => if is_cleanup {
- span_mirbug!(self, block_data, "generator_drop in cleanup block")
- },
+ TerminatorKind::SwitchInt { ref targets, .. } => {
+ for target in targets {
+ self.assert_iscleanup(body, block_data, *target, is_cleanup);
+ }
+ }
+ TerminatorKind::Resume => {
+ if !is_cleanup {
+ span_mirbug!(self, block_data, "resume on non-cleanup block!")
+ }
+ }
+ TerminatorKind::Abort => {
+ if !is_cleanup {
+ span_mirbug!(self, block_data, "abort on non-cleanup block!")
+ }
+ }
+ TerminatorKind::Return => {
+ if is_cleanup {
+ span_mirbug!(self, block_data, "return on cleanup block")
+ }
+ }
+ TerminatorKind::GeneratorDrop { .. } => {
+ if is_cleanup {
+ span_mirbug!(self, block_data, "generator_drop in cleanup block")
+ }
+ }
TerminatorKind::Yield { resume, drop, .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "yield in cleanup block")
TerminatorKind::Unreachable => {}
TerminatorKind::Drop { target, unwind, .. }
| TerminatorKind::DropAndReplace { target, unwind, .. }
- | TerminatorKind::Assert {
- target,
- cleanup: unwind,
- ..
- } => {
+ | TerminatorKind::Assert { target, cleanup: unwind, .. } => {
self.assert_iscleanup(body, block_data, target, is_cleanup);
if let Some(unwind) = unwind {
if is_cleanup {
self.assert_iscleanup(body, block_data, unwind, true);
}
}
- TerminatorKind::Call {
- ref destination,
- cleanup,
- ..
- } => {
+ TerminatorKind::Call { ref destination, cleanup, .. } => {
if let &Some((_, target)) = destination {
self.assert_iscleanup(body, block_data, target, is_cleanup);
}
self.assert_iscleanup(body, block_data, cleanup, true);
}
}
- TerminatorKind::FalseEdges {
- real_target,
- imaginary_target,
- } => {
+ TerminatorKind::FalseEdges { real_target, imaginary_target } => {
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
self.assert_iscleanup(body, block_data, imaginary_target, is_cleanup);
}
- TerminatorKind::FalseUnwind {
- real_target,
- unwind,
- } => {
+ TerminatorKind::FalseUnwind { real_target, unwind } => {
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
if let Some(unwind) = unwind {
if is_cleanup {
- span_mirbug!(
- self,
- block_data,
- "cleanup in cleanup block via false unwind"
- );
+ span_mirbug!(self, block_data, "cleanup in cleanup block via false unwind");
}
self.assert_iscleanup(body, block_data, unwind, true);
}
iscleanuppad: bool,
) {
if body[bb].is_cleanup != iscleanuppad {
- span_mirbug!(
- self,
- ctxt,
- "cleanuppad mismatch: {:?} should be {:?}",
- bb,
- iscleanuppad
- );
+ span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad);
}
}
if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location))
} else {
- Err(FieldAccessError::OutOfRange {
- field_count: variant.fields.len(),
- })
+ Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
}
}
AggregateKind::Closure(def_id, substs) => {
&mut self,
body: ReadOnlyBodyAndCache<'_, 'tcx>,
rvalue: &Rvalue<'tcx>,
- location: Location)
- {
+ location: Location,
+ ) {
let tcx = self.tcx();
match rvalue {
self.check_aggregate_rvalue(&body, rvalue, ak, ops, location)
}
- Rvalue::Repeat(operand, len) => if *len > 1 {
- if let Operand::Move(_) = operand {
- // While this is located in `nll::typeck` this error is not an NLL error, it's
- // a required check to make sure that repeated elements implement `Copy`.
- let span = body.source_info(location).span;
- let ty = operand.ty(*body, tcx);
- if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
- // To determine if `const_in_array_repeat_expressions` feature gate should
- // be mentioned, need to check if the rvalue is promotable.
- let should_suggest =
- should_suggest_const_in_array_repeat_expressions_attribute(
- tcx, self.mir_def_id, body, operand);
- debug!("check_rvalue: should_suggest={:?}", should_suggest);
-
- self.infcx.report_selection_error(
- &traits::Obligation::new(
- ObligationCause::new(
- span,
- self.tcx().hir().def_index_to_hir_id(self.mir_def_id.index),
- traits::ObligationCauseCode::RepeatVec(should_suggest),
- ),
- self.param_env,
- ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate {
- trait_ref: ty::TraitRef::new(
- self.tcx().lang_items().copy_trait().unwrap(),
- tcx.mk_substs_trait(ty, &[]),
+ Rvalue::Repeat(operand, len) => {
+ if *len > 1 {
+ if let Operand::Move(_) = operand {
+ // While this is located in `nll::typeck` this error is not an NLL error, it's
+ // a required check to make sure that repeated elements implement `Copy`.
+ let span = body.source_info(location).span;
+ let ty = operand.ty(*body, tcx);
+ if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
+ // To determine if `const_in_array_repeat_expressions` feature gate should
+ // be mentioned, need to check if the rvalue is promotable.
+ let should_suggest =
+ should_suggest_const_in_array_repeat_expressions_attribute(
+ tcx,
+ self.mir_def_id,
+ body,
+ operand,
+ );
+ debug!("check_rvalue: should_suggest={:?}", should_suggest);
+
+ self.infcx.report_selection_error(
+ &traits::Obligation::new(
+ ObligationCause::new(
+ span,
+ self.tcx().hir().def_index_to_hir_id(self.mir_def_id.index),
+ traits::ObligationCauseCode::RepeatVec(should_suggest),
),
- })),
- ),
- &traits::SelectionError::Unimplemented,
- false,
- false,
- );
+ self.param_env,
+ ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate {
+ trait_ref: ty::TraitRef::new(
+ self.tcx().lang_items().copy_trait().unwrap(),
+ tcx.mk_substs_trait(ty, &[]),
+ ),
+ })),
+ ),
+ &traits::SelectionError::Unimplemented,
+ false,
+ false,
+ );
+ }
}
}
- },
+ }
Rvalue::NullaryOp(_, ty) => {
// Even with unsized locals cannot box an unsized value.
}
}
- CastKind::Pointer(PointerCast::ArrayToPointer) => {
+ CastKind::Pointer(PointerCast::ArrayToPointer) => {
let ty_from = op.ty(*body, tcx);
let opt_ty_elem = match ty_from.kind {
- ty::RawPtr(
- ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: array_ty }
- ) => {
- match array_ty.kind {
- ty::Array(ty_elem, _) => Some(ty_elem),
- _ => None,
- }
- }
+ ty::RawPtr(ty::TypeAndMut {
+ mutbl: hir::Mutability::Not,
+ ty: array_ty,
+ }) => match array_ty.kind {
+ ty::Array(ty_elem, _) => Some(ty_elem),
+ _ => None,
+ },
_ => None,
};
};
let ty_to = match ty.kind {
- ty::RawPtr(
- ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: ty_to }
- ) => {
- ty_to
- }
+ ty::RawPtr(ty::TypeAndMut {
+ mutbl: hir::Mutability::Not,
+ ty: ty_to,
+ }) => ty_to,
_ => {
span_mirbug!(
self,
| (_, Some(CastTy::FnPtr))
| (Some(CastTy::Float), Some(CastTy::Ptr(_)))
| (Some(CastTy::Ptr(_)), Some(CastTy::Float))
- | (Some(CastTy::FnPtr), Some(CastTy::Float)) => span_mirbug!(
- self,
- rvalue,
- "Invalid cast {:?} -> {:?}",
- ty_from,
- ty,
- ),
+ | (Some(CastTy::FnPtr), Some(CastTy::Float)) => {
+ span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,)
+ }
(Some(CastTy::Int(_)), Some(CastTy::Int(_)))
| (Some(CastTy::Float), Some(CastTy::Int(_)))
| (Some(CastTy::Int(_)), Some(CastTy::Float))
let ty_left = left.ty(*body, tcx);
if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.kind {
let ty_right = right.ty(*body, tcx);
- let common_ty = self.infcx.next_ty_var(
- TypeVariableOrigin {
- kind: TypeVariableOriginKind::MiscVariable,
- span: body.source_info(location).span,
- }
- );
+ let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span: body.source_info(location).span,
+ });
self.sub_types(
common_ty,
ty_left,
location.to_locations(),
- ConstraintCategory::Boring
- ).unwrap_or_else(|err| {
+ ConstraintCategory::Boring,
+ )
+ .unwrap_or_else(|err| {
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
});
if let Err(terr) = self.sub_types(
common_ty,
ty_right,
location.to_locations(),
- ConstraintCategory::Boring
+ ConstraintCategory::Boring,
) {
span_mirbug!(
self,
borrowed_place: &Place<'tcx>,
) {
// These constraints are only meaningful during borrowck:
- let BorrowCheckContext {
- borrow_set,
- location_table,
- all_facts,
- constraints,
- ..
- } = self.borrowck_context;
+ let BorrowCheckContext { borrow_set, location_table, all_facts, constraints, .. } =
+ self.borrowck_context;
// In Polonius mode, we also push a `borrow_region` fact
// linking the loan to the region (in some cases, though,
&closure_region_requirements.outlives_requirements[idx];
Some((
(r1_vid, r2_vid),
- (
- outlives_requirements.category,
- outlives_requirements.blame_span,
- ),
+ (outlives_requirements.category, outlives_requirements.blame_span),
))
}
GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
})
.collect();
- let existing = self.borrowck_context
+ let existing = self
+ .borrowck_context
.constraints
.closure_bounds_mapping
.insert(location, bounds_mapping);
- assert!(
- existing.is_none(),
- "Multiple closures at the same location."
- );
+ assert!(existing.is_none(), "Multiple closures at the same location.");
self.push_region_constraints(
location.to_locations(),
category: ConstraintCategory,
) {
self.prove_predicates(
- Some(ty::Predicate::Trait(
- trait_ref.to_poly_trait_ref().to_poly_trait_predicate(),
- )),
+ Some(ty::Predicate::Trait(trait_ref.to_poly_trait_ref().to_poly_trait_predicate())),
locations,
category,
);
category: ConstraintCategory,
) {
for predicate in predicates {
- debug!(
- "prove_predicates(predicate={:?}, locations={:?})",
- predicate, locations,
- );
+ debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
self.prove_predicate(predicate, locations, category);
}
locations: Locations,
category: ConstraintCategory,
) {
- debug!(
- "prove_predicate(predicate={:?}, location={:?})",
- predicate, locations,
- );
+ debug!("prove_predicate(predicate={:?}, location={:?})", predicate, locations,);
let param_env = self.param_env;
self.fully_perform_op(
locations,
category,
param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)),
- ).unwrap_or_else(|NoSolution| {
+ )
+ .unwrap_or_else(|NoSolution| {
span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
})
}
}
for (block, block_data) in body.basic_blocks().iter_enumerated() {
- let mut location = Location {
- block,
- statement_index: 0,
- };
+ let mut location = Location { block, statement_index: 0 };
for stmt in &block_data.statements {
if !stmt.source_info.span.is_dummy() {
self.last_span = stmt.source_info.span;
location.to_locations(),
ConstraintCategory::Boring,
param_env.and(type_op::normalize::Normalize::new(value)),
- ).unwrap_or_else(|NoSolution| {
+ )
+ .unwrap_or_else(|NoSolution| {
span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
value
})