Auto merge of #26677 - jroesch:fulfillment-context-refactor, r=nrc

This patch implements the next chunk of flattening out the type checking context. In a series of patches I moved around the necessary state and logic in order to delete the `Typer` and `ClosureTyper` traits. My next goal is to clean the interfaces and start to move the normalization code behind them.

r? @nrc I hope my PR is coherent, doing this too late at night ;)
This commit is contained in:
bors 2015-07-02 03:10:25 +00:00
commit 560b1dab15
54 changed files with 483 additions and 610 deletions

View File

@ -26,7 +26,6 @@ use metadata::tydecode::{RegionParameter, ClosureSource};
use metadata::tyencode;
use middle::cast;
use middle::check_const::ConstQualif;
use middle::mem_categorization::Typer;
use middle::privacy::{AllPublic, LastMod};
use middle::subst;
use middle::subst::VecPerParamSpace;

View File

@ -110,14 +110,16 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
}
fn with_euv<'b, F, R>(&'b mut self, item_id: Option<ast::NodeId>, f: F) -> R where
F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'tcx,
ty::ParameterEnvironment<'a, 'tcx>>) -> R,
F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'b, 'tcx>) -> R,
{
let param_env = match item_id {
Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id),
None => self.tcx.empty_parameter_environment()
};
f(&mut euv::ExprUseVisitor::new(self, &param_env))
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false);
f(&mut euv::ExprUseVisitor::new(self, &infcx))
}
fn global_expr(&mut self, mode: Mode, expr: &ast::Expr) -> ConstQualif {
@ -283,11 +285,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
fn check_static_type(&self, e: &ast::Expr) {
let ty = self.tcx.node_id_to_type(e.id);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None);
let mut fulfill_cx = traits::FulfillmentContext::new(false);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false);
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
match fulfill_cx.select_all_or_error(&infcx) {
Ok(()) => { },
Err(ref errors) => {
traits::report_fulfillment_errors(&infcx, errors);

View File

@ -20,7 +20,8 @@ use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
use middle::expr_use_visitor::WriteAndRead;
use middle::expr_use_visitor as euv;
use middle::mem_categorization::{cmt, Typer};
use middle::infer;
use middle::mem_categorization::{cmt};
use middle::pat_util::*;
use middle::ty::*;
use middle::ty;
@ -1111,7 +1112,12 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
match p.node {
ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
let pat_ty = tcx.node_id_to_type(p.id);
if cx.param_env.type_moves_by_default(pat_ty, pat.span) {
//FIXME: (@jroesch) this code should be floated up as well
let infcx = infer::new_infer_ctxt(cx.tcx,
&cx.tcx.tables,
Some(cx.param_env.clone()),
false);
if infcx.type_moves_by_default(pat_ty, pat.span) {
check_move(p, sub.as_ref().map(|p| &**p));
}
}
@ -1139,8 +1145,13 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
let mut checker = MutationChecker {
cx: cx,
};
let mut visitor = ExprUseVisitor::new(&mut checker,
&checker.cx.param_env);
let infcx = infer::new_infer_ctxt(cx.tcx,
&cx.tcx.tables,
Some(checker.cx.param_env.clone()),
false);
let mut visitor = ExprUseVisitor::new(&mut checker, &infcx);
visitor.walk_expr(guard);
}

View File

@ -12,6 +12,7 @@
// is the public starting point.
use middle::expr_use_visitor as euv;
use middle::infer;
use middle::mem_categorization as mc;
use middle::ty::ParameterEnvironment;
use middle::ty;
@ -38,9 +39,14 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
s: Span,
fn_id: ast::NodeId) {
{
// FIXME (@jroesch) change this to be an inference context
let param_env = ParameterEnvironment::for_item(self.tcx, fn_id);
let infcx = infer::new_infer_ctxt(self.tcx,
&self.tcx.tables,
Some(param_env.clone()),
false);
let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &param_env };
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &param_env);
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx);
euv.walk_fn(fd, b);
}
visit::walk_fn(self, fk, fd, b, s)

View File

