Include context info into closure_kinds
This commit is contained in:
parent
5b13bff520
commit
7748bc665d
6 changed files with 35 additions and 19 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue