about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTommy Ip <hkmp7tommy@gmail.com>2017-05-24 16:23:02 +0100
committerTommy Ip <hkmp7tommy@gmail.com>2017-05-24 16:23:02 +0100
commit7748bc665d012042d2fe8bbda416ab4682ae45ba (patch)
treec3868d20dec1560e7c8bc46e6fdd618c4f944f8d /src
parent5b13bff5203c1bdc6ac6dc87f69b5359a9503078 (diff)
downloadrust-7748bc665d012042d2fe8bbda416ab4682ae45ba.tar.gz
rust-7748bc665d012042d2fe8bbda416ab4682ae45ba.zip
Include context info into closure_kinds
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/mod.rs6
-rw-r--r--src/librustc/ty/context.rs6
-rw-r--r--src/librustc_typeck/check/closure.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/check/upvar.rs36
6 files changed, 35 insertions, 19 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 270430f40df..a6dbbee79a4 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1682,7 +1682,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     {
         if let InferTables::InProgress(tables) = self.tables {
             if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
-                return tables.borrow().closure_kinds.get(&id).cloned();
+                return tables.borrow()
+                             .closure_kinds
+                             .get(&id)
+                             .cloned()
+                             .map(|(kind, _)| kind);
             }
         }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5ee0b1c9e5e..bc9fd1147b6 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -58,6 +58,7 @@ use syntax::abi;
 use syntax::ast::{self, Name, NodeId};
 use syntax::attr;
 use syntax::symbol::{Symbol, keywords};
+use syntax_pos::Span;
 
 use hir;
 
@@ -229,8 +230,9 @@ pub struct TypeckTables<'tcx> {
     /// Records the type of each closure.
     pub closure_tys: NodeMap<ty::PolyFnSig<'tcx>>,
 
-    /// Records the kind of each closure.
-    pub closure_kinds: NodeMap<ty::ClosureKind>,
+    /// Records the kind of each closure and the span of the variable that
+    /// cause the closure to be this kind.
+    pub closure_kinds: NodeMap<(ty::ClosureKind, Option<Span>)>,
 
     /// For each fn, records the "liberated" types of its arguments
     /// and return type. Liberated means that all bound regions
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 4c3d5c8aaca..c2e8269aafe 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         self.tables.borrow_mut().closure_tys.insert(expr.id, sig);
         match opt_kind {
             Some(kind) => {
-                self.tables.borrow_mut().closure_kinds.insert(expr.id, kind);
+                self.tables.borrow_mut().closure_kinds.insert(expr.id, (kind, None));
             }
             None => {}
         }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 9ad72b2a137..7981df9211a 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -802,7 +802,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
 
             let closure_kinds = &self.tables.borrow().closure_kinds;
             let closure_kind = match closure_kinds.get(&closure_id) {
-                Some(&k) => k,
+                Some(&(k, _)) => k,
                 None => {
                     return Err(MethodError::ClosureAmbiguity(trait_def_id));
                 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 24a88140cf0..06af22b9a41 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -702,7 +702,7 @@ fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           def_id: DefId)
                           -> ty::ClosureKind {
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    tcx.typeck_tables_of(def_id).closure_kinds[&node_id]
+    tcx.typeck_tables_of(def_id).closure_kinds[&node_id].0
 }
 
 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 9bfc5f3f0ea..3d5cb13b0ee 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
 struct SeedBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
-    temp_closure_kinds: NodeMap<ty::ClosureKind>,
+    temp_closure_kinds: NodeMap<(ty::ClosureKind, Option<Span>)>,
 }
 
 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for SeedBorrowKind<'a, 'gcx, 'tcx> {
@@ -107,7 +107,7 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
                      capture_clause: hir::CaptureClause)
     {
         if !self.fcx.tables.borrow().closure_kinds.contains_key(&expr.id) {
-            self.temp_closure_kinds.insert(expr.id, ty::ClosureKind::Fn);
+            self.temp_closure_kinds.insert(expr.id, (ty::ClosureKind::Fn, None));
             debug!("check_closure: adding closure {:?} as Fn", expr.id);
         }
 
@@ -143,12 +143,12 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
 
 struct AdjustBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
-    temp_closure_kinds: NodeMap<ty::ClosureKind>,
+    temp_closure_kinds: NodeMap<(ty::ClosureKind, Option<Span>)>,
 }
 
 impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
     fn new(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
-           temp_closure_kinds: NodeMap<ty::ClosureKind>)
+           temp_closure_kinds: NodeMap<(ty::ClosureKind, Option<Span>)>)
            -> AdjustBorrowKind<'a, 'gcx, 'tcx> {
         AdjustBorrowKind { fcx: fcx, temp_closure_kinds: temp_closure_kinds }
     }