@ -1031,9 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
substs: trait_substs });
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
let mut selcx = traits::SelectionContext::new(&infcx);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
trait_ref.to_poly_trait_predicate());
let selection = match selcx.select(&obligation) {

View File

@ -21,8 +21,8 @@ use self::TrackMatchMode::*;
use self::OverloadedCallType::*;
use middle::{def, region, pat_util};
use middle::infer;
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
use middle::ty::{self};
use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
@ -291,9 +291,9 @@ impl OverloadedCallType {
// supplies types from the tree. After type checking is complete, you
// can just use the tcx as the typer.
pub struct ExprUseVisitor<'d,'t,'tcx:'t,TYPER:'t> {
typer: &'t TYPER,
mc: mc::MemCategorizationContext<'t,TYPER>,
pub struct ExprUseVisitor<'d,'t,'a: 't, 'tcx:'a> {
typer: &'t infer::InferCtxt<'a, 'tcx>,
mc: mc::MemCategorizationContext<'t, 'a, 'tcx>,
delegate: &'d mut (Delegate<'tcx>+'d),
}
@ -319,10 +319,10 @@ enum PassArgs {
ByRef,
}
impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
pub fn new(delegate: &'d mut Delegate<'tcx>,
typer: &'t TYPER)
-> ExprUseVisitor<'d,'t,'tcx,TYPER> {
typer: &'t infer::InferCtxt<'a, 'tcx>)
-> ExprUseVisitor<'d,'t,'a, 'tcx> {
ExprUseVisitor {
typer: typer,
mc: mc::MemCategorizationContext::new(typer),
@ -355,7 +355,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
}
fn tcx(&self) -> &'t ty::ctxt<'tcx> {
self.typer.tcx()
self.typer.tcx
}
fn delegate_consume(&mut self,
@ -690,7 +690,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
match local.init {
None => {
let delegate = &mut self.delegate;
pat_util::pat_bindings(&self.typer.tcx().def_map, &*local.pat,
pat_util::pat_bindings(&self.typer.tcx.def_map, &*local.pat,
|_, id, span, _| {
delegate.decl_without_init(id, span);
})
@ -1052,7 +1052,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
let delegate = &mut self.delegate;
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
if pat_util::pat_is_binding(def_map, pat) {
let tcx = typer.tcx();
let tcx = typer.tcx;
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}",
cmt_pat,
@ -1139,7 +1139,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
// the leaves of the pattern tree structure.
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
let def_map = def_map.borrow();
let tcx = typer.tcx();
let tcx = typer.tcx;
match pat.node {
ast::PatEnum(_, _) | ast::PatQPath(..) |
@ -1278,7 +1278,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
}
}
fn copy_or_move<'tcx>(typer: &mc::Typer<'tcx>,
fn copy_or_move<'a, 'tcx>(typer: &infer::InferCtxt<'a, 'tcx>,
cmt: &mc::cmt<'tcx>,
move_reason: MoveReason)
-> ConsumeMode

View File

@ -34,7 +34,6 @@ pub enum Implication<'tcx> {
struct Implicator<'a, 'tcx: 'a> {
infcx: &'a InferCtxt<'a,'tcx>,
closure_typer: &'a (ty::ClosureTyper<'tcx>+'a),
body_id: ast::NodeId,
stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
span: Span,
@ -46,7 +45,6 @@ struct Implicator<'a, 'tcx: 'a> {
/// appear in a context with lifetime `outer_region`
pub fn implications<'a,'tcx>(
infcx: &'a InferCtxt<'a,'tcx>,
closure_typer: &ty::ClosureTyper<'tcx>,
body_id: ast::NodeId,
ty: Ty<'tcx>,
outer_region: ty::Region,
@ -60,8 +58,7 @@ pub fn implications<'a,'tcx>(
let mut stack = Vec::new();
stack.push((outer_region, None));
let mut wf = Implicator { closure_typer: closure_typer,
infcx: infcx,
let mut wf = Implicator { infcx: infcx,
body_id: body_id,
span: span,
stack: stack,
@ -404,7 +401,6 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
{
let value =
traits::fully_normalize(self.infcx,
self.closure_typer,
traits::ObligationCause::misc(self.span, self.body_id),
value);
match value {

View File

@ -29,7 +29,8 @@ use middle::region::CodeExtent;
use middle::subst;
use middle::subst::Substs;
use middle::subst::Subst;
use middle::traits;
use middle::traits::{self, FulfillmentContext, Normalized,
SelectionContext, ObligationCause};
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
@ -39,7 +40,7 @@ use std::cell::{RefCell, Ref};
use std::fmt;
use syntax::ast;
use syntax::codemap;
use syntax::codemap::Span;
use syntax::codemap::{Span, DUMMY_SP};
use util::nodemap::{FnvHashMap, NodeMap};
use self::combine::CombineFields;
@ -87,6 +88,8 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
// This is a temporary field used for toggling on normalization in the inference context,
// as we move towards the approach described here:
// https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
@ -327,9 +330,16 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
}
}
/// errors_will_be_reported is required to proxy to the fulfillment context
/// FIXME -- a better option would be to hold back on modifying
/// the global cache until we know that all dependent obligations
/// are also satisfied. In that case, we could actually remove
/// this boolean flag, and we'd also avoid the problem of squelching
/// duplicate errors that occur across fns.
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
tables: &'a RefCell<ty::Tables<'tcx>>,
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>,
errors_will_be_reported: bool)
-> InferCtxt<'a, 'tcx> {
InferCtxt {
tcx: tcx,
@ -339,11 +349,20 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(tcx),
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
normalize: false,
err_count_on_creation: tcx.sess.err_count()
}
}
pub fn normalizing_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
tables: &'a RefCell<ty::Tables<'tcx>>)
-> InferCtxt<'a, 'tcx> {
let mut infcx = new_infer_ctxt(tcx, tables, None, false);
infcx.normalize = true;
infcx
}
/// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and
/// returns ty::err.
pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
@ -455,123 +474,145 @@ pub struct CombinedSnapshot {
region_vars_snapshot: RegionSnapshot,
}
impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> {
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
let ty = self.node_ty(id);
self.resolve_type_vars_or_error(&ty)
pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
where T : TypeFoldable<'tcx> + HasTypeFlags
{
debug!("normalize_associated_type(t={:?})", value);
let value = erase_regions(tcx, value);
if !value.has_projection_types() {
return value;
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
self.resolve_type_vars_or_error(&ty)
let infcx = new_infer_ctxt(tcx, &tcx.tables, None, true);
let mut selcx = traits::SelectionContext::new(&infcx);
let cause = traits::ObligationCause::dummy();
let traits::Normalized { value: result, obligations } =
traits::normalize(&mut selcx, cause, &value);
debug!("normalize_associated_type: result={:?} obligations={:?}",
result,
obligations);
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
for obligation in obligations {
fulfill_cx.register_predicate_obligation(&infcx, obligation);
}
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
let ty = self.resolve_type_vars_if_possible(&ty);
!traits::type_known_to_meet_builtin_bound(self, self, ty, ty::BoundCopy, span)
}
let result = drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result);
fn node_method_ty(&self, method_call: ty::MethodCall)
-> Option<Ty<'tcx>> {
self.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.ty)
.map(|ty| self.resolve_type_vars_if_possible(&ty))
}
result
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
self.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.origin.clone())
}
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
-> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
&tables.adjustments
pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
infcx: &InferCtxt<'a,'tcx>,
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
result: &T)
-> T
where T : TypeFoldable<'tcx>
{
match drain_fulfillment_cx(infcx, fulfill_cx, result) {
Ok(v) => v,
Err(errors) => {
infcx.tcx.sess.span_bug(
span,
&format!("Encountered errors `{:?}` fulfilling during trans",
errors));
}
Ref::map(self.tables.borrow(), project_adjustments)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
self.parameter_environment.temporary_scope(rvalue_id)
}
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
}
}
impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
&self.parameter_environment
}
/// Finishes processes any obligations that remain in the fulfillment
/// context, and then "freshens" and returns `result`. This is
/// primarily used during normalization and other cases where
/// processing the obligations in `fulfill_cx` may cause type
/// inference variables that appear in `result` to be unified, and
/// hence we need to process those obligations to get the complete
/// picture of the type.
pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
result: &T)
-> Result<T,Vec<traits::FulfillmentError<'tcx>>>
where T : TypeFoldable<'tcx>
{
debug!("drain_fulfillment_cx(result={:?})",
result);
fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
self.tables.borrow().closure_kinds.get(&def_id).cloned()
}
fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
let closure_ty = self.tables
.borrow()
.closure_tys
.get(&def_id)
.unwrap()
.subst(self.tcx, substs);
if self.normalize {
// NOTE: this flag is currently *always* set to false, we are slowly folding
// normalization into this trait and will come back to remove this in the near
// future.
// code from NormalizingClosureTyper:
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
// normalize_associated_type(self.param_env.tcx, &closure_ty)
panic!("see issue 26597: fufillment context refactor must occur")
} else {
closure_ty
// In principle, we only need to do this so long as `result`
// contains unbound type parameters. It could be a slight
// optimization to stop iterating early.
match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => { }
Err(errors) => {
return Err(errors);
}
}
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
{
let result = ty::ctxt::closure_upvars(self, def_id, substs);
// Use freshen to simultaneously replace all type variables with
// their bindings and replace all regions with 'static. This is
// sort of overkill because we do not expect there to be any
// unbound type variables, hence no `TyFresh` types should ever be
// inserted.
Ok(result.fold_with(&mut infcx.freshener()))
}
if self.normalize {
// NOTE: this flag is currently *always* set to false, we are slowly folding
// normalization into this trait and will come back to remove this in the near
// future.
/// Returns an equivalent value with all free regions removed (note
/// that late-bound regions remain, because they are important for
/// subtyping, but they are anonymized and normalized as well). This
/// is a stronger, caching version of `ty_fold::erase_regions`.
pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
where T : TypeFoldable<'tcx>
{
let value1 = value.fold_with(&mut RegionEraser(cx));
debug!("erase_regions({:?}) = {:?}",
value, value1);
return value1;
// code from NormalizingClosureTyper:
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
// monomorphize::normalize_associated_type(self.param_env.tcx, &result)
panic!("see issue 26597: fufillment context refactor must occur")
} else {
result
struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>);
impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match self.tcx().normalized_cache.borrow().get(&ty).cloned() {
None => {}
Some(u) => return u
}
let t_norm = ty_fold::super_fold_ty(self, ty);
self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm);
return t_norm;
}
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
where T : TypeFoldable<'tcx>
{
let u = self.tcx().anonymize_late_bound_regions(t);
ty_fold::super_fold_binder(self, &u)
}
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
// because late-bound regions affect subtyping, we can't
// erase the bound/free distinction, but we can replace
// all free regions with 'static.
//
// Note that we *CAN* replace early-bound regions -- the
// type system never "sees" those, they get substituted
// away. In trans, they will always be erased to 'static
// whenever a substitution occurs.
match r {
ty::ReLateBound(..) => r,
_ => ty::ReStatic
}
}
fn fold_substs(&mut self,
substs: &subst::Substs<'tcx>)
-> subst::Substs<'tcx> {
subst::Substs { regions: subst::ErasedRegions,
types: substs.types.fold_with(self) }
}
}
}
@ -1017,7 +1058,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.map(|method| resolve_ty(method.ty)))
}
pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
match self.tables.borrow().node_types.get(&id) {
Some(&t) => t,
// FIXME
@ -1263,6 +1304,109 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.equate(true, trace).relate(a, b)
}).map(|_| ())
}
pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
let ty = self.node_type(id);
self.resolve_type_vars_or_error(&ty)
}
pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
self.resolve_type_vars_or_error(&ty)
}
pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
let ty = self.resolve_type_vars_if_possible(&ty);
!traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
// FIXME(@jroesch): should be able to use:
// ty.moves_by_default(&self.parameter_environment, span)
}
pub fn node_method_ty(&self, method_call: ty::MethodCall)
-> Option<Ty<'tcx>> {
self.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.ty)
.map(|ty| self.resolve_type_vars_if_possible(&ty))
}
pub fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
self.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.origin.clone())
}
pub fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
-> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
&tables.adjustments
}
Ref::map(self.tables.borrow(), project_adjustments)
}
pub fn is_method_call(&self, id: ast::NodeId) -> bool {
self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
}
pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
self.tcx.region_maps.temporary_scope(rvalue_id)
}
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
}
pub fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
&self.parameter_environment
}
pub fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
self.tables.borrow().closure_kinds.get(&def_id).cloned()
}
pub fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
let closure_ty = self.tables
.borrow()
.closure_tys
.get(&def_id)
.unwrap()
.subst(self.tcx, substs);
if self.normalize {
normalize_associated_type(&self.tcx, &closure_ty)
} else {
closure_ty
}
}
pub fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
{
let result = ty::ctxt::closure_upvars(self, def_id, substs);
if self.normalize {
normalize_associated_type(&self.tcx, &result)
} else {
result
}
}
}
impl<'tcx> TypeTrace<'tcx> {

View File

@ -110,11 +110,9 @@ use self::LiveNodeKind::*;
use self::VarKind::*;
use middle::def::*;
use middle::mem_categorization::Typer;
use middle::pat_util;
use middle::region;
use middle::ty;
use middle::ty::ClosureTyper;
use lint;
use util::nodemap::NodeMap;

View File

@ -73,17 +73,16 @@ pub use self::categorization::*;
use self::Aliasability::*;
use ast_map;
use middle::infer;
use middle::check_const;
use middle::def;
use middle::region;
use middle::ty::{self, Ty};
use util::nodemap::NodeMap;
use syntax::ast::{MutImmutable, MutMutable};
use syntax::ast;
use syntax::codemap::Span;
use std::cell::Ref;
use std::fmt;
use std::rc::Rc;
@ -255,46 +254,13 @@ impl ast_node for ast::Pat {
fn span(&self) -> Span { self.span }
}
pub struct MemCategorizationContext<'t,TYPER:'t> {
typer: &'t TYPER
}
impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
impl<'t,TYPER:'t> Clone for MemCategorizationContext<'t,TYPER> {
fn clone(&self) -> MemCategorizationContext<'t,TYPER> { *self }
#[derive(Copy, Clone)]
pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> {
pub typer: &'t infer::InferCtxt<'a, 'tcx>,
}
pub type McResult<T> = Result<T, ()>;
/// The `Typer` trait provides the interface for the mem-categorization
/// module to the results of the type check. It can be used to query
/// the type assigned to an expression node, to inquire after adjustments,
/// and so on.
///
/// This interface is needed because mem-categorization is used from
/// two places: `regionck` and `borrowck`. `regionck` executes before
/// type inference is complete, and hence derives types and so on from
/// intermediate tables. This also implies that type errors can occur,
/// and hence `node_ty()` and friends return a `Result` type -- any
/// error will propagate back up through the mem-categorization
/// routines.
///
/// In the borrow checker, in contrast, type checking is complete and we
/// know that no errors have occurred, so we simply consult the tcx and we
/// can be sure that only `Ok` results will occur.
pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool;
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>;
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture>;
}
impl MutabilityCategory {
pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory {
let ret = match m {
@ -391,13 +357,13 @@ impl MutabilityCategory {
}
}
impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
pub fn new(typer: &'t TYPER) -> MemCategorizationContext<'t,TYPER> {
impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
pub fn new(typer: &'t infer::InferCtxt<'a, 'tcx>) -> MemCategorizationContext<'t, 'a, 'tcx> {
MemCategorizationContext { typer: typer }
}
fn tcx(&self) -> &'t ty::ctxt<'tcx> {
self.typer.tcx()
fn tcx(&self) -> &'a ty::ctxt<'tcx> {
self.typer.tcx
}
fn expr_ty(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
@ -1175,7 +1141,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}
pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()>
where F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat),
{
self.cat_pattern_(cmt, pat, &mut op)
}
@ -1183,7 +1149,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
// FIXME(#19596) This is a workaround, but there should be a better way to do this
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
-> McResult<()>
where F : FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat),
{
// Here, `cmt` is the categorization for the value being
// matched and pat is the pattern it is being matched against.

View File

@ -38,8 +38,7 @@ pub fn overlapping_impls(infcx: &InferCtxt,
impl1_def_id,
impl2_def_id);
let param_env = &infcx.tcx.empty_parameter_environment();
let selcx = &mut SelectionContext::intercrate(infcx, param_env);
let selcx = &mut SelectionContext::intercrate(infcx);
infcx.probe(|_| {
overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id)
})

View File

@ -85,7 +85,7 @@ pub struct FulfillmentContext<'tcx> {
// particular node-id).
region_obligations: NodeMap<Vec<RegionObligation<'tcx>>>,
errors_will_be_reported: bool,
pub errors_will_be_reported: bool,
}
#[derive(Clone)]
@ -132,7 +132,6 @@ impl<'tcx> FulfillmentContext<'tcx> {
/// `projection_ty` again.
pub fn normalize_projection_type<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
typer: &ty::ClosureTyper<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
cause: ObligationCause<'tcx>)
-> Ty<'tcx>
@ -144,7 +143,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
// FIXME(#20304) -- cache
let mut selcx = SelectionContext::new(infcx, typer);
let mut selcx = SelectionContext::new(infcx);
let normalized = project::normalize_projection_type(&mut selcx, projection_ty, cause, 0);
for obligation in normalized.obligations {
@ -208,11 +207,10 @@ impl<'tcx> FulfillmentContext<'tcx> {
}
pub fn select_all_or_error<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
typer: &ty::ClosureTyper<'tcx>)
infcx: &InferCtxt<'a,'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
try!(self.select_where_possible(infcx, typer));
try!(self.select_where_possible(infcx));
// Anything left is ambiguous.
let errors: Vec<FulfillmentError> =
@ -233,20 +231,18 @@ impl<'tcx> FulfillmentContext<'tcx> {
/// gaining type information. It'd be equally valid to use `select_where_possible` but it
/// results in `O(n^2)` performance (#18208).
pub fn select_new_obligations<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
typer: &ty::ClosureTyper<'tcx>)
infcx: &InferCtxt<'a,'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, typer);
let mut selcx = SelectionContext::new(infcx);
self.select(&mut selcx, true)
}
pub fn select_where_possible<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
typer: &ty::ClosureTyper<'tcx>)
infcx: &InferCtxt<'a,'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, typer);
let mut selcx = SelectionContext::new(infcx);
self.select(&mut selcx, false)
}

View File

@ -312,7 +312,6 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
/// conservative towards *no impl*, which is the opposite of the
/// `evaluate` methods).
pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
typer: &ty::ClosureTyper<'tcx>,
ty: Ty<'tcx>,
bound: ty::BuiltinBound,
span: Span)
@ -334,7 +333,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
// Note: we only assume something is `Copy` if we can
// *definitively* show that it implements `Copy`. Otherwise,
// assume it is move; linear is always ok.
match fulfill_cx.select_all_or_error(infcx, typer) {
match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => {
debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success",
ty,
@ -397,8 +396,8 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env));
let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env), false);
let predicates = match fully_normalize(&infcx, cause,
&infcx.parameter_environment.caller_bounds) {
Ok(predicates) => predicates,
Err(errors) => {
@ -429,7 +428,6 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
}
pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
closure_typer: &ty::ClosureTyper<'tcx>,
cause: ObligationCause<'tcx>,
value: &T)
-> Result<T, Vec<FulfillmentError<'tcx>>>
@ -437,8 +435,22 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
{
debug!("normalize_param_env(value={:?})", value);
let mut selcx = &mut SelectionContext::new(infcx, closure_typer);
let mut selcx = &mut SelectionContext::new(infcx);
// FIXME (@jroesch) ISSUE 26721
// I'm not sure if this is a bug or not, needs further investigation.
// It appears that by reusing the fulfillment_cx here we incur more
// obligations and later trip an asssertion on regionck.rs line 337.
//
// The two possibilities I see is:
// - normalization is not actually fully happening and we
// have a bug else where
// - we are adding a duplicate bound into the list causing
// its size to change.
//
// I think we should probably land this refactor and then come
// back to this is a follow-up patch.
let mut fulfill_cx = FulfillmentContext::new(false);
let Normalized { value: normalized_value, obligations } =
project::normalize(selcx, cause, value);
debug!("normalize_param_env: normalized_value={:?} obligations={:?}",
@ -447,7 +459,8 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
for obligation in obligations {
fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
}
try!(fulfill_cx.select_all_or_error(infcx, closure_typer));
try!(fulfill_cx.select_all_or_error(infcx));
let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
debug!("normalize_param_env: resolved_value={:?}", resolved_value);
Ok(resolved_value)

View File

@ -55,8 +55,6 @@ use util::nodemap::FnvHashMap;
pub struct SelectionContext<'cx, 'tcx:'cx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx),
/// Freshener used specifically for skolemizing entries on the
/// obligation stack. This ensures that all entries on the stack
/// at one time will have the same set of skolemized entries,
@ -244,23 +242,19 @@ enum EvaluationResult<'tcx> {
}
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
closure_typer: &'cx ty::ClosureTyper<'tcx>)
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: false,
}
}
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
closure_typer: &'cx ty::ClosureTyper<'tcx>)
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: true,
}
@ -275,11 +269,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'cx, 'tcx> {
self.closure_typer.param_env()
self.infcx.param_env()
}
pub fn closure_typer(&self) -> &'cx (ty::ClosureTyper<'tcx>+'cx) {
self.closure_typer
pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'tcx> {
self.infcx
}
///////////////////////////////////////////////////////////////////////////
@ -1163,7 +1157,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
kind,
obligation);
match self.closure_typer.closure_kind(closure_def_id) {
match self.infcx.closure_kind(closure_def_id) {
Some(closure_kind) => {
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
if closure_kind.extends(kind) {
@ -1727,7 +1721,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return ok_if(Vec::new());
}
match self.closure_typer.closure_upvars(def_id, substs) {
match self.infcx.closure_upvars(def_id, substs) {
Some(upvars) => ok_if(upvars.iter().map(|c| c.ty).collect()),
None => {
debug!("assemble_builtin_bound_candidates: no upvar types available yet");
@ -1865,7 +1859,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::TyClosure(def_id, substs) => {
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
match self.closure_typer.closure_upvars(def_id, substs) {
match self.infcx.closure_upvars(def_id, substs) {
Some(upvars) => {
Some(upvars.iter().map(|c| c.ty).collect())
}
@ -2844,7 +2838,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
substs: &Substs<'tcx>)
-> ty::PolyTraitRef<'tcx>
{
let closure_type = self.closure_typer.closure_type(closure_def_id, substs);
let closure_type = self.infcx.closure_type(closure_def_id, substs);
let ty::Binder((trait_ref, _)) =
util::closure_trait_ref_and_return_type(self.tcx(),
obligation.predicate.def_id(),

View File

@ -52,8 +52,6 @@ use middle::dependency_format;
use middle::fast_reject;
use middle::free_region::FreeRegionMap;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
use middle::region;
use middle::resolve_lifetime;
use middle::infer;
@ -2919,11 +2917,14 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
-> Result<(),CopyImplementationError> {
let tcx = self.tcx;
// FIXME: (@jroesch) float this code up
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(self.clone()), false);
let did = match self_type.sty {
ty::TyStruct(struct_did, substs) => {
let fields = tcx.struct_fields(struct_did, substs);
for field in &fields {
if self.type_moves_by_default(field.mt.ty, span) {
if infcx.type_moves_by_default(field.mt.ty, span) {
return Err(FieldDoesNotImplementCopy(field.name))
}
}
@ -2935,7 +2936,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
for variant_arg_type in &variant.args {
let substd_arg_type =
variant_arg_type.subst(tcx, substs);
if self.type_moves_by_default(substd_arg_type, span) {
if infcx.type_moves_by_default(substd_arg_type, span) {
return Err(VariantDoesNotImplementCopy(variant.name))
}
}
@ -3177,35 +3178,6 @@ impl ClosureKind {
}
}
pub trait ClosureTyper<'tcx> {
fn tcx(&self) -> &ctxt<'tcx> {
self.param_env().tcx
}
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
/// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck,
/// returns `None` if the kind of this closure has not yet been
/// inferred.
fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>;
/// Returns the argument/return types of this closure.
fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>;
/// Returns the set of all upvars and their transformed
/// types. During typeck, maybe return `None` if the upvar types
/// have not yet been inferred.
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ClosureUpvar<'tcx>>>;
}
impl<'tcx> CommonTypes<'tcx> {
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
@ -4272,7 +4244,8 @@ impl<'tcx> TyS<'tcx> {
TyClosure(did, substs) => {
// FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
let param_env = cx.empty_parameter_environment();
let upvars = param_env.closure_upvars(did, substs).unwrap();
let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false);
let upvars = infcx.closure_upvars(did, substs).unwrap();
TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
}
@ -4400,10 +4373,10 @@ impl<'tcx> TyS<'tcx> {
span: Span)
-> bool
{
let tcx = param_env.tcx();
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()));
let tcx = param_env.tcx;
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false);
let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
let is_impld = traits::type_known_to_meet_builtin_bound(&infcx,
self, bound, span);
debug!("Ty::impls_bound({:?}, {:?}) = {:?}",
@ -4412,7 +4385,8 @@ impl<'tcx> TyS<'tcx> {
is_impld
}
fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
// FIXME (@jroesch): I made this public to use it, not sure if should be private
pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
span: Span) -> bool {
if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
@ -6112,7 +6086,7 @@ impl<'tcx> ctxt<'tcx> {
}
// Returns a list of `ClosureUpvar`s for each upvar.
pub fn closure_upvars(typer: &Typer<'tcx>,
pub fn closure_upvars<'a>(typer: &infer::InferCtxt<'a, 'tcx>,
closure_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ClosureUpvar<'tcx>>>
@ -6123,7 +6097,7 @@ impl<'tcx> ctxt<'tcx> {
// This may change if abstract return types of some sort are
// implemented.
assert!(closure_id.krate == ast::LOCAL_CRATE);
let tcx = typer.tcx();
let tcx = typer.tcx;
match tcx.freevars.borrow().get(&closure_id.node) {
None => Some(vec![]),
Some(ref freevars) => {
@ -6711,79 +6685,6 @@ impl<'tcx> ctxt<'tcx> {
}
}
impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
Ok(self.tcx.node_id_to_type(id))
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
Ok(self.tcx.expr_ty_adjusted(expr))
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone())
}
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
&tables.adjustments
}
Ref::map(self.tcx.tables.borrow(), projection)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
self.tcx.is_method_call(id)
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
self.tcx.region_maps.temporary_scope(rvalue_id)
}
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
self.tcx.upvar_capture(upvar_id)
}
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
ty.moves_by_default(self, span)
}
}
impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
self
}
fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
Some(self.tcx.closure_kind(def_id))
}
fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
self.tcx.closure_type(def_id, substs)
}
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ClosureUpvar<'tcx>>> {
ctxt::closure_upvars(self, def_id, substs)
}
}
/// The category of explicit self.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum ExplicitSelfCategory {

View File

@ -21,6 +21,7 @@ use self::UseError::*;
use borrowck::*;
use borrowck::InteriorKind::{InteriorElement, InteriorField};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::infer;
use rustc::middle::mem_categorization as mc;
use rustc::middle::region;
use rustc::middle::ty;
@ -198,17 +199,18 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
debug!("check_loans(body id={})", body.id);
let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id);
let infcx = infer::new_infer_ctxt(bccx.tcx, &bccx.tcx.tables, Some(param_env), false);
let mut clcx = CheckLoanCtxt {
bccx: bccx,
dfcx_loans: dfcx_loans,
move_data: move_data,
all_loans: all_loans,
param_env: &param_env,
param_env: &infcx.parameter_environment
};
{
let mut euv = euv::ExprUseVisitor::new(&mut clcx, &param_env);
let mut euv = euv::ExprUseVisitor::new(&mut clcx, &infcx);
euv.walk_fn(decl, body);
}
}

View File

@ -19,6 +19,7 @@
use borrowck::*;
use borrowck::move_data::MoveData;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::infer;
use rustc::middle::mem_categorization as mc;
use rustc::middle::region;
use rustc::middle::ty;
@ -49,9 +50,9 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
};
let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id);
let infcx = infer::new_infer_ctxt(bccx.tcx, &bccx.tcx.tables, Some(param_env), false);
{
let mut euv = euv::ExprUseVisitor::new(&mut glcx, &param_env);
let mut euv = euv::ExprUseVisitor::new(&mut glcx, &infcx);
euv.walk_fn(decl, body);
}
@ -490,8 +491,8 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> {
impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
if let ast::ExprAddrOf(mutbl, ref base) = ex.node {
let param_env = self.bccx.tcx.empty_parameter_environment();
let mc = mc::MemCategorizationContext::new(&param_env);
let infcx = infer::new_infer_ctxt(self.bccx.tcx, &self.bccx.tcx.tables, None, false);
let mc = mc::MemCategorizationContext::new(&infcx);
let base_cmt = mc.cat_expr(&**base).unwrap();
let borrow_kind = ty::BorrowKind::from_mutbl(mutbl);
// Check that we don't allow borrows of unsafe static items.

View File

@ -30,7 +30,6 @@ use rustc::middle::dataflow::KillFrom;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Typer;
use rustc::middle::region;
use rustc::middle::ty::{self, Ty};
@ -747,7 +746,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
-> (&'static str, &'static str) {
match ty.sty {
_ => {
if param_env.type_moves_by_default(ty, span) {
if ty.moves_by_default(param_env, span) {
("non-copyable",
"perhaps you meant to use `clone()`?")
} else {

View File

@ -140,7 +140,7 @@ fn test_env<F>(source_string: &str,
lang_items,
stability::Index::new(krate),
|tcx| {
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
body(Env { infcx: &infcx });
let free_regions = FreeRegionMap::new();
infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID);

View File

@ -33,7 +33,6 @@
use metadata::{csearch, decoder};
use middle::def::*;
use middle::mem_categorization::Typer;
use middle::subst::Substs;
use middle::ty::{self, Ty};
use middle::{def, pat_util, stability};
@ -1709,7 +1708,9 @@ impl LintPass for MissingCopyImplementations {
_ => return,
};
let parameter_environment = cx.tcx.empty_parameter_environment();
if !parameter_environment.type_moves_by_default(ty, item.span) {
// FIXME (@jroesch) should probably inver this so that the parameter env still impls this
// method
if !ty.moves_by_default(&parameter_environment, item.span) {
return;
}
if parameter_environment.can_type_implement_copy(ty, item.span).is_ok() {

View File

@ -43,7 +43,6 @@
#![feature(unicode)]
#![feature(unicode)]
#![feature(vec_push_all)]
#![feature(cell_extras)]
#![allow(trivial_casts)]

View File

@ -195,9 +195,9 @@ use middle::check_match;
use middle::const_eval;
use middle::def::{self, DefMap};
use middle::expr_use_visitor as euv;
use middle::infer;
use middle::lang_items::StrEqFnLangItem;
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
use middle::pat_util::*;
use trans::adt;
use trans::base::*;
@ -1351,7 +1351,8 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool
reassigned: false
};
{
let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx);
let infcx = infer::new_infer_ctxt(bcx.tcx(), &bcx.tcx().tables, None, false);
let mut visitor = euv::ExprUseVisitor::new(&mut rc, &infcx);
visitor.walk_expr(body);
}
rc.reassigned
@ -1416,7 +1417,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
let trmode;
match bm {
ast::BindByValue(_)
if !param_env.type_moves_by_default(variable_ty, span) || reassigned =>
if !variable_ty.moves_by_default(&param_env, span) || reassigned =>
{
llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),

View File

@ -50,7 +50,8 @@ use std::rc::Rc;
use llvm::{ValueRef, True, IntEQ, IntNE};
use back::abi::FAT_PTR_ADDR;
use middle::subst;
use middle::ty::{self, Ty, ClosureTyper};
use middle::infer;
use middle::ty::{self, Ty};
use middle::ty::Disr;
use syntax::ast;
use syntax::attr;
@ -223,8 +224,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor))
}
ty::TyClosure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(cx.tcx());
let upvars = typer.closure_upvars(def_id, substs).unwrap();
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
Univariant(mk_struct(cx, &upvar_types[..], false, t), 0)
}
@ -443,8 +444,8 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
// Perhaps one of the upvars of this struct is non-zero
// Let's recurse and find out!
ty::TyClosure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(tcx);
let upvars = typer.closure_upvars(def_id, substs).unwrap();
let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
for (j, &ty) in upvar_types.iter().enumerate() {

View File

@ -11,7 +11,8 @@
use libc::{c_uint, c_ulonglong};
use llvm::{self, ValueRef, AttrHelper};
use middle::ty::{self, ClosureTyper};
use middle::ty;
use middle::infer;
use session::config::NoDebugInfo;
use syntax::abi;
use syntax::ast;
@ -145,8 +146,8 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
let (fn_sig, abi, env_ty) = match fn_type.sty {
ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
ty::TyClosure(closure_did, substs) => {
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
function_type = typer.closure_type(closure_did, substs);
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
function_type = infcx.closure_type(closure_did, substs);
let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
(&function_type.sig, abi::RustCall, Some(self_type))
}

View File

@ -37,10 +37,11 @@ use llvm;
use metadata::{csearch, encoder, loader};
use middle::astencode;
use middle::cfg;
use middle::infer;
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
use middle::weak_lang_items;
use middle::subst::Substs;
use middle::ty::{self, Ty, ClosureTyper, HasTypeFlags};
use middle::ty::{self, Ty, HasTypeFlags};
use rustc::ast_map;
use session::config::{self, NoDebugInfo};
use session::Session;
@ -434,8 +435,8 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
}
ty::TyClosure(def_id, substs) => {
let repr = adt::represent_type(cx.ccx(), t);
let typer = common::NormalizingClosureTyper::new(cx.tcx());
let upvars = typer.closure_upvars(def_id, substs).unwrap();
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
for (i, upvar) in upvars.iter().enumerate() {
let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
cx = f(cx, llupvar, upvar.ty);

View File

@ -11,7 +11,7 @@
use arena::TypedArena;
use back::link::{self, mangle_internal_name_by_path_and_seq};
use llvm::{ValueRef, get_params};
use middle::mem_categorization::Typer;
use middle::infer;
use trans::adt;
use trans::attributes;
use trans::base::*;
@ -25,7 +25,7 @@ use trans::declare;
use trans::expr;
use trans::monomorphize::{self, MonoId};
use trans::type_of::*;
use middle::ty::{self, ClosureTyper};
use middle::ty;
use middle::subst::Substs;
use session::config::FullDebugInfo;
@ -214,8 +214,9 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
// takes the same set of type arguments as the enclosing fn, and
// this function (`trans_closure`) is invoked at the point
// of the closure expression.
let typer = NormalizingClosureTyper::new(tcx);
let function_type = typer.closure_type(closure_id, param_substs);
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
let function_type = infcx.closure_type(closure_id, param_substs);
let freevars: Vec<ty::Freevar> =
tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
@ -358,7 +359,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
ccx.tn().val_to_string(llreffn));
let tcx = ccx.tcx();
let typer = NormalizingClosureTyper::new(tcx);
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
// Find a version of the closure type. Substitute static for the
// region since it doesn't really matter.
@ -367,7 +368,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty);
// Make a version with the type of by-ref closure.
let ty::ClosureTy { unsafety, abi, mut sig } = typer.closure_type(closure_def_id, substs);
let ty::ClosureTy { unsafety, abi, mut sig } = infcx.closure_type(closure_def_id, substs);
sig.0.inputs.insert(0, ref_closure_ty); // sig has no self type as of yet
let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety,
abi: abi,

View File

@ -22,9 +22,6 @@ use middle::cfg;
use middle::def;
use middle::infer;
use middle::lang_items::LangItem;
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
use middle::region;
use middle::subst::{self, Substs};
use trans::base;
use trans::build;
@ -47,7 +44,7 @@ use util::nodemap::{FnvHashMap, NodeMap};
use arena::TypedArena;
use libc::{c_uint, c_char};
use std::ffi::CString;
use std::cell::{Cell, RefCell, Ref};
use std::cell::{Cell, RefCell};
use std::result::Result as StdResult;
use std::vec::Vec;
use syntax::ast;
@ -153,7 +150,7 @@ fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
// normalized version of the type, and therefore will definitely
// know whether the type implements Copy (and thus needs no
// cleanup/drop/zeroing) ...
let implements_copy = !param_env.type_moves_by_default(ty, DUMMY_SP);
let implements_copy = !ty.moves_by_default(param_env, DUMMY_SP);
if implements_copy { return false; }
@ -576,95 +573,6 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
}
}
impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
Ok(node_id_type(self, id))
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
Ok(expr_ty_adjusted(self, expr))
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
self.tcx()
.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| monomorphize_type(self, method.ty))
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
self.tcx()
.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.origin.clone())
}
fn adjustments<'a>(&'a self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
// FIXME (@jroesch): this is becuase we currently have a HR inference problem
// in the snapshot that causes this code not to work.
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) ->
&'a NodeMap<ty::AutoAdjustment<'tcx>> {
&tables.adjustments
}
Ref::map(self.tcx().tables.borrow(), project_adjustments)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
self.tcx().region_maps.temporary_scope(rvalue_id)
}
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
Some(self.tcx().tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
}
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
self.fcx.param_env.type_moves_by_default(ty, span)
}
}
impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> {
&self.fcx.param_env
}
fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
let typer = NormalizingClosureTyper::new(self.tcx());
typer.closure_kind(def_id)
}
fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
let typer = NormalizingClosureTyper::new(self.tcx());
typer.closure_type(def_id, substs)
}
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
{
let typer = NormalizingClosureTyper::new(self.tcx());
typer.closure_upvars(def_id, substs)
}
}
pub struct Result<'blk, 'tcx: 'blk> {
pub bcx: Block<'blk, 'tcx>,
pub val: ValueRef
@ -957,12 +865,12 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
trait_ref, trait_ref.def_id());
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
let mut selcx = traits::SelectionContext::new(&infcx);
let obligation =
traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
trait_ref.to_poly_trait_predicate());
@ -994,7 +902,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// Currently, we use a fulfillment context to completely resolve
// all nested obligations. This is because they can inform the
// inference of the impl's type parameters.
let mut fulfill_cx = traits::FulfillmentContext::new(true);
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
let vtable = selection.map(|predicate| {
fulfill_cx.register_predicate_obligation(&infcx, predicate);
});
@ -1019,10 +927,9 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
predicates);
let tcx = ccx.tcx();
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let mut fulfill_cx = traits::FulfillmentContext::new(false);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
let mut selcx = traits::SelectionContext::new(&infcx);
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
let cause = traits::ObligationCause::dummy();
let traits::Normalized { value: predicates, obligations } =
traits::normalize(&mut selcx, cause.clone(), &predicates);
@ -1036,57 +943,6 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
}
// NOTE: here is another use of parameter environment without an InferCtxt,
// this is obviously related to the typer interface requiring a parameter env.
// We should pay attention to this when refactoring
// - @jroesch
pub struct NormalizingClosureTyper<'a,'tcx:'a> {
param_env: ty::ParameterEnvironment<'a, 'tcx>
}
impl<'a,'tcx> NormalizingClosureTyper<'a,'tcx> {
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingClosureTyper<'a,'tcx> {
// Parameter environment is used to give details about type parameters,
// but since we are in trans, everything is fully monomorphized.
NormalizingClosureTyper { param_env: tcx.empty_parameter_environment() }
}
}
impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
&self.param_env
}
fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
self.param_env.closure_kind(def_id)
}
fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
let closure_ty = self.param_env.tcx.closure_type(def_id, substs);
monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty)
}
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
{
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
let result = self.param_env.closure_upvars(def_id, substs);
monomorphize::normalize_associated_type(self.param_env.tcx, &result)
}
}
pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
infcx: &infer::InferCtxt<'a,'tcx>,
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
@ -1124,8 +980,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>,
// In principle, we only need to do this so long as `result`
// contains unbound type parameters. It could be a slight
// optimization to stop iterating early.
let typer = NormalizingClosureTyper::new(infcx.tcx);
match fulfill_cx.select_all_or_error(infcx, &typer) {
match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => { }
Err(errors) => {
return Err(errors);

View File

@ -101,7 +101,6 @@ use trans::cleanup::CleanupMethods;
use trans::expr;
use trans::tvec;
use trans::type_of;
use middle::mem_categorization::Typer;
use middle::ty::Ty;
use std::fmt;
@ -606,8 +605,8 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> {
* affine values (since they must never be duplicated).
*/
assert!(!bcx.tcx().empty_parameter_environment()
.type_moves_by_default(self.ty, DUMMY_SP));
assert!(!self.ty
.moves_by_default(&bcx.tcx().empty_parameter_environment(), DUMMY_SP));
self.shallow_copy_raw(bcx, dst)
}

View File

@ -16,7 +16,6 @@ use llvm::ValueRef;
use trans::common::{C_bytes, CrateContext};
use trans::declare;
use trans::type_::Type;
use middle::ty::ClosureTyper;
use session::config::NoDebugInfo;
use std::ffi::CString;

View File

@ -26,12 +26,13 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
use metadata::csearch;
use middle::pat_util;
use middle::subst::{self, Substs};
use middle::infer;
use rustc::ast_map;
use trans::{type_of, adt, machine, monomorphize};
use trans::common::{self, CrateContext, FunctionContext, NormalizingClosureTyper, Block};
use trans::common::{self, CrateContext, FunctionContext, Block};
use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
use trans::type_::Type;
use middle::ty::{self, Ty, ClosureTyper};
use middle::ty::{self, Ty};
use session::config::{self, FullDebugInfo};
use util::nodemap::FnvHashMap;
use util::common::path2cstr;
@ -287,8 +288,8 @@ impl<'tcx> TypeMap<'tcx> {
}
},
ty::TyClosure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(cx.tcx());
let closure_ty = typer.closure_type(def_id, substs);
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
let closure_ty = infcx.closure_type(def_id, substs);
self.get_unique_type_id_of_closure_type(cx,
closure_ty,
&mut unique_type_id);
@ -796,8 +797,8 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
}
ty::TyClosure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(cx.tcx());
let sig = typer.closure_type(def_id, substs).sig;
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
let sig = infcx.closure_type(def_id, substs).sig;
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
}
ty::TyStruct(def_id, substs) => {

View File

@ -30,7 +30,7 @@ use rustc::ast_map;
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
use trans;
use trans::monomorphize;
use middle::ty::{Ty, ClosureTyper};
use middle::ty::Ty;
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};

