diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index dfca7b924b12..2ea2978b2940 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -175,12 +175,6 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // any obligations set during the current snapshot. In that case, the // snapshot can't be rolled back. pub obligations_in_snapshot: Cell, - - // This is false except during closure kind inference. It is used - // by the mem-categorization code to be able to have stricter - // assertions (which are always true except during upvar - // inference). - during_closure_kind_inference: Cell, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -497,7 +491,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { tainted_by_errors_flag: Cell::new(false), err_count_on_creation: self.sess.err_count(), obligations_in_snapshot: Cell::new(false), - during_closure_kind_inference: Cell::new(false), } } } @@ -539,7 +532,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { tainted_by_errors_flag: Cell::new(false), err_count_on_creation: tcx.sess.err_count(), obligations_in_snapshot: Cell::new(false), - during_closure_kind_inference: Cell::new(false), })) } } @@ -1302,14 +1294,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .map(|method| resolve_ty(method.ty))) } - pub fn set_during_closure_kind_inference(&self, value: bool) { - self.during_closure_kind_inference.set(value); - } - - pub fn during_closure_kind_inference(&self) -> bool { - self.during_closure_kind_inference.get() - } - /// True if errors have been reported since this infcx was /// created. This is sometimes used as a heuristic to skip /// reporting errors that often occur as a result of earlier diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 6551e0129f88..18b80a9636b4 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -271,10 +271,19 @@ enum PassArgs { impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pub fn new(delegate: &'a mut (Delegate<'tcx>+'a), - infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self + infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) + -> Self + { + ExprUseVisitor::with_options(delegate, infcx, mc::MemCategorizationOptions::default()) + } + + pub fn with_options(delegate: &'a mut (Delegate<'tcx>+'a), + infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + options: mc::MemCategorizationOptions) + -> Self { ExprUseVisitor { - mc: mc::MemCategorizationContext::new(infcx), + mc: mc::MemCategorizationContext::with_options(infcx, options), delegate: delegate } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index e4308aabf5f7..0bc3c1ae899d 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -259,6 +259,18 @@ impl ast_node for hir::Pat { #[derive(Copy, Clone)] pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + options: MemCategorizationOptions, +} + +#[derive(Copy, Clone, Default)] +pub struct MemCategorizationOptions { + // If true, then when analyzing a closure upvar, if the closure + // has a missing kind, we treat it like a Fn closure. When false, + // we ICE if the closure has a missing kind. Should be false + // except during closure kind inference. It is used by the + // mem-categorization code to be able to have stricter assertions + // (which are always true except during upvar inference). + pub during_closure_kind_inference: bool, } pub type McResult = Result; @@ -362,8 +374,15 @@ impl MutabilityCategory { impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> MemCategorizationContext<'a, 'gcx, 'tcx> { + MemCategorizationContext::with_options(infcx, MemCategorizationOptions::default()) + } + + pub fn with_options(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + options: MemCategorizationOptions) + -> MemCategorizationContext<'a, 'gcx, 'tcx> { MemCategorizationContext { infcx: infcx, + options: options, } } @@ -586,7 +605,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { self.cat_upvar(id, span, var_id, fn_node_id, kind) } None => { - if !self.infcx.during_closure_kind_inference() { + if !self.options.during_closure_kind_inference { span_bug!( span, "No closure kind for {:?}", diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index c1ffc668bc26..71490423f73f 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -171,10 +171,13 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id); { - self.fcx.set_during_closure_kind_inference(true); - let mut euv = euv::ExprUseVisitor::new(self, self.fcx); + let mut euv = + euv::ExprUseVisitor::with_options(self, + self.fcx, + mc::MemCategorizationOptions { + during_closure_kind_inference: true + }); euv.walk_fn(decl, body); - self.fcx.set_during_closure_kind_inference(false); } // Now that we've analyzed the closure, we know how each