From 4547b622d8d29df964fa2914213088b148c498fc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:32 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_borrowck/src/type_check/mod.rs | 200 +++++++------------------- 1 file changed, 52 insertions(+), 148 deletions(-) (limited to 'compiler/rustc_borrowck/src/type_check/mod.rs') diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3c1c3ab45..6d4ec6b72 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This pass type-checks the MIR to ensure it is not broken. use std::rc::Rc; @@ -27,12 +29,11 @@ use rustc_middle::mir::AssertKind; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; -use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts}; +use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, - OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, - UserTypeAnnotationIndex, + OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, }; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{Span, DUMMY_SP}; @@ -61,7 +62,7 @@ use crate::{ region_infer::values::{ LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, }, - region_infer::{ClosureRegionRequirementsExt, TypeTest}, + region_infer::TypeTest, type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, universal_regions::{DefiningTy, UniversalRegions}, Upvar, @@ -144,7 +145,6 @@ pub(crate) fn type_check<'mir, 'tcx>( liveness_constraints: LivenessValues::new(elements.clone()), outlives_constraints: OutlivesConstraintSet::default(), member_constraints: MemberConstraintSet::default(), - closure_bounds_mapping: Default::default(), type_tests: Vec::default(), universe_causes: FxHashMap::default(), }; @@ -234,11 +234,11 @@ pub(crate) fn type_check<'mir, 'tcx>( let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); if hidden_type.has_non_region_infer() { - infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.delay_span_bug( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), ); - hidden_type.ty = infcx.tcx.ty_error(); + hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported); } (opaque_type_key, (hidden_type, decl.origin)) @@ -547,10 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let tcx = self.tcx(); - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty.ty, &[]), - }; + let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]); // To have a `Copy` operand, the type `T` of the // value must be `Copy`. Note that we prove that `T: Copy`, @@ -584,8 +581,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { // modify their locations. let all_facts = &mut None; let mut constraints = Default::default(); - let mut type_tests = Default::default(); - let mut closure_bounds = Default::default(); let mut liveness_constraints = LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body))); // Don't try to add borrow_region facts for the promoted MIR @@ -596,11 +591,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { &mut this.cx.borrowck_context.constraints.outlives_constraints, &mut constraints, ); - mem::swap(&mut this.cx.borrowck_context.constraints.type_tests, &mut type_tests); - mem::swap( - &mut this.cx.borrowck_context.constraints.closure_bounds_mapping, - &mut closure_bounds, - ); mem::swap( &mut this.cx.borrowck_context.constraints.liveness_constraints, &mut liveness_constraints, @@ -621,13 +611,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { swap_constraints(self); let locations = location.to_locations(); - - // Use location of promoted const in collected constraints - for type_test in type_tests.iter() { - let mut type_test = type_test.clone(); - type_test.locations = locations; - self.cx.borrowck_context.constraints.type_tests.push(type_test) - } for constraint in constraints.outlives().iter() { let mut constraint = constraint.clone(); constraint.locations = locations; @@ -653,18 +636,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { .add_element(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 - .constraints - .closure_bounds_mapping - .insert(location, combined_bounds_mapping); - assert!(existing.is_none(), "Multiple promoteds/closures at the same location."); - } } fn sanitize_projection( @@ -941,9 +912,6 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, - pub(crate) closure_bounds_mapping: - FxHashMap, Span)>>, - pub(crate) universe_causes: FxHashMap>, pub(crate) type_tests: Vec>, @@ -1097,8 +1065,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } self.prove_predicate( - ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())) - .to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())), Locations::All(span), ConstraintCategory::TypeAnnotation, ); @@ -1222,8 +1189,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) { let tcx = self.tcx(); debug!("stmt kind: {:?}", stmt.kind); - match stmt.kind { - StatementKind::Assign(box (ref place, ref rv)) => { + match &stmt.kind { + StatementKind::Assign(box (place, 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 @@ -1303,10 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_rvalue(body, rv, location); if !self.unsized_feature_enabled() { - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty, &[]), - }; + let trait_ref = + tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]); self.prove_trait_ref( trait_ref, location.to_locations(), @@ -1314,11 +1279,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - StatementKind::AscribeUserType(box (ref place, ref projection), variance) => { + StatementKind::AscribeUserType(box (place, projection), variance) => { let place_ty = place.ty(body, tcx).ty; if let Err(terr) = self.relate_type_and_user_type( place_ty, - variance, + *variance, projection, Locations::All(stmt.source_info.span), ConstraintCategory::TypeAnnotation, @@ -1335,7 +1300,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - StatementKind::Intrinsic(box ref kind) => match kind { + StatementKind::Intrinsic(box kind) => match kind { NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location), NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( stmt.source_info.span, @@ -1363,7 +1328,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) { let tcx = self.tcx(); debug!("terminator kind: {:?}", term.kind); - match term.kind { + match &term.kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume | TerminatorKind::Abort @@ -1377,7 +1342,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // no checks needed for these } - TerminatorKind::DropAndReplace { ref place, ref value, target: _, unwind: _ } => { + TerminatorKind::DropAndReplace { place, value, target: _, unwind: _ } => { let place_ty = place.ty(body, tcx).ty; let rv_ty = value.ty(body, tcx); @@ -1395,13 +1360,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => { + TerminatorKind::SwitchInt { discr, switch_ty, .. } => { self.check_operand(discr, term_location); let discr_ty = discr.ty(body, tcx); if let Err(terr) = self.sub_types( discr_ty, - switch_ty, + *switch_ty, term_location.to_locations(), ConstraintCategory::Assignment, ) { @@ -1419,14 +1384,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // FIXME: check the values } - TerminatorKind::Call { - ref func, - ref args, - ref destination, - from_hir_call, - target, - .. - } => { + TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => { self.check_operand(func, term_location); for arg in args { self.check_operand(arg, term_location); @@ -1466,7 +1424,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Boring, ); let sig = self.normalize(sig, term_location); - self.check_call_dest(body, term, &sig, *destination, target, term_location); + self.check_call_dest(body, term, &sig, *destination, *target, term_location); // The ordinary liveness rules will ensure that all // regions in the type of the callee are live here. We @@ -1484,9 +1442,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .add_element(region_vid, term_location); } - self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call); + self.check_call_inputs(body, term, &sig, args, term_location, *from_hir_call); } - TerminatorKind::Assert { ref cond, ref msg, .. } => { + TerminatorKind::Assert { cond, msg, .. } => { self.check_operand(cond, term_location); let cond_ty = cond.ty(body, tcx); @@ -1494,7 +1452,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); } - if let AssertKind::BoundsCheck { ref len, ref index } = *msg { + if let AssertKind::BoundsCheck { len, index } = msg { if len.ty(body, tcx) != tcx.types.usize { span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) } @@ -1503,7 +1461,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } - TerminatorKind::Yield { ref value, .. } => { + TerminatorKind::Yield { value, .. } => { self.check_operand(value, term_location); let value_ty = value.ty(body, tcx); @@ -1594,10 +1552,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } None => { - if !self - .tcx() - .conservative_is_privately_uninhabited(self.param_env.and(sig.output())) - { + if !sig.output().is_privately_uninhabited(self.tcx(), self.param_env) { span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); } } @@ -1873,6 +1828,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self, body), level = "debug")] fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { let tcx = self.tcx(); + let span = body.source_info(location).span; match rvalue { Rvalue::Aggregate(ak, ops) => { @@ -1896,12 +1852,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Operand::Move(place) => { // Make sure that repeated elements implement `Copy`. - let span = body.source_info(location).span; let ty = place.ty(body, tcx).ty; - let trait_ref = ty::TraitRef::new( - tcx.require_lang_item(LangItem::Copy, Some(span)), - tcx.mk_substs_trait(ty, &[]), - ); + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]); self.prove_trait_ref( trait_ref, @@ -1914,10 +1866,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]); self.prove_trait_ref( trait_ref, @@ -1929,10 +1878,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::ShallowInitBox(operand, ty) => { self.check_operand(operand, location); - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(*ty, &[]), - }; + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]); self.prove_trait_ref( trait_ref, @@ -2029,11 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::Unsize) => { let &ty = ty; - let trait_ref = ty::TraitRef { - def_id: tcx - .require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), - substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]), - }; + let trait_ref = tcx + .at(span) + .mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]); self.prove_trait_ref( trait_ref, @@ -2062,8 +2006,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); let outlives_predicate = - tcx.mk_predicate(Binder::dummy(ty::PredicateKind::TypeOutlives( - ty::OutlivesPredicate(self_ty, *region), + tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause( + ty::Clause::TypeOutlives(ty::OutlivesPredicate(self_ty, *region)), ))); self.prove_predicate( outlives_predicate, @@ -2562,6 +2506,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span: location.to_locations().span(body), category, variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, }); match mutbl { @@ -2636,7 +2581,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // For closures, we have some **extra requirements** we - // // have to check. In particular, in their upvars and // signatures, closures often reference various regions // from the surrounding function -- we call those the @@ -2679,62 +2623,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { substs: SubstsRef<'tcx>, location: Location, ) -> ty::InstantiatedPredicates<'tcx> { - if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements - { - let closure_constraints = QueryRegionConstraints { - outlives: closure_region_requirements.apply_requirements( - tcx, - def_id.to_def_id(), - substs, - ), - - // Presently, closures never propagate member - // constraints to their parents -- they are enforced - // locally. This is largely a non-issue as member - // constraints only come from `-> impl Trait` and - // friends which don't appear (thus far...) in - // closures. - member_constraints: vec![], - }; - - let bounds_mapping = closure_constraints - .outlives - .iter() - .enumerate() - .filter_map(|(idx, constraint)| { - let ty::OutlivesPredicate(k1, r2) = - constraint.0.no_bound_vars().unwrap_or_else(|| { - bug!("query_constraint {:?} contained bound vars", constraint,); - }); - - match k1.unpack() { - GenericArgKind::Lifetime(r1) => { - // constraint is r1: r2 - let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1); - let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2); - let outlives_requirements = - &closure_region_requirements.outlives_requirements[idx]; - Some(( - (r1_vid, r2_vid), - (outlives_requirements.category, outlives_requirements.blame_span), - )) - } - GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, - } - }) - .collect(); - - let existing = self - .borrowck_context - .constraints - .closure_bounds_mapping - .insert(location, bounds_mapping); - assert!(existing.is_none(), "Multiple closures at the same location."); - - self.push_region_constraints( + if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements { + constraint_conversion::ConstraintConversion::new( + self.infcx, + self.borrowck_context.universal_regions, + self.region_bound_pairs, + self.implicit_region_bound, + self.param_env, location.to_locations(), - ConstraintCategory::ClosureBounds, - &closure_constraints, + DUMMY_SP, // irrelevant; will be overrided. + ConstraintCategory::Boring, // same as above. + &mut self.borrowck_context.constraints, + ) + .apply_closure_requirements( + &closure_requirements, + def_id.to_def_id(), + substs, ); } -- cgit v1.2.3