View File

@ -16,7 +16,6 @@ use llvm;
use llvm::debuginfo::DIScope;
use rustc::ast_map;
use trans::common::CrateContext;
use middle::ty::ClosureTyper;
use std::ffi::CString;
use std::ptr;

View File

@ -14,7 +14,7 @@ use super::namespace::crate_root_namespace;
use trans::common::CrateContext;
use middle::subst::{self, Substs};
use middle::ty::{self, Ty, ClosureTyper};
use middle::ty::{self, Ty};
use syntax::ast;
use syntax::parse::token;
@ -225,4 +225,3 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push('>');
}
}

View File

@ -20,11 +20,11 @@
//! * Use define_* family of methods when you might be defining the ValueRef.
//! * When in doubt, define.
use llvm::{self, ValueRef};
use middle::ty::{self, ClosureTyper};
use middle::ty;
use middle::infer;
use syntax::abi;
use trans::attributes;
use trans::base;
use trans::common;
use trans::context::CrateContext;
use trans::monomorphize;
use trans::type_::Type;
@ -117,8 +117,8 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
(&f.sig, f.abi, None)
}
ty::TyClosure(closure_did, substs) => {
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
function_type = typer.closure_type(closure_did, substs);
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
function_type = infcx.closure_type(closure_did, substs);
let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
let llenvironment_type = type_of::type_of_explicit_arg(ccx, self_type);
debug!("declare_rust_fn function_type={:?} self_type={:?}",

View File

@ -56,7 +56,6 @@ use llvm::{self, ValueRef, TypeKind};
use middle::check_const;
use middle::def;
use middle::lang_items::CoerceUnsizedTraitLangItem;
use middle::mem_categorization::Typer;
use middle::subst::{Substs, VecPerParamSpace};
use middle::traits;
use trans::{_match, adt, asm, base, callee, closure, consts, controlflow};

View File

@ -17,7 +17,6 @@ use middle::subst::{Subst, Substs};
use middle::subst::VecPerParamSpace;
use middle::subst;
use middle::traits;
use middle::ty::ClosureTyper;
use rustc::ast_map;
use trans::base::*;
use trans::build::*;

View File

@ -322,11 +322,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
}
// FIXME(#20304) -- cache
// NOTE: @jroesch
// Here is of an example where we do not use a param_env but use a typer instead.
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
let mut selcx = traits::SelectionContext::new(&infcx);
let cause = traits::ObligationCause::dummy();
let traits::Normalized { value: result, obligations } =
traits::normalize(&mut selcx, cause, &value);
@ -335,7 +332,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
result,
obligations);
let mut fulfill_cx = traits::FulfillmentContext::new(true);
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
for obligation in obligations {
fulfill_cx.register_predicate_obligation(&infcx, obligation);
}

