diff options
Diffstat (limited to 'compiler/rustc_borrowck/src/type_check/mod.rs')
-rw-r--r-- | compiler/rustc_borrowck/src/type_check/mod.rs | 170 |
1 files changed, 77 insertions, 93 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a49da3da6..2f10e30be 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -9,13 +9,12 @@ use either::Either; use hir::OpaqueTyOrigin; use rustc_data_structures::frozen::Frozen; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::vec_map::VecMap; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; @@ -36,8 +35,9 @@ use rustc_middle::ty::{ OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, }; use rustc_span::def_id::CRATE_DEF_ID; +use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -56,7 +56,6 @@ use crate::{ facts::AllFacts, location::LocationTable, member_constraints::MemberConstraintSet, - nll::ToRegionVid, path_utils, region_infer::values::{ LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, @@ -126,7 +125,7 @@ pub(crate) fn type_check<'mir, 'tcx>( infcx: &BorrowckInferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, - promoted: &IndexVec<Promoted, Body<'tcx>>, + promoted: &IndexSlice<Promoted, Body<'tcx>>, universal_regions: &Rc<UniversalRegions<'tcx>>, location_table: &LocationTable, borrow_set: &BorrowSet<'tcx>, @@ -145,7 +144,7 @@ pub(crate) fn type_check<'mir, 'tcx>( outlives_constraints: OutlivesConstraintSet::default(), member_constraints: MemberConstraintSet::default(), type_tests: Vec::default(), - universe_causes: FxHashMap::default(), + universe_causes: FxIndexMap::default(), }; let CreateResult { @@ -293,7 +292,7 @@ enum FieldAccessError { /// is a problem. struct TypeVerifier<'a, 'b, 'tcx> { cx: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexVec<Promoted, Body<'tcx>>, + promoted: &'b IndexSlice<Promoted, Body<'tcx>>, last_span: Span, errors_reported: bool, } @@ -494,7 +493,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { fn new( cx: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexVec<Promoted, Body<'tcx>>, + promoted: &'b IndexSlice<Promoted, Body<'tcx>>, ) -> Self { TypeVerifier { promoted, last_span: cx.body.span, cx, errors_reported: false } } @@ -772,11 +771,14 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { match context { PlaceContext::MutatingUse(_) => ty::Invariant, - PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant, + PlaceContext::NonUse(StorageDead | StorageLive | PlaceMention | VarDebugInfo) => { + ty::Invariant + } PlaceContext::NonMutatingUse( - Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf - | Projection, - ) => ty::Covariant, + Inspect | Copy | Move | SharedBorrow | ShallowBorrow | AddressOf | Projection + ) => { + ty::Covariant + }, PlaceContext::NonUse(AscribeUserTy) => ty::Covariant, } } @@ -785,7 +787,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { &mut self, parent: &dyn fmt::Debug, base_ty: PlaceTy<'tcx>, - field: Field, + field: FieldIdx, location: Location, ) -> Result<Ty<'tcx>, FieldAccessError> { let tcx = self.tcx(); @@ -811,7 +813,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }, PlaceTy { ty, variant_index: None } => match *ty.kind() { ty::Adt(adt_def, substs) if !adt_def.is_enum() => { - (adt_def.variant(VariantIdx::new(0)), substs) + (adt_def.variant(FIRST_VARIANT), substs) } ty::Closure(_, substs) => { return match substs @@ -853,7 +855,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }, }; - if let Some(field) = variant.fields.get(field.index()) { + if let Some(field) = variant.fields.get(field) { Ok(self.cx.normalize(field.ty(tcx, substs), location)) } else { Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) @@ -875,7 +877,7 @@ struct TypeChecker<'a, 'tcx> { user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, - reported_errors: FxHashSet<(Ty<'tcx>, Span)>, + reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, } @@ -892,7 +894,7 @@ pub(crate) struct MirTypeckResults<'tcx> { pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, pub(crate) opaque_type_values: - VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, + FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, } /// A collection of region constraints that must be satisfied for the @@ -925,7 +927,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, - pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, + pub(crate) universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>, pub(crate) type_tests: Vec<TypeTest<'tcx>>, } @@ -1178,10 +1180,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } Some(l) - if matches!( - body.local_decls[l].local_info, - Some(box LocalInfo::AggregateTemp) - ) => + if matches!(body.local_decls[l].local_info(), LocalInfo::AggregateTemp) => { ConstraintCategory::Usage } @@ -1282,6 +1281,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | StatementKind::Retag { .. } | StatementKind::Coverage(..) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(..) | StatementKind::Nop => {} StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") @@ -1301,7 +1301,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match &term.kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume - | TerminatorKind::Abort + | TerminatorKind::Terminate | TerminatorKind::Return | TerminatorKind::GeneratorDrop | TerminatorKind::Unreachable @@ -1312,24 +1312,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // no checks needed for these } - TerminatorKind::DropAndReplace { place, value, target: _, unwind: _ } => { - let place_ty = place.ty(body, tcx).ty; - let rv_ty = value.ty(body, tcx); - - let locations = term_location.to_locations(); - if let Err(terr) = - self.sub_types(rv_ty, place_ty, locations, ConstraintCategory::Assignment) - { - span_mirbug!( - self, - term, - "bad DropAndReplace ({:?} = {:?}): {:?}", - place_ty, - rv_ty, - terr - ); - } - } TerminatorKind::SwitchInt { discr, .. } => { self.check_operand(discr, term_location); @@ -1357,20 +1339,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { }; let (sig, map) = tcx.replace_late_bound_regions(sig, |br| { use crate::renumber::{BoundRegionInfo, RegionCtxt}; - use rustc_span::Symbol; let region_ctxt_fn = || { let reg_info = match br.kind { - ty::BoundRegionKind::BrAnon(_, Some(span)) => { - BoundRegionInfo::Span(span) - } - ty::BoundRegionKind::BrAnon(..) => { - BoundRegionInfo::Name(Symbol::intern("anon")) - } + ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span), + ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon), ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name), - ty::BoundRegionKind::BrEnv => { - BoundRegionInfo::Name(Symbol::intern("env")) - } + ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env), }; RegionCtxt::LateBound(reg_info) @@ -1603,7 +1578,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, block_data, "resume on non-cleanup block!") } } - TerminatorKind::Abort => { + TerminatorKind::Terminate => { if !is_cleanup { span_mirbug!(self, block_data, "abort on non-cleanup block!") } @@ -1629,26 +1604,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } TerminatorKind::Unreachable => {} TerminatorKind::Drop { target, unwind, .. } - | TerminatorKind::DropAndReplace { target, unwind, .. } - | TerminatorKind::Assert { target, cleanup: unwind, .. } => { + | TerminatorKind::Assert { target, unwind, .. } => { self.assert_iscleanup(body, block_data, target, is_cleanup); - if let Some(unwind) = unwind { - if is_cleanup { - span_mirbug!(self, block_data, "unwind on cleanup block") - } - self.assert_iscleanup(body, block_data, unwind, true); - } + self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); } - TerminatorKind::Call { ref target, cleanup, .. } => { + TerminatorKind::Call { ref target, unwind, .. } => { if let &Some(target) = target { self.assert_iscleanup(body, block_data, target, is_cleanup); } - if let Some(cleanup) = cleanup { - if is_cleanup { - span_mirbug!(self, block_data, "cleanup on cleanup block") - } - self.assert_iscleanup(body, block_data, cleanup, true); - } + self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); } TerminatorKind::FalseEdge { real_target, imaginary_target } => { self.assert_iscleanup(body, block_data, real_target, is_cleanup); @@ -1656,23 +1620,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } 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"); - } - self.assert_iscleanup(body, block_data, unwind, true); - } + self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); } - TerminatorKind::InlineAsm { destination, cleanup, .. } => { + TerminatorKind::InlineAsm { destination, unwind, .. } => { if let Some(target) = destination { self.assert_iscleanup(body, block_data, target, is_cleanup); } - if let Some(cleanup) = cleanup { - if is_cleanup { - span_mirbug!(self, block_data, "cleanup on cleanup block") - } - self.assert_iscleanup(body, block_data, cleanup, true); - } + self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); } } } @@ -1689,6 +1643,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + fn assert_iscleanup_unwind( + &mut self, + body: &Body<'tcx>, + ctxt: &dyn fmt::Debug, + unwind: UnwindAction, + is_cleanup: bool, + ) { + match unwind { + UnwindAction::Cleanup(unwind) => { + if is_cleanup { + span_mirbug!(self, ctxt, "unwind on cleanup block") + } + self.assert_iscleanup(body, ctxt, unwind, true); + } + UnwindAction::Continue => { + if is_cleanup { + span_mirbug!(self, ctxt, "unwind on cleanup block") + } + } + UnwindAction::Unreachable | UnwindAction::Terminate => (), + } + } + fn check_local(&mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) { match body.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Arg => { @@ -1700,7 +1677,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // - maybe we should make that a warning. return; } - LocalKind::Var | LocalKind::Temp => {} + LocalKind::Temp => {} } // When `unsized_fn_params` or `unsized_locals` is enabled, only function calls @@ -1736,7 +1713,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn aggregate_field_ty( &mut self, ak: &AggregateKind<'tcx>, - field_index: usize, + field_index: FieldIdx, location: Location, ) -> Result<Ty<'tcx>, FieldAccessError> { let tcx = self.tcx(); @@ -1753,7 +1730,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } AggregateKind::Closure(_, substs) => { - match substs.as_closure().upvar_tys().nth(field_index) { + match substs.as_closure().upvar_tys().nth(field_index.as_usize()) { Some(ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { field_count: substs.as_closure().upvar_tys().count(), @@ -1764,7 +1741,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // It doesn't make sense to look at a field beyond the prefix; // these require a variant index, and are not initialized in // aggregate rvalues. - match substs.as_generator().prefix_tys().nth(field_index) { + match substs.as_generator().prefix_tys().nth(field_index.as_usize()) { Some(ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { field_count: substs.as_generator().prefix_tys().count(), @@ -2242,6 +2219,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } + CastKind::Transmute => { + span_mirbug!( + self, + rvalue, + "Unexpected CastKind::Transmute, which is not permitted in Analysis MIR", + ); + } } } @@ -2362,7 +2346,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, aggregate_kind: &AggregateKind<'tcx>, - operands: &[Operand<'tcx>], + operands: &IndexSlice<FieldIdx, Operand<'tcx>>, location: Location, ) { let tcx = self.tcx(); @@ -2374,7 +2358,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } - for (i, operand) in operands.iter().enumerate() { + for (i, operand) in operands.iter_enumerated() { let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) { Ok(field_ty) => field_ty, Err(FieldAccessError::OutOfRange { field_count }) => { @@ -2382,8 +2366,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self, rvalue, "accessed field #{} but variant only has {}", - i, - field_count + i.as_u32(), + field_count, ); continue; } @@ -2435,7 +2419,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(all_facts) = all_facts { let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); if let Some(borrow_index) = borrow_set.get_index_of(&location) { - let region_vid = borrow_region.to_region_vid(); + let region_vid = borrow_region.as_var(); all_facts.loan_issued_at.push(( region_vid, borrow_index, @@ -2481,8 +2465,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match base_ty.kind() { ty::Ref(ref_region, _, mutbl) => { constraints.outlives_constraints.push(OutlivesConstraint { - sup: ref_region.to_region_vid(), - sub: borrow_region.to_region_vid(), + sup: ref_region.as_var(), + sub: borrow_region.as_var(), locations: location.to_locations(), span: location.to_locations().span(body), category, @@ -2612,7 +2596,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.implicit_region_bound, self.param_env, location.to_locations(), - DUMMY_SP, // irrelevant; will be overrided. + DUMMY_SP, // irrelevant; will be overridden. ConstraintCategory::Boring, // same as above. &mut self.borrowck_context.constraints, ) |