use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::lang_items::{CoerceUnsizedTraitLangItem, CopyTraitLangItem, SizedTraitLangItem};
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
use rustc_middle::ty::{
- self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
- TyCtxt, UserType, UserTypeAnnotationIndex,
+ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef,
+ ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations};
+use crate::dataflow::impls::MaybeInitializedPlaces;
use crate::dataflow::move_paths::MoveData;
-use crate::dataflow::MaybeInitializedPlaces;
use crate::dataflow::ResultsCursor;
-use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
+use crate::transform::{
+ check_consts::ConstCx,
+ promote_consts::should_suggest_const_in_array_repeat_expressions_attribute,
+};
use crate::borrow_check::{
borrow_set::BorrowSet,
///
/// - `infcx` -- inference context to use
/// - `param_env` -- parameter environment to use for trait solving
-/// - `mir` -- MIR to type-check
-/// - `mir_def_id` -- DefId from which the MIR is derived (must be local)
-/// - `region_bound_pairs` -- the implied outlives obligations between type parameters
-/// and lifetimes (e.g., `&'a T` implies `T: 'a`)
-/// - `implicit_region_bound` -- a region which all generic parameters are assumed
-/// to outlive; should represent the fn body
-/// - `input_tys` -- fully liberated, but **not** normalized, expected types of the arguments;
-/// the types of the input parameters found in the MIR itself will be equated with these
-/// - `output_ty` -- fully liberated, but **not** normalized, expected return type;
-/// the type for the RETURN_PLACE will be equated with this
-/// - `liveness` -- results of a liveness computation on the MIR; used to create liveness
-/// constraints for the regions in the types of variables
+/// - `body` -- MIR body to type-check
+/// - `promoted` -- map of promoted constants within `body`
+/// - `mir_def_id` -- `LocalDefId` from which the MIR is derived
+/// - `universal_regions` -- the universal regions from `body`s function signature
+/// - `location_table` -- MIR location map of `body`
+/// - `borrow_set` -- information about borrows occurring in `body`
+/// - `all_facts` -- when using Polonius, this is the generated set of Polonius facts
/// - `flow_inits` -- results of a maybe-init dataflow analysis
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
+/// - `elements` -- MIR region map
pub(crate) fn type_check<'mir, 'tcx>(
infcx: &InferCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
- body: ReadOnlyBodyAndCache<'_, 'tcx>,
- promoted: &IndexVec<Promoted, ReadOnlyBodyAndCache<'_, 'tcx>>,
- mir_def_id: DefId,
+ body: &Body<'tcx>,
+ promoted: &IndexVec<Promoted, Body<'tcx>>,
+ mir_def_id: LocalDefId,
universal_regions: &Rc<UniversalRegions<'tcx>>,
location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>,
fn type_check_internal<'a, 'tcx, R>(
infcx: &'a InferCtxt<'a, 'tcx>,
- mir_def_id: DefId,
+ mir_def_id: LocalDefId,
param_env: ty::ParamEnv<'tcx>,
- body: ReadOnlyBodyAndCache<'a, 'tcx>,
- promoted: &'a IndexVec<Promoted, ReadOnlyBodyAndCache<'_, 'tcx>>,
+ body: &'a Body<'tcx>,
+ promoted: &'a IndexVec<Promoted, Body<'tcx>>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
) -> R {
let mut checker = TypeChecker::new(
infcx,
- *body,
+ body,
mir_def_id,
param_env,
region_bound_pairs,
universal_region_relations,
);
let errors_reported = {
- let mut verifier = TypeVerifier::new(&mut checker, *body, promoted);
+ let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
verifier.visit_body(&body);
verifier.errors_reported
};
struct TypeVerifier<'a, 'b, 'tcx> {
cx: &'a mut TypeChecker<'b, 'tcx>,
body: &'b Body<'tcx>,
- promoted: &'b IndexVec<Promoted, ReadOnlyBodyAndCache<'b, 'tcx>>,
+ promoted: &'b IndexVec<Promoted, Body<'tcx>>,
last_span: Span,
- mir_def_id: DefId,
+ mir_def_id: LocalDefId,
errors_reported: bool,
}
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>,
+ promoted: &Body<'tcx>,
ty,
san_ty| {
if let Err(terr) = verifier.cx.eq_types(
};
if !self.errors_reported {
- let promoted_body = self.promoted[promoted];
+ 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);
+ check_err(self, promoted_body, ty, promoted_ty);
}
} else {
if let Err(terr) = self.cx.fully_perform_op(
self.super_local_decl(local, local_decl);
self.sanitize_type(local_decl, local_decl.ty);
- for (user_ty, span) in local_decl.user_ty.projections_and_spans() {
- let ty = if !local_decl.is_nonref_binding() {
- // If we have a binding of the form `let ref x: T = ..` then remove the outermost
- // reference so we can check the type annotation for the remaining type.
- if let ty::Ref(_, rty, _) = local_decl.ty.kind {
- rty
+ if let Some(user_ty) = &local_decl.user_ty {
+ for (user_ty, span) in user_ty.projections_and_spans() {
+ let ty = if !local_decl.is_nonref_binding() {
+ // If we have a binding of the form `let ref x: T = ..`
+ // then remove the outermost reference so we can check the
+ // type annotation for the remaining type.
+ if let ty::Ref(_, rty, _) = local_decl.ty.kind {
+ rty
+ } else {
+ bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
+ }
} else {
- bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
- }
- } else {
- local_decl.ty
- };
+ local_decl.ty
+ };
- if let Err(terr) = self.cx.relate_type_and_user_type(
- ty,
- ty::Variance::Invariant,
- user_ty,
- Locations::All(*span),
- ConstraintCategory::TypeAnnotation,
- ) {
- span_mirbug!(
- self,
- local,
- "bad user type on variable {:?}: {:?} != {:?} ({:?})",
- local,
- local_decl.ty,
- local_decl.user_ty,
- terr,
- );
+ if let Err(terr) = self.cx.relate_type_and_user_type(
+ ty,
+ ty::Variance::Invariant,
+ user_ty,
+ Locations::All(*span),
+ ConstraintCategory::TypeAnnotation,
+ ) {
+ span_mirbug!(
+ self,
+ local,
+ "bad user type on variable {:?}: {:?} != {:?} ({:?})",
+ local,
+ local_decl.ty,
+ local_decl.user_ty,
+ terr,
+ );
+ }
}
}
}
fn new(
cx: &'a mut TypeChecker<'b, 'tcx>,
body: &'b Body<'tcx>,
- promoted: &'b IndexVec<Promoted, ReadOnlyBodyAndCache<'b, 'tcx>>,
+ promoted: &'b IndexVec<Promoted, Body<'tcx>>,
) -> Self {
TypeVerifier {
body,
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let tcx = self.tcx();
let trait_ref = ty::TraitRef {
- def_id: tcx.lang_items().copy_trait().unwrap(),
+ def_id: tcx.require_lang_item(CopyTraitLangItem, Some(self.last_span)),
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
};
place_ty
}
- fn sanitize_promoted(
- &mut self,
- promoted_body: ReadOnlyBodyAndCache<'b, 'tcx>,
- location: Location,
- ) {
+ fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) {
// Determine the constraints from the promoted MIR by running the type
// checker on the promoted MIR, then transfer the constraints back to
// the main MIR, changing the locations to the provided location.
- let parent_body = mem::replace(&mut self.body, *promoted_body);
+ let parent_body = mem::replace(&mut self.body, promoted_body);
// Use new sets of constraints and closure bounds so that we can
// modify their locations.
fn sanitize_projection(
&mut self,
base: PlaceTy<'tcx>,
- pi: &PlaceElem<'tcx>,
+ pi: PlaceElem<'tcx>,
place: &Place<'tcx>,
location: Location,
) -> PlaceTy<'tcx> {
debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, place);
let tcx = self.tcx();
let base_ty = base.ty;
- match *pi {
+ match pi {
ProjectionElem::Deref => {
let deref_ty = base_ty.builtin_deref(true);
PlaceTy::from_ty(deref_ty.map(|t| t.ty).unwrap_or_else(|| {
/// User type annotations are shared between the main MIR and the MIR of
/// all of the promoted items.
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
- mir_def_id: DefId,
+ mir_def_id: LocalDefId,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
fn new(
infcx: &'a InferCtxt<'a, 'tcx>,
body: &'a Body<'tcx>,
- mir_def_id: DefId,
+ mir_def_id: LocalDefId,
param_env: ty::ParamEnv<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
}
self.prove_predicate(
- ty::Predicate::WellFormed(inferred_ty),
+ ty::PredicateKind::WellFormed(inferred_ty).to_predicate(self.tcx()),
Locations::All(span),
ConstraintCategory::TypeAnnotation,
);
// When you have `let x: impl Foo = ...` in a closure,
// the resulting inferend values are stored with the
// def-id of the base function.
- let parent_def_id = self.tcx().closure_base_def_id(self.mir_def_id);
+ let parent_def_id = self.tcx().closure_base_def_id(self.mir_def_id.to_def_id());
return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
} else {
return Err(terr);
let tcx = infcx.tcx;
let param_env = self.param_env;
let body = self.body;
- let concrete_opaque_types = &tcx.typeck_tables_of(anon_owner_def_id).concrete_opaque_types;
+ let concrete_opaque_types =
+ &tcx.typeck_tables_of(anon_owner_def_id.expect_local()).concrete_opaque_types;
let mut opaque_type_values = Vec::new();
debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id);
obligations.obligations.push(traits::Obligation::new(
ObligationCause::dummy(),
param_env,
- ty::Predicate::WellFormed(revealed_ty),
+ ty::PredicateKind::WellFormed(revealed_ty).to_predicate(infcx.tcx),
));
obligations.add(
infcx
self.infcx.tcx
}
- fn check_stmt(
- &mut self,
- body: ReadOnlyBodyAndCache<'_, 'tcx>,
- stmt: &Statement<'tcx>,
- location: Location,
- ) {
+ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
debug!("check_stmt: {:?}", stmt);
let tcx = self.tcx();
match stmt.kind {
_ => ConstraintCategory::Assignment,
};
- let place_ty = place.ty(*body, tcx).ty;
+ let place_ty = place.ty(body, tcx).ty;
let place_ty = self.normalize(place_ty, location);
- let rv_ty = rv.ty(*body, tcx);
+ let rv_ty = rv.ty(body, tcx);
let rv_ty = self.normalize(rv_ty, location);
if let Err(terr) =
self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
self.check_rvalue(body, rv, location);
if !self.tcx().features().unsized_locals {
let trait_ref = ty::TraitRef {
- def_id: tcx.lang_items().sized_trait().unwrap(),
+ def_id: tcx.require_lang_item(SizedTraitLangItem, Some(self.last_span)),
substs: tcx.mk_substs_trait(place_ty, &[]),
};
self.prove_trait_ref(
}
}
StatementKind::SetDiscriminant { ref place, variant_index } => {
- let place_type = place.ty(*body, tcx).ty;
+ 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) => {
- let place_ty = place.ty(*body, tcx).ty;
+ let place_ty = place.ty(body, tcx).ty;
if let Err(terr) = self.relate_type_and_user_type(
place_ty,
variance,
| TerminatorKind::Unreachable
| TerminatorKind::Drop { .. }
| TerminatorKind::FalseEdges { .. }
- | TerminatorKind::FalseUnwind { .. } => {
+ | TerminatorKind::FalseUnwind { .. }
+ | TerminatorKind::InlineAsm { .. } => {
// no checks needed for these
}
self.check_call_dest(body, term, &sig, destination, term_location);
self.prove_predicates(
- sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
+ sig.inputs_and_output.iter().map(|ty| ty::PredicateKind::WellFormed(ty)),
term_location.to_locations(),
ConstraintCategory::Boring,
);
self.assert_iscleanup(body, block_data, unwind, true);
}
}
+ TerminatorKind::InlineAsm { ref destination, .. } => {
+ if let &Some(target) = destination {
+ self.assert_iscleanup(body, block_data, target, is_cleanup);
+ }
+ }
}
}
}
}
- fn check_rvalue(
- &mut self,
- body: ReadOnlyBodyAndCache<'_, 'tcx>,
- rvalue: &Rvalue<'tcx>,
- location: Location,
- ) {
+ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
let tcx = self.tcx();
match rvalue {
// 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);
+ let ty = operand.ty(body, tcx);
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
+ let ccx = ConstCx::new_with_param_env(
+ tcx,
+ self.mir_def_id,
+ body,
+ self.param_env,
+ );
// 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,
+ &ccx, operand,
);
debug!("check_rvalue: should_suggest={:?}", should_suggest);
&traits::Obligation::new(
ObligationCause::new(
span,
- self.tcx()
- .hir()
- .local_def_id_to_hir_id(self.mir_def_id.expect_local()),
+ self.tcx().hir().local_def_id_to_hir_id(self.mir_def_id),
traits::ObligationCauseCode::RepeatVec(should_suggest),
),
self.param_env,
- ty::Predicate::Trait(
+ ty::PredicateKind::Trait(
ty::Binder::bind(ty::TraitPredicate {
trait_ref: ty::TraitRef::new(
- self.tcx().lang_items().copy_trait().unwrap(),
+ self.tcx().require_lang_item(
+ CopyTraitLangItem,
+ Some(self.last_span),
+ ),
tcx.mk_substs_trait(ty, &[]),
),
}),
hir::Constness::NotConst,
- ),
+ )
+ .to_predicate(self.tcx()),
),
&traits::SelectionError::Unimplemented,
false,
}
let trait_ref = ty::TraitRef {
- def_id: tcx.lang_items().sized_trait().unwrap(),
+ def_id: tcx.require_lang_item(SizedTraitLangItem, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
};
Rvalue::Cast(cast_kind, op, ty) => {
match cast_kind {
CastKind::Pointer(PointerCast::ReifyFnPointer) => {
- let fn_sig = op.ty(*body, tcx).fn_sig(tcx);
+ let fn_sig = op.ty(body, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
// `foo::<'a, 'b>`, where `foo` is the path to a
}
CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
- let sig = match op.ty(*body, tcx).kind {
+ let sig = match op.ty(body, tcx).kind {
ty::Closure(_, substs) => substs.as_closure().sig(),
_ => bug!(),
};
- let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);
+ let ty_fn_ptr_from = tcx.mk_fn_ptr(tcx.signature_unclosure(sig, *unsafety));
if let Err(terr) = self.eq_types(
ty_fn_ptr_from,
}
CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
- let fn_sig = op.ty(*body, tcx).fn_sig(tcx);
+ let fn_sig = op.ty(body, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
// `foo::<'a, 'b>`, where `foo` is the path to a
CastKind::Pointer(PointerCast::Unsize) => {
let &ty = ty;
let trait_ref = ty::TraitRef {
- def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
- substs: tcx.mk_substs_trait(op.ty(*body, tcx), &[ty.into()]),
+ def_id: tcx.require_lang_item(
+ CoerceUnsizedTraitLangItem,
+ Some(self.last_span),
+ ),
+ substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
};
self.prove_trait_ref(
}
CastKind::Pointer(PointerCast::MutToConstPointer) => {
- let ty_from = match op.ty(*body, tcx).kind {
+ let ty_from = match op.ty(body, tcx).kind {
ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
mutbl: hir::Mutability::Mut,
}
CastKind::Pointer(PointerCast::ArrayToPointer) => {
- let ty_from = op.ty(*body, tcx);
+ let ty_from = op.ty(body, tcx);
let opt_ty_elem = match ty_from.kind {
ty::RawPtr(ty::TypeAndMut {
}
CastKind::Misc => {
- let ty_from = op.ty(*body, tcx);
+ let ty_from = op.ty(body, tcx);
let cast_ty_from = CastTy::from_ty(ty_from);
let cast_ty_to = CastTy::from_ty(ty);
match (cast_ty_from, cast_ty_to) {
left,
right,
) => {
- 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,
- });
- self.sub_types(
- common_ty,
- ty_left,
- location.to_locations(),
- 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,
- ) {
- span_mirbug!(
- self,
- rvalue,
- "unexpected comparison types {:?} and {:?} yields {:?}",
+ let ty_left = left.ty(body, tcx);
+ match ty_left.kind {
+ // Types with regions are comparable if they have a common super-type.
+ ty::RawPtr(_) | ty::FnPtr(_) => {
+ 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,
+ });
+ self.relate_types(
+ common_ty,
+ ty::Variance::Contravariant,
ty_left,
- ty_right,
- terr
+ location.to_locations(),
+ ConstraintCategory::Boring,
)
+ .unwrap_or_else(|err| {
+ bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
+ });
+ if let Err(terr) = self.relate_types(
+ common_ty,
+ ty::Variance::Contravariant,
+ ty_right,
+ location.to_locations(),
+ ConstraintCategory::Boring,
+ ) {
+ span_mirbug!(
+ self,
+ rvalue,
+ "unexpected comparison types {:?} and {:?} yields {:?}",
+ ty_left,
+ ty_right,
+ terr
+ )
+ }
}
+ // For types with no regions we can just check that the
+ // both operands have the same type.
+ ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_)
+ if ty_left == right.ty(body, tcx) => {}
+ // Other types are compared by trait methods, not by
+ // `Rvalue::BinaryOp`.
+ _ => span_mirbug!(
+ self,
+ rvalue,
+ "unexpected comparison types {:?} and {:?}",
+ ty_left,
+ right.ty(body, tcx)
+ ),
}
}
Rvalue::AddressOf(..)
+ | Rvalue::ThreadLocalRef(..)
| Rvalue::Use(..)
| Rvalue::Len(..)
| Rvalue::BinaryOp(..)
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationIndex> {
match rvalue {
Rvalue::Use(_)
+ | Rvalue::ThreadLocalRef(_)
| Rvalue::Repeat(..)
| Rvalue::Ref(..)
| Rvalue::AddressOf(..)
// clauses on the struct.
AggregateKind::Closure(def_id, substs)
| AggregateKind::Generator(def_id, substs, _) => {
- self.prove_closure_bounds(tcx, *def_id, substs, location)
+ self.prove_closure_bounds(tcx, def_id.expect_local(), substs, location)
}
AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
fn prove_closure_bounds(
&mut self,
tcx: TyCtxt<'tcx>,
- def_id: DefId,
+ def_id: LocalDefId,
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, substs),
+ 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
category: ConstraintCategory,
) {
self.prove_predicates(
- Some(ty::Predicate::Trait(
+ Some(ty::PredicateKind::Trait(
trait_ref.to_poly_trait_ref().to_poly_trait_predicate(),
hir::Constness::NotConst,
)),
fn prove_predicates(
&mut self,
- predicates: impl IntoIterator<Item = ty::Predicate<'tcx>>,
+ predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
locations: Locations,
category: ConstraintCategory,
) {
for predicate in predicates {
+ let predicate = predicate.to_predicate(self.tcx());
debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
self.prove_predicate(predicate, locations, category);
})
}
- fn typeck_mir(&mut self, body: ReadOnlyBodyAndCache<'_, 'tcx>) {
+ fn typeck_mir(&mut self, body: &Body<'tcx>) {
self.last_span = body.span;
debug!("run_on_mir: {:?}", body.span);