View File

@ -11,13 +11,13 @@
use middle::infer::InferCtxt;
use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation,
SelectionContext, ObligationCause};
use middle::ty::{self, HasTypeFlags};
use middle::ty::HasTypeFlags;
use middle::ty_fold::TypeFoldable;
use syntax::ast;
use syntax::codemap::Span;
//FIXME(@jroesch): Ideally we should be able to drop the fulfillment_cx argument.
pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
typer: &(ty::ClosureTyper<'tcx>+'a),
fulfillment_cx: &mut FulfillmentContext<'tcx>,
span: Span,
body_id: ast::NodeId,
@ -26,7 +26,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
where T : TypeFoldable<'tcx> + HasTypeFlags
{
debug!("normalize_associated_types_in(value={:?})", value);
let mut selcx = SelectionContext::new(infcx, typer);
let mut selcx = SelectionContext::new(infcx);
let cause = ObligationCause::new(span, body_id, MiscObligation);
let Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, value);
debug!("normalize_associated_types_in: result={:?} predicates={:?}",

View File

@ -27,7 +27,7 @@ use super::write_call;
use CrateCtxt;
use middle::infer;
use middle::ty::{self, Ty, ClosureTyper};
use middle::ty::{self, Ty};
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token;

View File

@ -125,7 +125,7 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
expected_vid: ty::TyVid)
-> (Option<ty::FnSig<'tcx>>, Option<ty::ClosureKind>)
{
let fulfillment_cx = fcx.inh.fulfillment_cx.borrow();
let fulfillment_cx = fcx.inh.infcx.fulfillment_cx.borrow();
// Here `expected_ty` is known to be a type inference variable.
let expected_sig =

View File

@ -273,7 +273,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
};
let source = source.adjust_for_autoref(self.tcx(), reborrow);
let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx());
let mut selcx = traits::SelectionContext::new(self.fcx.infcx());
// Use a FIFO queue for this custom fulfillment procedure.
let mut queue = VecDeque::new();

