summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/type_check
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/type_check')
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs13
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs82
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs5
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs7
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/polonius.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs200
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs17
7 files changed, 129 insertions, 199 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index a581726a1..3617bf58b 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -88,12 +88,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
category: ConstraintCategory<'tcx>,
) {
self.prove_predicate(
- ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
- }))
- .to_predicate(self.tcx()),
+ }))),
locations,
category,
);
@@ -122,14 +121,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
pub(super) fn prove_predicates(
&mut self,
- predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
+ predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>,
locations: Locations,
category: ConstraintCategory<'tcx>,
) {
for predicate in predicates {
- let predicate = predicate.to_predicate(self.tcx());
- debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
-
self.prove_predicate(predicate, locations, category);
}
}
@@ -137,11 +133,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
pub(super) fn prove_predicate(
&mut self,
- predicate: ty::Predicate<'tcx>,
+ predicate: impl ToPredicate<'tcx> + std::fmt::Debug,
locations: Locations,
category: ConstraintCategory<'tcx>,
) {
let param_env = self.param_env;
+ let predicate = predicate.to_predicate(self.tcx());
self.fully_perform_op(
locations,
category,
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index d5bfc2f52..ce7f857e2 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -1,10 +1,10 @@
-use rustc_infer::infer::canonical::QueryOutlivesConstraint;
+use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
-use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, TyCtxt};
@@ -38,6 +38,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
locations: Locations,
span: Span,
category: ConstraintCategory<'tcx>,
+ from_closure: bool,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
}
@@ -64,6 +65,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
span,
category,
constraints,
+ from_closure: false,
}
}
@@ -81,12 +83,62 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
self.constraints.member_constraints = tmp;
- for query_constraint in outlives {
- self.convert(query_constraint);
+ for (predicate, constraint_category) in outlives {
+ // At the moment, we never generate any "higher-ranked"
+ // region constraints like `for<'a> 'a: 'b`. At some point
+ // when we move to universes, we will, and this assertion
+ // will start to fail.
+ let predicate = predicate.no_bound_vars().unwrap_or_else(|| {
+ bug!("query_constraint {:?} contained bound vars", predicate,);
+ });
+
+ self.convert(predicate, *constraint_category);
}
}
- fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) {
+ /// Given an instance of the closure type, this method instantiates the "extra" requirements
+ /// that we computed for the closure. This has the effect of adding new outlives obligations
+ /// to existing region variables in `closure_substs`.
+ #[instrument(skip(self), level = "debug")]
+ pub fn apply_closure_requirements(
+ &mut self,
+ closure_requirements: &ClosureRegionRequirements<'tcx>,
+ closure_def_id: DefId,
+ closure_substs: ty::SubstsRef<'tcx>,
+ ) {
+ // Extract the values of the free regions in `closure_substs`
+ // into a vector. These are the regions that we will be
+ // relating to one another.
+ let closure_mapping = &UniversalRegions::closure_mapping(
+ self.tcx,
+ closure_substs,
+ closure_requirements.num_external_vids,
+ closure_def_id.expect_local(),
+ );
+ debug!(?closure_mapping);
+
+ // Create the predicates.
+ let backup = (self.category, self.span, self.from_closure);
+ self.from_closure = true;
+ for outlives_requirement in &closure_requirements.outlives_requirements {
+ let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
+ let subject = match outlives_requirement.subject {
+ ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
+ ClosureOutlivesSubject::Ty(ty) => ty.into(),
+ };
+
+ self.category = outlives_requirement.category;
+ self.span = outlives_requirement.blame_span;
+ self.convert(ty::OutlivesPredicate(subject, outlived_region), self.category);
+ }
+ (self.category, self.span, self.from_closure) = backup;
+ }
+
+ fn convert(
+ &mut self,
+ predicate: ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
+ constraint_category: ConstraintCategory<'tcx>,
+ ) {
debug!("generate: constraints at: {:#?}", self.locations);
// Extract out various useful fields we'll need below.
@@ -94,17 +146,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
tcx, region_bound_pairs, implicit_region_bound, param_env, ..
} = *self;
- // At the moment, we never generate any "higher-ranked"
- // region constraints like `for<'a> 'a: 'b`. At some point
- // when we move to universes, we will, and this assertion
- // will start to fail.
- let ty::OutlivesPredicate(k1, r2) =
- query_constraint.0.no_bound_vars().unwrap_or_else(|| {
- bug!("query_constraint {:?} contained bound vars", query_constraint,);
- });
-
- let constraint_category = query_constraint.1;
-
+ let ty::OutlivesPredicate(k1, r2) = predicate;
match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
let r1_vid = self.to_region_vid(r1);
@@ -127,10 +169,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
.type_must_outlive(origin, t1, r2, constraint_category);
}
- GenericArgKind::Const(_) => {
- // Consts cannot outlive one another, so we
- // don't need to handle any relations here.
- }
+ GenericArgKind::Const(_) => unreachable!(),
}
}
@@ -160,7 +199,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
verify_bound: VerifyBound<'tcx>,
) -> TypeTest<'tcx> {
let lower_bound = self.to_region_vid(region);
- TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound }
+ TypeTest { generic_kind, lower_bound, span: self.span, verify_bound }
}
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
@@ -188,6 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
sub,
sup,
variance_info: ty::VarianceDiagInfo::default(),
+ from_closure: self.from_closure,
});
}
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 029095926..14cfc3613 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -247,12 +247,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
.and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx)
.unwrap_or_else(|_| {
- self.infcx
+ let reported = self
+ .infcx
.tcx
.sess
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
TypeOpOutput {
- output: self.infcx.tcx.ty_error(),
+ output: self.infcx.tcx.ty_error_with_guaranteed(reported),
constraints: None,
error_info: None,
}
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index a66ddd27d..62c6f9581 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -42,8 +42,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
user_provided_sig = None;
} else {
let typeck_results = self.tcx().typeck(mir_def_id);
- user_provided_sig = typeck_results.user_provided_sigs.get(&mir_def_id.to_def_id()).map(
- |user_provided_poly_sig| {
+ user_provided_sig =
+ typeck_results.user_provided_sigs.get(&mir_def_id).map(|user_provided_poly_sig| {
// Instantiate the canonicalized variables from
// user-provided signature (e.g., the `_` in the code
// above) with fresh variables.
@@ -60,8 +60,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
LateBoundRegionConversionTime::FnCall,
poly_sig,
)
- },
- );
+ });
}
debug!(?normalized_input_tys, ?body.local_decls);
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
index bc76a465e..b344ab46a 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
@@ -121,8 +121,8 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
}
}
-// For every potentially drop()-touched region `region` in `local`'s type
-// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
+/// For every potentially drop()-touched region `region` in `local`'s type
+/// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
local: Local,
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,
);
}
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 4f2dc263b..b2702eafd 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -2,9 +2,8 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_infer::traits::PredicateObligations;
use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::TypeRelation;
-use rustc_middle::ty::{self, Const, Ty};
+use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
use rustc_trait_selection::traits::query::Fallible;
@@ -136,17 +135,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
span: self.locations.span(self.type_checker.body),
category: self.category,
variance_info: info,
+ from_closure: false,
},
);
}
- // We don't have to worry about the equality of consts during borrow checking
- // as consts always have a static lifetime.
- // FIXME(oli-obk): is this really true? We can at least have HKL and with
- // inline consts we may have further lifetimes that may be unsound to treat as
- // 'static.
- fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {}
-
fn normalization() -> NormalizationStrategy {
NormalizationStrategy::Eager
}
@@ -155,10 +148,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
true
}
- fn register_opaque_type_obligations(
- &mut self,
- obligations: PredicateObligations<'tcx>,
- ) -> Result<(), TypeError<'tcx>> {
+ fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
self.type_checker
.fully_perform_op(
self.locations,
@@ -171,6 +161,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
},
)
.unwrap();
- Ok(())
}
}