summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/type_check/mod.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /compiler/rustc_borrowck/src/type_check/mod.rs
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/type_check/mod.rs')
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs200
1 files changed, 52 insertions, 148 deletions
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<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>,
-
pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
pub(crate) type_tests: Vec<TypeTest<'tcx>>,
@@ -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,
);
}