mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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:
commit
560b1dab15
@ -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;
|
||||
|
@ -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, ¶m_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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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: ¶m_env };
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut delegate, ¶m_env);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx);
|
||||
euv.walk_fn(fd, b);
|
||||
}
|
||||
visit::walk_fn(self, fk, fd, b, s)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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> {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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(),
|
||||
|
@ -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 {
|
||||
|
@ -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: ¶m_env,
|
||||
param_env: &infcx.parameter_environment
|
||||
};
|
||||
|
||||
{
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut clcx, ¶m_env);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut clcx, &infcx);
|
||||
euv.walk_fn(decl, body);
|
||||
}
|
||||
}
|
||||
|
@ -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, ¶m_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(¶m_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.
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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(¶meter_environment, item.span) {
|
||||
return;
|
||||
}
|
||||
if parameter_environment.can_type_implement_copy(ty, item.span).is_ok() {
|
||||
|
@ -43,7 +43,6 @@
|
||||
#![feature(unicode)]
|
||||
#![feature(unicode)]
|
||||
#![feature(vec_push_all)]
|
||||
#![feature(cell_extras)]
|
||||
|
||||
#![allow(trivial_casts)]
|
||||
|
||||
|
@ -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(¶m_env, span) || reassigned =>
|
||||
{
|
||||
llmatch = alloca_no_lifetime(bcx,
|
||||
llvariable_ty.ptr_to(),
|
||||
|
@ -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() {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) => {
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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('>');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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={:?}",
|
||||
|
@ -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};
|
||||
|
@ -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::*;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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={:?}",
|
||||
|
@ -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;
|
||||
|
@ -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 =
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) =
|
||||
|
@ -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};
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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); }
|
||||
|
@ -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 ®ion_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);
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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) => {
|
||||
|
Loading…
Reference in New Issue
Block a user