@@ -211,8 +211,8 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
 
         // If we are also inferred the closure kind here, update the
         // main table and process any deferred resolutions.
-        if let Some(&kind) = self.temp_closure_kinds.get(&id) {
-            self.fcx.tables.borrow_mut().closure_kinds.insert(id, kind);
+        if let Some(&(kind, span)) = self.temp_closure_kinds.get(&id) {
+            self.fcx.tables.borrow_mut().closure_kinds.insert(id, (kind, span));
             let closure_def_id = self.fcx.tcx.hir.local_def_id(id);
             debug!("closure_kind({:?}) = {:?}", closure_def_id, kind);
 
@@ -276,6 +276,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
         // for that to be legal, the upvar would have to be borrowed
         // by value instead
         let guarantor = cmt.guarantor();
+        let tcx = self.fcx.tcx;
         debug!("adjust_upvar_borrow_kind_for_consume: guarantor={:?}",
                guarantor);
         match guarantor.cat {
@@ -289,7 +290,8 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
 
                         // to move out of an upvar, this must be a FnOnce closure
                         self.adjust_closure_kind(upvar_id.closure_expr_id,
-                                                 ty::ClosureKind::FnOnce);
+                                                 ty::ClosureKind::FnOnce,
+                                                 tcx.hir.span(upvar_id.var_id));
 
                         let upvar_capture_map =
                             &mut self.fcx.tables.borrow_mut().upvar_capture_map;
@@ -303,7 +305,8 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
                         // to be a FnOnce closure to permit moves out
                         // of the environment.
                         self.adjust_closure_kind(upvar_id.closure_expr_id,
-                                                 ty::ClosureKind::FnOnce);
+                                                 ty::ClosureKind::FnOnce,
+                                                 tcx.hir.span(upvar_id.var_id));
                     }
                     mc::NoteNone => {
                     }
@@ -394,6 +397,8 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
             ty::ImmBorrow => false,
         });
 
+        let tcx = self.fcx.tcx;
+
         match *note {
             mc::NoteUpvarRef(upvar_id) => {
                 // if this is an implicit deref of an
@@ -407,7 +412,9 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
                 }
 
                 // also need to be in an FnMut closure since this is not an ImmBorrow
-                self.adjust_closure_kind(upvar_id.closure_expr_id, ty::ClosureKind::FnMut);
+                self.adjust_closure_kind(upvar_id.closure_expr_id,
+                                         ty::ClosureKind::FnMut,
+                                         tcx.hir.span(upvar_id.var_id));
 
                 true
             }
@@ -415,7 +422,9 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
                 // this kind of deref occurs in a `move` closure, or
                 // for a by-value upvar; in either case, to mutate an
                 // upvar, we need to be an FnMut closure
-                self.adjust_closure_kind(upvar_id.closure_expr_id, ty::ClosureKind::FnMut);
+                self.adjust_closure_kind(upvar_id.closure_expr_id,
+                                         ty::ClosureKind::FnMut,
+                                         tcx.hir.span(upvar_id.var_id));
 
                 true
             }
@@ -462,11 +471,12 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
 
     fn adjust_closure_kind(&mut self,
                            closure_id: ast::NodeId,
-                           new_kind: ty::ClosureKind) {
+                           new_kind: ty::ClosureKind,
+                           upvar_span: Span) {
         debug!("adjust_closure_kind(closure_id={}, new_kind={:?})",
                closure_id, new_kind);
 
-        if let Some(&existing_kind) = self.temp_closure_kinds.get(&closure_id) {
+        if let Some(&(existing_kind, _)) = self.temp_closure_kinds.get(&closure_id) {
             debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
                    closure_id, existing_kind, new_kind);
 
@@ -482,7 +492,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
                 (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) |
                 (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
                     // new kind is stronger than the old kind
-                    self.temp_closure_kinds.insert(closure_id, new_kind);
+                    self.temp_closure_kinds.insert(closure_id, (new_kind, Some(upvar_span)));
                 }
             }
         }