View File

@ -43,8 +43,8 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
impl_trait_ref);
let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
let mut fulfillment_cx = infcx.fulfillment_cx.borrow_mut();
let trait_to_impl_substs = &impl_trait_ref.substs;
@ -246,7 +246,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("compare_impl_method: trait_bounds={:?}",
infcx.parameter_environment.caller_bounds);
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
let mut selcx = traits::SelectionContext::new(&infcx);
for predicate in impl_pred.fns {
let traits::Normalized { value: predicate, .. } =
@ -293,7 +293,6 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_sig.subst(tcx, impl_to_skol_substs);
let impl_sig =
assoc::normalize_associated_types_in(&infcx,
&impl_param_env,
&mut fulfillment_cx,
impl_m_span,
impl_m_body_id,
@ -312,7 +311,6 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_sig.subst(tcx, &trait_to_skol_substs);
let trait_sig =
assoc::normalize_associated_types_in(&infcx,
&impl_param_env,
&mut fulfillment_cx,
impl_m_span,
impl_m_body_id,
@ -347,7 +345,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
// Check that all obligations are satisfied by the implementation's
// version.
match fulfillment_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
match fulfillment_cx.select_all_or_error(&infcx) {
Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) }
Ok(_) => {}
}
@ -419,8 +417,8 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("compare_const_impl(impl_trait_ref={:?})",
impl_trait_ref);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true);
let mut fulfillment_cx = infcx.fulfillment_cx.borrow_mut();
// The below is for the most part highly similar to the procedure
// for methods above. It is simpler in many respects, especially
@ -456,21 +454,21 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
// There is no "body" here, so just pass dummy id.
let impl_ty =
assoc::normalize_associated_types_in(&infcx,
&impl_param_env,
&mut fulfillment_cx,
impl_c_span,
0,
&impl_ty);
debug!("compare_const_impl: impl_ty={:?}",
impl_ty);
let trait_ty =
assoc::normalize_associated_types_in(&infcx,
&impl_param_env,
&mut fulfillment_cx,
impl_c_span,
0,
&trait_ty);
debug!("compare_const_impl: trait_ty={:?}",
trait_ty);

