use rustc::infer::canonical::QueryRegionConstraint;
use rustc::infer::outlives::env::RegionBoundPairs;
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
/// constraints for the regions in the types of variables
/// - `flow_inits` -- results of a maybe-init dataflow analysis
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
-pub(crate) fn type_check<'gcx, 'tcx>(
- infcx: &InferCtxt<'_, 'gcx, 'tcx>,
- param_env: ty::ParamEnv<'gcx>,
- mir: &Body<'tcx>,
+pub(crate) fn type_check<'tcx>(
+ infcx: &InferCtxt<'_, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ body: &Body<'tcx>,
mir_def_id: DefId,
universal_regions: &Rc<UniversalRegions<'tcx>>,
location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>,
- flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
+ flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
move_data: &MoveData<'tcx>,
elements: &Rc<RegionValueElements>,
) -> MirTypeckResults<'tcx> {
infcx,
mir_def_id,
param_env,
- mir,
+ body,
®ion_bound_pairs,
implicit_region_bound,
&mut borrowck_context,
&universal_region_relations,
|mut cx| {
- cx.equate_inputs_and_outputs(mir, universal_regions, &normalized_inputs_and_output);
- liveness::generate(&mut cx, mir, elements, flow_inits, move_data, location_table);
+ cx.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
+ liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
translate_outlives_facts(cx.borrowck_context);
},
}
}
-fn type_check_internal<'a, 'gcx, 'tcx, R>(
- infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+fn type_check_internal<'a, 'tcx, R>(
+ infcx: &'a InferCtxt<'a, 'tcx>,
mir_def_id: DefId,
- param_env: ty::ParamEnv<'gcx>,
- mir: &'a Body<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ body: &'a Body<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
universal_region_relations: &'a UniversalRegionRelations<'tcx>,
- mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R,
+ mut extra: impl FnMut(&mut TypeChecker<'a, 'tcx>) -> R,
) -> R where {
let mut checker = TypeChecker::new(
infcx,
- mir,
+ body,
mir_def_id,
param_env,
region_bound_pairs,
universal_region_relations,
);
let errors_reported = {
- let mut verifier = TypeVerifier::new(&mut checker, mir);
- verifier.visit_body(mir);
+ let mut verifier = TypeVerifier::new(&mut checker, body);
+ verifier.visit_body(body);
verifier.errors_reported
};
if !errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
- checker.typeck_mir(mir);
+ checker.typeck_mir(body);
}
extra(&mut checker)
}
}
-fn mirbug(tcx: TyCtxt<'_, '_, '_>, span: Span, msg: &str) {
+fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: &str) {
// We sometimes see MIR failures (notably predicate failures) due to
// the fact that we check rvalue sized predicates here. So use `delay_span_bug`
// to avoid reporting bugs in those cases.
/// The sanitize_XYZ methods here take an MIR object and compute its
/// type, calling `span_mirbug` and returning an error type if there
/// is a problem.
-struct TypeVerifier<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
- cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>,
- mir: &'b Body<'tcx>,
+struct TypeVerifier<'a, 'b: 'a, 'tcx: 'b> {
+ cx: &'a mut TypeChecker<'b, 'tcx>,
+ body: &'b Body<'tcx>,
last_span: Span,
mir_def_id: DefId,
errors_reported: bool,
}
-impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
+impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
fn visit_span(&mut self, span: &Span) {
if !span.is_dummy() {
self.last_span = *span;
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
self.super_rvalue(rvalue, location);
- let rval_ty = rvalue.ty(self.mir, self.tcx());
+ let rval_ty = rvalue.ty(self.body, self.tcx());
self.sanitize_type(rvalue, rval_ty);
}
}
}
- fn visit_body(&mut self, mir: &Body<'tcx>) {
- self.sanitize_type(&"return type", mir.return_ty());
- for local_decl in &mir.local_decls {
+ fn visit_body(&mut self, body: &Body<'tcx>) {
+ self.sanitize_type(&"return type", body.return_ty());
+ for local_decl in &body.local_decls {
self.sanitize_type(local_decl, local_decl.ty);
}
if self.errors_reported {
return;
}
- self.super_body(mir);
+ self.super_body(body);
}
}
-impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
- fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'b Body<'tcx>) -> Self {
+impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
+ fn new(cx: &'a mut TypeChecker<'b, 'tcx>, body: &'b Body<'tcx>) -> Self {
TypeVerifier {
- mir,
+ body,
mir_def_id: cx.mir_def_id,
cx,
- last_span: mir.span,
+ last_span: body.span,
errors_reported: false,
}
}
- fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
self.cx.infcx.tcx
}
place.iterate(|place_base, place_projection| {
let mut place_ty = match place_base {
PlaceBase::Local(index) =>
- PlaceTy::from_ty(self.mir.local_decls[*index].ty),
+ PlaceTy::from_ty(self.body.local_decls[*index].ty),
PlaceBase::Static(box Static { kind, ty: sty }) => {
let sty = self.sanitize_type(place, sty);
let check_err =
- |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
+ |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
place: &Place<'tcx>,
ty,
sty| {
match kind {
StaticKind::Promoted(promoted) => {
if !self.errors_reported {
- let promoted_mir = &self.mir.promoted[*promoted];
- self.sanitize_promoted(promoted_mir, location);
+ let promoted_body = &self.body.promoted[*promoted];
+ self.sanitize_promoted(promoted_body, location);
- let promoted_ty = promoted_mir.return_ty();
+ let promoted_ty = promoted_body.return_ty();
check_err(self, place, promoted_ty, sty);
}
}
})
}
- fn sanitize_promoted(&mut self, promoted_mir: &'b Body<'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_mir = mem::replace(&mut self.mir, promoted_mir);
+ let parent_body = mem::replace(&mut self.body, promoted_body);
let all_facts = &mut None;
let mut constraints = Default::default();
&mut closure_bounds
);
- self.visit_body(promoted_mir);
+ self.visit_body(promoted_body);
if !self.errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
- self.cx.typeck_mir(promoted_mir);
+ self.cx.typeck_mir(promoted_body);
}
- self.mir = parent_mir;
+ self.body = parent_body;
// Merge the outlives constraints back in, at the given location.
mem::swap(self.cx.borrowck_context.all_facts, all_facts);
mem::swap(
)
}
ProjectionElem::Index(i) => {
- let index_ty = Place::Base(PlaceBase::Local(i)).ty(self.mir, tcx).ty;
+ let index_ty = Place::Base(PlaceBase::Local(i)).ty(self.body, tcx).ty;
if index_ty != tcx.types.usize {
PlaceTy::from_ty(
span_mirbug_and_err!(self, i, "index by non-usize {:?}", i),
/// constraints needed for it to be valid and well-typed. Along the
/// way, it accrues region constraints -- these can later be used by
/// NLL region checking.
-struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
- infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
- param_env: ty::ParamEnv<'gcx>,
+struct TypeChecker<'a, 'tcx: 'a> {
+ infcx: &'a InferCtxt<'a, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
last_span: Span,
/// User type annotations are shared between the main MIR and the MIR of
/// all of the promoted items.
impl MirTypeckRegionConstraints<'tcx> {
fn placeholder_region(
&mut self,
- infcx: &InferCtxt<'_, '_, 'tcx>,
+ infcx: &InferCtxt<'_, 'tcx>,
placeholder: ty::PlaceholderRegion,
) -> ty::Region<'tcx> {
let placeholder_index = self.placeholder_indices.insert(placeholder);
}
/// Gets a span representing the location.
- pub fn span(&self, mir: &Body<'_>) -> Span {
+ pub fn span(&self, body: &Body<'_>) -> Span {
match self {
Locations::All(span) => *span,
- Locations::Single(l) => mir.source_info(*l).span,
+ Locations::Single(l) => body.source_info(*l).span,
}
}
}
-impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn new(
- infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
- mir: &'a Body<'tcx>,
+ infcx: &'a InferCtxt<'a, 'tcx>,
+ body: &'a Body<'tcx>,
mir_def_id: DefId,
- param_env: ty::ParamEnv<'gcx>,
+ param_env: ty::ParamEnv<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
infcx,
last_span: DUMMY_SP,
mir_def_id,
- user_type_annotations: &mir.user_type_annotations,
+ user_type_annotations: &body.user_type_annotations,
param_env,
region_bound_pairs,
implicit_region_bound,
&mut self,
locations: Locations,
category: ConstraintCategory,
- op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>,
+ op: impl type_op::TypeOp<'tcx, Output = R>,
) -> Fallible<R> {
let (r, opt_data) = op.fully_perform(self.infcx)?;
Ok(())
}
- fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
- fn check_stmt(&mut self, mir: &Body<'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::Return
},
Place::Base(PlaceBase::Local(l))
- if !mir.local_decls[l].is_user_variable.is_some() => {
+ if !body.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring
}
_ => ConstraintCategory::Assignment,
};
- let place_ty = place.ty(mir, tcx).ty;
- let rv_ty = rv.ty(mir, tcx);
+ let place_ty = place.ty(body, tcx).ty;
+ let rv_ty = rv.ty(body, tcx);
if let Err(terr) =
self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
{
}
}
- self.check_rvalue(mir, rv, location);
+ 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(),
ref place,
variant_index,
} => {
- let place_type = place.ty(mir, tcx).ty;
+ let place_type = place.ty(body, tcx).ty;
let adt = match place_type.sty {
ty::Adt(adt, _) if adt.is_enum() => adt,
_ => {
};
}
StatementKind::AscribeUserType(ref place, variance, box ref projection) => {
- let place_ty = place.ty(mir, tcx).ty;
+ let place_ty = place.ty(body, tcx).ty;
if let Err(terr) = self.relate_type_and_user_type(
place_ty,
variance,
fn check_terminator(
&mut self,
- mir: &Body<'tcx>,
+ body: &Body<'tcx>,
term: &Terminator<'tcx>,
term_location: Location,
) {
target: _,
unwind: _,
} => {
- let place_ty = location.ty(mir, tcx).ty;
- let rv_ty = value.ty(mir, tcx);
+ let place_ty = location.ty(body, tcx).ty;
+ let rv_ty = value.ty(body, tcx);
let locations = term_location.to_locations();
if let Err(terr) =
switch_ty,
..
} => {
- let discr_ty = discr.ty(mir, tcx);
+ let discr_ty = discr.ty(body, tcx);
if let Err(terr) = self.sub_types(
discr_ty,
switch_ty,
from_hir_call,
..
} => {
- let func_ty = func.ty(mir, tcx);
+ let func_ty = func.ty(body, tcx);
debug!("check_terminator: call, func_ty={:?}", func_ty);
let sig = match func_ty.sty {
ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx),
&sig,
);
let sig = self.normalize(sig, term_location);
- self.check_call_dest(mir, term, &sig, destination, term_location);
+ self.check_call_dest(body, term, &sig, destination, term_location);
self.prove_predicates(
sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
.add_element(region_vid, term_location);
}
- self.check_call_inputs(mir, 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, ..
} => {
- let cond_ty = cond.ty(mir, tcx);
+ let cond_ty = cond.ty(body, tcx);
if cond_ty != tcx.types.bool {
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
}
if let BoundsCheck { ref len, ref index } = *msg {
- if len.ty(mir, tcx) != tcx.types.usize {
+ if len.ty(body, tcx) != tcx.types.usize {
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
}
- if index.ty(mir, tcx) != tcx.types.usize {
+ if index.ty(body, tcx) != tcx.types.usize {
span_mirbug!(self, index, "bounds-check index non-usize {:?}", index)
}
}
}
TerminatorKind::Yield { ref value, .. } => {
- let value_ty = value.ty(mir, tcx);
- match mir.yield_ty {
+ let value_ty = value.ty(body, tcx);
+ match body.yield_ty {
None => span_mirbug!(self, term, "yield in non-generator"),
Some(ty) => {
if let Err(terr) = self.sub_types(
fn check_call_dest(
&mut self,
- mir: &Body<'tcx>,
+ body: &Body<'tcx>,
term: &Terminator<'tcx>,
sig: &ty::FnSig<'tcx>,
destination: &Option<(Place<'tcx>, BasicBlock)>,
let tcx = self.tcx();
match *destination {
Some((ref dest, _target_block)) => {
- let dest_ty = dest.ty(mir, tcx).ty;
+ let dest_ty = dest.ty(body, tcx).ty;
let category = match *dest {
Place::Base(PlaceBase::Local(RETURN_PLACE)) => {
if let BorrowCheckContext {
}
}
Place::Base(PlaceBase::Local(l))
- if !mir.local_decls[l].is_user_variable.is_some() => {
+ if !body.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring
}
_ => ConstraintCategory::Assignment,
fn check_call_inputs(
&mut self,
- mir: &Body<'tcx>,
+ body: &Body<'tcx>,
term: &Terminator<'tcx>,
sig: &ty::FnSig<'tcx>,
args: &[Operand<'tcx>],
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
}
for (n, (fn_arg, op_arg)) in inputs.iter().zip(args).enumerate() {
- let op_arg_ty = op_arg.ty(mir, self.tcx());
+ let op_arg_ty = op_arg.ty(body, self.tcx());
let category = if from_hir_call {
ConstraintCategory::CallArgument
} else {
}
}
- fn check_iscleanup(&mut self, mir: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) {
+ fn check_iscleanup(&mut self, body: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) {
let is_cleanup = block_data.is_cleanup;
self.last_span = block_data.terminator().source_info.span;
match block_data.terminator().kind {
TerminatorKind::Goto { target } => {
- self.assert_iscleanup(mir, block_data, target, is_cleanup)
+ self.assert_iscleanup(body, block_data, target, is_cleanup)
}
TerminatorKind::SwitchInt { ref targets, .. } => for target in targets {
- self.assert_iscleanup(mir, block_data, *target, is_cleanup);
+ self.assert_iscleanup(body, block_data, *target, is_cleanup);
},
TerminatorKind::Resume => if !is_cleanup {
span_mirbug!(self, block_data, "resume on non-cleanup block!")
if is_cleanup {
span_mirbug!(self, block_data, "yield in cleanup block")
}
- self.assert_iscleanup(mir, block_data, resume, is_cleanup);
+ self.assert_iscleanup(body, block_data, resume, is_cleanup);
if let Some(drop) = drop {
- self.assert_iscleanup(mir, block_data, drop, is_cleanup);
+ self.assert_iscleanup(body, block_data, drop, is_cleanup);
}
}
TerminatorKind::Unreachable => {}
cleanup: unwind,
..
} => {
- self.assert_iscleanup(mir, block_data, target, is_cleanup);
+ 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(mir, block_data, unwind, true);
+ self.assert_iscleanup(body, block_data, unwind, true);
}
}
TerminatorKind::Call {
..
} => {
if let &Some((_, target)) = destination {
- self.assert_iscleanup(mir, block_data, target, is_cleanup);
+ 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(mir, block_data, cleanup, true);
+ self.assert_iscleanup(body, block_data, cleanup, true);
}
}
TerminatorKind::FalseEdges {
real_target,
ref imaginary_targets,
} => {
- self.assert_iscleanup(mir, block_data, real_target, is_cleanup);
+ self.assert_iscleanup(body, block_data, real_target, is_cleanup);
for target in imaginary_targets {
- self.assert_iscleanup(mir, block_data, *target, is_cleanup);
+ self.assert_iscleanup(body, block_data, *target, is_cleanup);
}
}
TerminatorKind::FalseUnwind {
real_target,
unwind,
} => {
- self.assert_iscleanup(mir, block_data, real_target, is_cleanup);
+ self.assert_iscleanup(body, block_data, real_target, is_cleanup);
if let Some(unwind) = unwind {
if is_cleanup {
span_mirbug!(
"cleanup in cleanup block via false unwind"
);
}
- self.assert_iscleanup(mir, block_data, unwind, true);
+ self.assert_iscleanup(body, block_data, unwind, true);
}
}
}
fn assert_iscleanup(
&mut self,
- mir: &Body<'tcx>,
+ body: &Body<'tcx>,
ctxt: &dyn fmt::Debug,
bb: BasicBlock,
iscleanuppad: bool,
) {
- if mir[bb].is_cleanup != iscleanuppad {
+ if body[bb].is_cleanup != iscleanuppad {
span_mirbug!(
self,
ctxt,
}
}
- fn check_local(&mut self, mir: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
- match mir.local_kind(local) {
+ fn check_local(&mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
+ match body.local_kind(local) {
LocalKind::ReturnPointer | LocalKind::Arg => {
// return values of normal functions are required to be
// sized by typeck, but return values of ADT constructors are
// `Sized` bound in no way depends on precise regions, so this
// shouldn't affect `is_sized`.
let gcx = tcx.global_tcx();
- let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
+ let erased_ty = tcx.erase_regions(&ty);
if !erased_ty.is_sized(gcx.at(span), self.param_env) {
// in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return
}
}
- fn check_rvalue(&mut self, mir: &Body<'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 {
Rvalue::Aggregate(ak, ops) => {
- self.check_aggregate_rvalue(mir, rvalue, ak, ops, location)
+ self.check_aggregate_rvalue(body, rvalue, ak, ops, location)
}
Rvalue::Repeat(operand, len) => if *len > 1 {
- let operand_ty = operand.ty(mir, tcx);
+ let operand_ty = operand.ty(body, tcx);
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().copy_trait().unwrap(),
Rvalue::NullaryOp(_, ty) => {
// Even with unsized locals cannot box an unsized value.
if self.tcx().features().unsized_locals {
- let span = mir.source_info(location).span;
+ let span = body.source_info(location).span;
self.ensure_place_sized(ty, span);
}
Rvalue::Cast(cast_kind, op, ty) => {
match cast_kind {
CastKind::Pointer(PointerCast::ReifyFnPointer) => {
- let fn_sig = op.ty(mir, 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(mir, tcx).sty {
+ let sig = match op.ty(body, tcx).sty {
ty::Closure(def_id, substs) => {
substs.closure_sig_ty(def_id, tcx).fn_sig(tcx)
}
}
CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
- let fn_sig = op.ty(mir, 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
let &ty = ty;
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
- substs: tcx.mk_substs_trait(op.ty(mir, tcx), &[ty.into()]),
+ 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(mir, tcx).sty {
+ let ty_from = match op.ty(body, tcx).sty {
ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
mutbl: hir::MutMutable,
}
CastKind::Misc => {
- if let ty::Ref(_, mut ty_from, _) = op.ty(mir, tcx).sty {
+ if let ty::Ref(_, mut ty_from, _) = op.ty(body, tcx).sty {
let (mut ty_to, mutability) = if let ty::RawPtr(ty::TypeAndMut {
ty: ty_to,
mutbl,
self,
rvalue,
"invalid cast types {:?} -> {:?}",
- op.ty(mir, tcx),
+ op.ty(body, tcx),
ty,
);
return;
}
Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
- self.add_reborrow_constraint(mir, location, region, borrowed_place);
+ self.add_reborrow_constraint(body, location, region, borrowed_place);
}
Rvalue::BinaryOp(BinOp::Eq, left, right)
| Rvalue::BinaryOp(BinOp::Le, left, right)
| Rvalue::BinaryOp(BinOp::Gt, left, right)
| Rvalue::BinaryOp(BinOp::Ge, left, right) => {
- let ty_left = left.ty(mir, tcx);
+ let ty_left = left.ty(body, tcx);
if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.sty {
- let ty_right = right.ty(mir, tcx);
+ let ty_right = right.ty(body, tcx);
let common_ty = self.infcx.next_ty_var(
- TypeVariableOrigin::MiscVariable(mir.source_info(location).span),
+ TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span: body.source_info(location).span,
+ }
);
self.sub_types(
common_ty,
fn check_aggregate_rvalue(
&mut self,
- mir: &Body<'tcx>,
+ body: &Body<'tcx>,
rvalue: &Rvalue<'tcx>,
aggregate_kind: &AggregateKind<'tcx>,
operands: &[Operand<'tcx>],
continue;
}
};
- let operand_ty = operand.ty(mir, tcx);
+ let operand_ty = operand.ty(body, tcx);
if let Err(terr) = self.sub_types(
operand_ty,
/// - `borrowed_place`: the place `P` being borrowed
fn add_reborrow_constraint(
&mut self,
- mir: &Body<'tcx>,
+ body: &Body<'tcx>,
location: Location,
borrow_region: ty::Region<'tcx>,
borrowed_place: &Place<'tcx>,
match *elem {
ProjectionElem::Deref => {
let tcx = self.infcx.tcx;
- let base_ty = base.ty(mir, tcx).ty;
+ let base_ty = base.ty(body, tcx).ty;
debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
match base_ty.sty {
fn prove_closure_bounds(
&mut self,
- tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ tcx: TyCtxt<'tcx>,
def_id: DefId,
substs: SubstsRef<'tcx>,
location: Location,
})
}
- fn typeck_mir(&mut self, mir: &Body<'tcx>) {
- self.last_span = mir.span;
- debug!("run_on_mir: {:?}", mir.span);
+ fn typeck_mir(&mut self, body: &Body<'tcx>) {
+ self.last_span = body.span;
+ debug!("run_on_mir: {:?}", body.span);
- for (local, local_decl) in mir.local_decls.iter_enumerated() {
- self.check_local(mir, local, local_decl);
+ for (local, local_decl) in body.local_decls.iter_enumerated() {
+ self.check_local(body, local, local_decl);
}
- for (block, block_data) in mir.basic_blocks().iter_enumerated() {
+ for (block, block_data) in body.basic_blocks().iter_enumerated() {
let mut location = Location {
block,
statement_index: 0,
if !stmt.source_info.span.is_dummy() {
self.last_span = stmt.source_info.span;
}
- self.check_stmt(mir, stmt, location);
+ self.check_stmt(body, stmt, location);
location.statement_index += 1;
}
- self.check_terminator(mir, block_data.terminator(), location);
- self.check_iscleanup(mir, block_data);
+ self.check_terminator(body, block_data.terminator(), location);
+ self.check_iscleanup(body, block_data);
}
}
fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
where
- T: type_op::normalize::Normalizable<'gcx, 'tcx> + Copy,
+ T: type_op::normalize::Normalizable<'tcx> + Copy + 'tcx,
{
debug!("normalize(value={:?}, location={:?})", value, location);
let param_env = self.param_env;