View File

@ -93,7 +93,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
ty: named_type } =
tcx.lookup_item_type(self_type_did);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
infcx.commit_if_ok(|snapshot| {
let (named_type_to_skolem, skol_map) =

View File

@ -12,7 +12,6 @@ use super::probe;
use check::{self, FnCtxt, NoPreference, PreferMutLvalue, callee, demand};
use check::UnresolvedTypeAction;
use middle::mem_categorization::Typer;
use middle::subst::{self};
use middle::traits;
use middle::ty::{self, Ty};

View File

@ -195,7 +195,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
poly_trait_ref.to_predicate());
// Now we want to know if this can be matched
let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx.infcx());
let mut selcx = traits::SelectionContext::new(fcx.infcx());
if !selcx.evaluate_obligation(&obligation) {
debug!("--> Cannot match obligation");
return None; // Cannot be matched, no such method resolution is possible.

View File

@ -421,7 +421,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// We can't use normalize_associated_types_in as it will pollute the
// fcx's fulfillment context after this probe is over.
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx());
let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx());
let traits::Normalized { value: xform_self_ty, obligations } =
traits::normalize(selcx, cause, &xform_self_ty);
debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}",
@ -681,7 +681,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// as it will pollute the fcx's fulfillment context after this probe
// is over.
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx());
let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx());
let traits::Normalized { value: xform_self_ty, obligations } =
traits::normalize(selcx, cause, &xform_self_ty);
@ -1076,7 +1076,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
match probe.kind {
InherentImplCandidate(impl_def_id, ref substs, ref ref_obligations) |
ExtensionImplCandidate(impl_def_id, _, ref substs, _, ref ref_obligations) => {
let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx.infcx());
let selcx = &mut traits::SelectionContext::new(self.infcx());
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
// Check whether the impl imposes obligations we have to worry about.

View File

@ -102,7 +102,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let obligation = Obligation::misc(span,
fcx.body_id,
poly_trait_ref.to_predicate());
let mut selcx = SelectionContext::new(infcx, fcx.infcx());
let mut selcx = SelectionContext::new(infcx);
if selcx.evaluate_obligation(&obligation) {
span_stored_function();

View File

@ -158,9 +158,6 @@ pub struct Inherited<'a, 'tcx: 'a> {
// one is never copied into the tcx: it is only used by regionck.
fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
// Tracks trait obligations incurred during this function body.
fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
// When we process a call like `c()` where `c` is a closure type,
// we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
// `FnOnce` closure. In that case, we defer full resolution of the
@ -295,28 +292,26 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
-> Inherited<'a, 'tcx> {
Inherited {
infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
locals: RefCell::new(NodeMap()),
tables: tables,
fn_sig_map: RefCell::new(NodeMap()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)),
deferred_call_resolutions: RefCell::new(DefIdMap()),
deferred_cast_checks: RefCell::new(Vec::new()),
}
}
fn normalize_associated_types_in<T>(&self,
typer: &ty::ClosureTyper<'tcx>,
span: Span,
body_id: ast::NodeId,
value: &T)
-> T
where T : TypeFoldable<'tcx> + HasTypeFlags
{
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
assoc::normalize_associated_types_in(&self.infcx,
typer,
&mut *fulfillment_cx, span,
&mut fulfillment_cx,
span,
body_id,
value)
}
@ -431,8 +426,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
&fn_sig);
let fn_sig =
inh.normalize_associated_types_in(&inh.infcx.parameter_environment,
body.span,
inh.normalize_associated_types_in(body.span,
body.id,
&fn_sig);
@ -1377,7 +1371,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
where T : TypeFoldable<'tcx> + HasTypeFlags
{
self.inh.normalize_associated_types_in(self.infcx(), span, self.body_id, value)
self.inh.normalize_associated_types_in(span, self.body_id, value)
}
fn normalize_associated_type(&self,
@ -1389,10 +1383,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let cause = traits::ObligationCause::new(span,
self.body_id,
traits::ObligationCauseCode::MiscObligation);
self.inh.fulfillment_cx
self.inh
.infcx
.fulfillment_cx
.borrow_mut()
.normalize_projection_type(self.infcx(),
self.infcx(),
ty::ProjectionTy {
trait_ref: trait_ref,
item_name: item_name,
@ -1502,7 +1497,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-> bool
{
traits::type_known_to_meet_builtin_bound(self.infcx(),
self.param_env(),
ty,
ty::BoundSized,
span)
@ -1513,7 +1507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
builtin_bound: ty::BuiltinBound,
cause: traits::ObligationCause<'tcx>)
{
self.inh.fulfillment_cx.borrow_mut()
self.inh.infcx.fulfillment_cx.borrow_mut()
.register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
}
@ -1522,7 +1516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
debug!("register_predicate({:?})",
obligation);
self.inh.fulfillment_cx
self.inh.infcx.fulfillment_cx
.borrow_mut()
.register_predicate_obligation(self.infcx(), obligation);
}
@ -1648,7 +1642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
region: ty::Region,
cause: traits::ObligationCause<'tcx>)
{
let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
fulfillment_cx.register_region_obligation(ty, region, cause);
}
@ -1747,8 +1741,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
self.select_all_obligations_and_apply_defaults();
let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) {
let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
match fulfillment_cx.select_all_or_error(self.infcx()) {
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
}
@ -1757,9 +1751,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Select as many obligations as we can at present.
fn select_obligations_where_possible(&self) {
match
self.inh.fulfillment_cx
self.inh.infcx.fulfillment_cx
.borrow_mut()
.select_where_possible(self.infcx(), self.infcx())
.select_where_possible(self.infcx())
{
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
@ -1772,9 +1766,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// work.
fn select_new_obligations(&self) {
match
self.inh.fulfillment_cx
self.inh.infcx.fulfillment_cx
.borrow_mut()
.select_new_obligations(self.infcx(), self.infcx())
.select_new_obligations(self.infcx())
{
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }

View File

@ -86,13 +86,12 @@ use astconv::AstConv;
use check::dropck;
use check::FnCtxt;
use middle::free_region::FreeRegionMap;
use middle::infer::InferCtxt;
use middle::implicator;
use middle::mem_categorization as mc;
use middle::region::CodeExtent;
use middle::subst::Substs;
use middle::traits;
use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall, HasTypeFlags};
use middle::ty::{self, ReScope, Ty, MethodCall, HasTypeFlags};
use middle::infer::{self, GenericKind};
use middle::pat_util;
@ -318,9 +317,13 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
// Make a copy of the region obligations vec because we'll need
// to be able to borrow the fulfillment-cx below when projecting.
let region_obligations =
self.fcx.inh.fulfillment_cx.borrow()
.region_obligations(node_id)
.to_vec();
self.fcx
.inh
.infcx
.fulfillment_cx
.borrow()
.region_obligations(node_id)
.to_vec();
for r_o in &region_obligations {
debug!("visit_region_obligations: r_o={:?}",
@ -332,7 +335,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
// Processing the region obligations should not cause the list to grow further:
assert_eq!(region_obligations.len(),
self.fcx.inh.fulfillment_cx.borrow().region_obligations(node_id).len());
self.fcx.inh.infcx.fulfillment_cx.borrow().region_obligations(node_id).len());
}
/// This method populates the region map's `free_region_map`. It walks over the transformed
@ -356,7 +359,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
debug!("relate_free_regions(t={:?})", ty);
let body_scope = CodeExtent::from_node_id(body_id);
let body_scope = ty::ReScope(body_scope);
let implications = implicator::implications(self.fcx.infcx(), self.fcx.infcx(), body_id,
let implications = implicator::implications(self.fcx.infcx(), body_id,
ty, body_scope, span);
// Record any relations between free regions that we observe into the free-region-map.
@ -1097,8 +1100,8 @@ fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) {
/// Link lifetimes of any ref bindings in `root_pat` to the pointers found in the discriminant, if
/// needed.
fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
mc: mc::MemCategorizationContext<InferCtxt<'a, 'tcx>>,
fn link_pattern<'t, 'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
mc: mc::MemCategorizationContext<'t, 'a, 'tcx>,
discr_cmt: mc::cmt<'tcx>,
root_pat: &ast::Pat) {
debug!("link_pattern(discr_cmt={:?}, root_pat={:?})",
@ -1405,7 +1408,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
ty,
region);
let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx.infcx(), rcx.body_id,
let implications = implicator::implications(rcx.fcx.infcx(), rcx.body_id,
ty, region, origin.span());
for implication in implications {
debug!("implication: {:?}", implication);

View File

@ -268,7 +268,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id());
let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref);
let predicates = {
let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx.infcx());
let selcx = &mut traits::SelectionContext::new(fcx.infcx());
traits::normalize(selcx, cause.clone(), &predicates)
};
for predicate in predicates.value.predicates {

View File

@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
source, target);
let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env));
let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env), true);
let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
@ -531,7 +531,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
}
};
let mut fulfill_cx = traits::FulfillmentContext::new(true);
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
// Register an obligation for `A: Trait<B>`.
let cause = traits::ObligationCause::misc(span, impl_did.node);
@ -540,8 +540,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
fulfill_cx.register_predicate_obligation(&infcx, predicate);
// Check that all transitive obligations are satisfied.
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx,
&infcx.parameter_environment) {
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
traits::report_fulfillment_errors(&infcx, &errors);
}
@ -632,7 +631,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
pub fn check_coherence(crate_context: &CrateCtxt) {
CoherenceChecker {
crate_context: crate_context,
inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None),
inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, true),
inherent_impls: RefCell::new(FnvHashMap()),
}.check(crate_context.tcx.map.krate());
unsafety::check(crate_context.tcx);

View File

@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
impl1_def_id,
impl2_def_id);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false);
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
}

View File

@ -2211,7 +2211,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
base_type,
base_type_free);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
drop(::require_same_types(tcx,
Some(&infcx),
false,

View File

@ -188,7 +188,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
{
let result = match maybe_infcx {
None => {
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
}
Some(infcx) => {