rustc: move freevar finding to resolve.
This commit is contained in:
parent
5c192ae123
commit
7c5df404b0
@ -17,7 +17,7 @@ use lint;
|
|||||||
use llvm::{ContextRef, ModuleRef};
|
use llvm::{ContextRef, ModuleRef};
|
||||||
use metadata::common::LinkMeta;
|
use metadata::common::LinkMeta;
|
||||||
use metadata::creader;
|
use metadata::creader;
|
||||||
use middle::{trans, freevars, stability, kind, ty, typeck, reachable};
|
use middle::{trans, stability, kind, ty, typeck, reachable};
|
||||||
use middle::dependency_format;
|
use middle::dependency_format;
|
||||||
use middle;
|
use middle;
|
||||||
use plugin::load::Plugins;
|
use plugin::load::Plugins;
|
||||||
@ -378,11 +378,13 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
|||||||
middle::lang_items::collect_language_items(krate, &sess));
|
middle::lang_items::collect_language_items(krate, &sess));
|
||||||
|
|
||||||
let middle::resolve::CrateMap {
|
let middle::resolve::CrateMap {
|
||||||
def_map: def_map,
|
def_map,
|
||||||
exp_map2: exp_map2,
|
freevars,
|
||||||
trait_map: trait_map,
|
capture_mode_map,
|
||||||
external_exports: external_exports,
|
exp_map2,
|
||||||
last_private_map: last_private_map
|
trait_map,
|
||||||
|
external_exports,
|
||||||
|
last_private_map
|
||||||
} =
|
} =
|
||||||
time(time_passes, "resolution", (), |_|
|
time(time_passes, "resolution", (), |_|
|
||||||
middle::resolve::resolve_crate(&sess, &lang_items, krate));
|
middle::resolve::resolve_crate(&sess, &lang_items, krate));
|
||||||
@ -401,10 +403,6 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
|||||||
plugin::build::find_plugin_registrar(
|
plugin::build::find_plugin_registrar(
|
||||||
sess.diagnostic(), krate)));
|
sess.diagnostic(), krate)));
|
||||||
|
|
||||||
let (freevars, capture_modes) =
|
|
||||||
time(time_passes, "freevar finding", (), |_|
|
|
||||||
freevars::annotate_freevars(&def_map, krate));
|
|
||||||
|
|
||||||
let region_map = time(time_passes, "region resolution", (), |_|
|
let region_map = time(time_passes, "region resolution", (), |_|
|
||||||
middle::region::resolve_crate(&sess, krate));
|
middle::region::resolve_crate(&sess, krate));
|
||||||
|
|
||||||
@ -423,7 +421,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
|||||||
named_region_map,
|
named_region_map,
|
||||||
ast_map,
|
ast_map,
|
||||||
freevars,
|
freevars,
|
||||||
capture_modes,
|
capture_mode_map,
|
||||||
region_map,
|
region_map,
|
||||||
lang_items,
|
lang_items,
|
||||||
stability_index);
|
stability_index);
|
||||||
|
@ -93,7 +93,6 @@ pub mod middle {
|
|||||||
pub mod effect;
|
pub mod effect;
|
||||||
pub mod entry;
|
pub mod entry;
|
||||||
pub mod expr_use_visitor;
|
pub mod expr_use_visitor;
|
||||||
pub mod freevars;
|
|
||||||
pub mod graph;
|
pub mod graph;
|
||||||
pub mod intrinsicck;
|
pub mod intrinsicck;
|
||||||
pub mod kind;
|
pub mod kind;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::freevars;
|
|
||||||
use middle::mem_categorization::Typer;
|
use middle::mem_categorization::Typer;
|
||||||
use middle::pat_util;
|
use middle::pat_util;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
// A pass that annotates for each loops and functions with the free
|
|
||||||
// variables that they contain.
|
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
use middle::def;
|
|
||||||
use middle::resolve;
|
|
||||||
use middle::ty;
|
|
||||||
use util::nodemap::{NodeMap, NodeSet};
|
|
||||||
|
|
||||||
use syntax::ast;
|
|
||||||
use syntax::codemap::Span;
|
|
||||||
use syntax::visit::Visitor;
|
|
||||||
use syntax::visit;
|
|
||||||
|
|
||||||
struct CollectFreevarsVisitor<'a, 'b:'a> {
|
|
||||||
node_id: ast::NodeId,
|
|
||||||
seen: NodeSet,
|
|
||||||
cx: &'a mut AnnotateFreevarsVisitor<'b>,
|
|
||||||
depth: u32
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, 'v> Visitor<'v> for CollectFreevarsVisitor<'a, 'b> {
|
|
||||||
fn visit_item(&mut self, _: &ast::Item) {
|
|
||||||
// ignore_item
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_expr(&mut self, expr: &ast::Expr) {
|
|
||||||
match expr.node {
|
|
||||||
ast::ExprProc(..) => {
|
|
||||||
self.cx.capture_mode_map.insert(expr.id, ast::CaptureByValue);
|
|
||||||
self.depth += 1;
|
|
||||||
visit::walk_expr(self, expr);
|
|
||||||
self.depth -= 1;
|
|
||||||
}
|
|
||||||
ast::ExprFnBlock(_, _, _) => {
|
|
||||||
// NOTE(stage0): After snapshot, change to:
|
|
||||||
//
|
|
||||||
//self.cx.capture_mode_map.insert(expr.id, capture_clause);
|
|
||||||
self.cx.capture_mode_map.insert(expr.id, ast::CaptureByRef);
|
|
||||||
self.depth += 1;
|
|
||||||
visit::walk_expr(self, expr);
|
|
||||||
self.depth -= 1;
|
|
||||||
}
|
|
||||||
ast::ExprUnboxedFn(capture_clause, _, _, _) => {
|
|
||||||
self.cx.capture_mode_map.insert(expr.id, capture_clause);
|
|
||||||
self.depth += 1;
|
|
||||||
visit::walk_expr(self, expr);
|
|
||||||
self.depth -= 1;
|
|
||||||
}
|
|
||||||
ast::ExprPath(..) => {
|
|
||||||
let def = *self.cx.def_map.borrow().find(&expr.id)
|
|
||||||
.expect("path not found");
|
|
||||||
let dnum = def.def_id().node;
|
|
||||||
if self.seen.contains(&dnum) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let def = match def {
|
|
||||||
def::DefUpvar(_, _, depth, _, _) => {
|
|
||||||
if depth < self.depth {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mut def = def;
|
|
||||||
for _ in range(0, depth - self.depth) {
|
|
||||||
match def {
|
|
||||||
def::DefUpvar(_, inner, _, _, _) => { def = *inner; }
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def
|
|
||||||
},
|
|
||||||
_ => return
|
|
||||||
};
|
|
||||||
self.cx.freevars.find_or_insert(self.node_id, vec![]).push(ty::Freevar {
|
|
||||||
def: def,
|
|
||||||
span: expr.span,
|
|
||||||
});
|
|
||||||
self.seen.insert(dnum);
|
|
||||||
}
|
|
||||||
_ => visit::walk_expr(self, expr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AnnotateFreevarsVisitor<'a> {
|
|
||||||
def_map: &'a resolve::DefMap,
|
|
||||||
freevars: ty::FreevarMap,
|
|
||||||
capture_mode_map: ty::CaptureModeMap,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'v> Visitor<'v> for AnnotateFreevarsVisitor<'a> {
|
|
||||||
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
|
|
||||||
blk: &'v ast::Block, s: Span, nid: ast::NodeId) {
|
|
||||||
CollectFreevarsVisitor {
|
|
||||||
node_id: nid,
|
|
||||||
seen: NodeSet::new(),
|
|
||||||
cx: self,
|
|
||||||
depth: 0
|
|
||||||
}.visit_block(blk);
|
|
||||||
visit::walk_fn(self, fk, fd, blk, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a map from every function and for-each body to a set of the
|
|
||||||
// freevars contained in it. The implementation is not particularly
|
|
||||||
// efficient as it fully recomputes the free variables at every
|
|
||||||
// node of interest rather than building up the free variables in
|
|
||||||
// one pass. This could be improved upon if it turns out to matter.
|
|
||||||
pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
|
|
||||||
-> (ty::FreevarMap, ty::CaptureModeMap) {
|
|
||||||
let mut visitor = AnnotateFreevarsVisitor {
|
|
||||||
def_map: def_map,
|
|
||||||
freevars: NodeMap::new(),
|
|
||||||
capture_mode_map: NodeMap::new(),
|
|
||||||
};
|
|
||||||
visit::walk_crate(&mut visitor, krate);
|
|
||||||
(visitor.freevars, visitor.capture_mode_map)
|
|
||||||
}
|
|
@ -103,7 +103,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use middle::def::*;
|
use middle::def::*;
|
||||||
use middle::freevars;
|
|
||||||
use middle::mem_categorization::Typer;
|
use middle::mem_categorization::Typer;
|
||||||
use middle::pat_util;
|
use middle::pat_util;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
|
@ -63,7 +63,6 @@
|
|||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::freevars;
|
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::typeck;
|
use middle::typeck;
|
||||||
use util::nodemap::{DefIdMap, NodeMap};
|
use util::nodemap::{DefIdMap, NodeMap};
|
||||||
|
@ -19,7 +19,8 @@ use middle::lang_items::LanguageItems;
|
|||||||
use middle::pat_util::pat_bindings;
|
use middle::pat_util::pat_bindings;
|
||||||
use middle::subst::{ParamSpace, FnSpace, TypeSpace};
|
use middle::subst::{ParamSpace, FnSpace, TypeSpace};
|
||||||
use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
|
use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
|
||||||
use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
|
use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
|
||||||
|
use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
|
||||||
|
|
||||||
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
|
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
|
||||||
use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
|
use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
|
||||||
@ -279,11 +280,7 @@ enum RibKind {
|
|||||||
|
|
||||||
// We passed through a closure scope at the given node ID.
|
// We passed through a closure scope at the given node ID.
|
||||||
// Translate upvars as appropriate.
|
// Translate upvars as appropriate.
|
||||||
ClosureRibKind(NodeId /* func id */),
|
ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
|
||||||
|
|
||||||
// We passed through a proc or unboxed closure scope at the given node ID.
|
|
||||||
// Translate upvars as appropriate.
|
|
||||||
ProcRibKind(NodeId /* func id */, NodeId /* body id */),
|
|
||||||
|
|
||||||
// We passed through an impl or trait and are now in one of its
|
// We passed through an impl or trait and are now in one of its
|
||||||
// methods. Allow references to ty params that impl or trait
|
// methods. Allow references to ty params that impl or trait
|
||||||
@ -895,6 +892,9 @@ struct Resolver<'a> {
|
|||||||
primitive_type_table: PrimitiveTypeTable,
|
primitive_type_table: PrimitiveTypeTable,
|
||||||
|
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
|
freevars: RefCell<FreevarMap>,
|
||||||
|
freevars_seen: RefCell<NodeMap<NodeSet>>,
|
||||||
|
capture_mode_map: RefCell<CaptureModeMap>,
|
||||||
export_map2: ExportMap2,
|
export_map2: ExportMap2,
|
||||||
trait_map: TraitMap,
|
trait_map: TraitMap,
|
||||||
external_exports: ExternalExports,
|
external_exports: ExternalExports,
|
||||||
@ -1000,6 +1000,9 @@ impl<'a> Resolver<'a> {
|
|||||||
primitive_type_table: PrimitiveTypeTable::new(),
|
primitive_type_table: PrimitiveTypeTable::new(),
|
||||||
|
|
||||||
def_map: RefCell::new(NodeMap::new()),
|
def_map: RefCell::new(NodeMap::new()),
|
||||||
|
freevars: RefCell::new(NodeMap::new()),
|
||||||
|
freevars_seen: RefCell::new(NodeMap::new()),
|
||||||
|
capture_mode_map: RefCell::new(NodeMap::new()),
|
||||||
export_map2: RefCell::new(NodeMap::new()),
|
export_map2: RefCell::new(NodeMap::new()),
|
||||||
trait_map: NodeMap::new(),
|
trait_map: NodeMap::new(),
|
||||||
used_imports: HashSet::new(),
|
used_imports: HashSet::new(),
|
||||||
@ -3831,75 +3834,56 @@ impl<'a> Resolver<'a> {
|
|||||||
self.current_module = orig_module;
|
self.current_module = orig_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the given definition in the appropriate number of `def_upvar`
|
/// Wraps the given definition in the appropriate number of `DefUpvar`
|
||||||
/// wrappers.
|
/// wrappers.
|
||||||
fn upvarify(&self,
|
fn upvarify(&self,
|
||||||
ribs: &[Rib],
|
ribs: &[Rib],
|
||||||
rib_index: uint,
|
|
||||||
def_like: DefLike,
|
def_like: DefLike,
|
||||||
span: Span)
|
span: Span)
|
||||||
-> Option<DefLike> {
|
-> Option<DefLike> {
|
||||||
let mut def;
|
|
||||||
let is_ty_param;
|
|
||||||
|
|
||||||
match def_like {
|
match def_like {
|
||||||
DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) => {
|
DlDef(d @ DefUpvar(..)) => {
|
||||||
def = d;
|
self.session.span_bug(span,
|
||||||
is_ty_param = false;
|
format!("unexpected {} in bindings", d).as_slice())
|
||||||
}
|
}
|
||||||
DlDef(d @ DefTyParam(..)) |
|
DlDef(d @ DefLocal(_)) => {
|
||||||
DlDef(d @ DefSelfTy(..)) => {
|
let node_id = d.def_id().node;
|
||||||
def = d;
|
let mut def = d;
|
||||||
is_ty_param = true;
|
let mut depth = 0;
|
||||||
}
|
let mut last_proc_body_id = ast::DUMMY_NODE_ID;
|
||||||
_ => {
|
for rib in ribs.iter() {
|
||||||
return Some(def_like);
|
match rib.kind {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut rib_index = rib_index + 1;
|
|
||||||
while rib_index < ribs.len() {
|
|
||||||
match ribs[rib_index].kind {
|
|
||||||
NormalRibKind => {
|
NormalRibKind => {
|
||||||
// Nothing to do. Continue.
|
// Nothing to do. Continue.
|
||||||
}
|
}
|
||||||
ClosureRibKind(function_id) => {
|
ClosureRibKind(function_id, maybe_proc_body) => {
|
||||||
if !is_ty_param {
|
let prev_def = def;
|
||||||
let (depth, block_id) = match def {
|
if maybe_proc_body != ast::DUMMY_NODE_ID {
|
||||||
DefUpvar(_, _, depth, _, block_id) => (depth + 1, block_id),
|
last_proc_body_id = maybe_proc_body;
|
||||||
_ => (0, ast::DUMMY_NODE_ID)
|
|
||||||
};
|
|
||||||
def = DefUpvar(def.def_id().node, box(GC) def, depth, function_id, block_id);
|
|
||||||
}
|
}
|
||||||
|
def = DefUpvar(node_id, box(GC) def,
|
||||||
|
depth, function_id, last_proc_body_id);
|
||||||
|
depth += 1;
|
||||||
|
|
||||||
|
let mut seen = self.freevars_seen.borrow_mut();
|
||||||
|
let seen = seen.find_or_insert(function_id, NodeSet::new());
|
||||||
|
if seen.contains(&node_id) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ProcRibKind(function_id, block_id) => {
|
self.freevars.borrow_mut().find_or_insert(function_id, vec![])
|
||||||
if !is_ty_param {
|
.push(Freevar { def: prev_def, span: span });
|
||||||
let depth = match def {
|
seen.insert(node_id);
|
||||||
DefUpvar(_, _, depth, _, _) => depth + 1,
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
def = DefUpvar(def.def_id().node, box(GC) def, depth, function_id, block_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
MethodRibKind(item_id, _) => {
|
MethodRibKind(item_id, _) => {
|
||||||
// If the def is a ty param, and came from the parent
|
// If the def is a ty param, and came from the parent
|
||||||
// item, it's ok
|
// item, it's ok
|
||||||
match def {
|
match def {
|
||||||
DefTyParam(_, did, _) if {
|
DefTyParam(_, did, _) if {
|
||||||
self.def_map.borrow().find(&did.node).map(|x| *x)
|
self.def_map.borrow().find_copy(&did.node)
|
||||||
== Some(DefTyParamBinder(item_id))
|
== Some(DefTyParamBinder(item_id))
|
||||||
} => {
|
} => {} // ok
|
||||||
// ok
|
DefSelfTy(did) if did == item_id => {} // ok
|
||||||
}
|
|
||||||
|
|
||||||
DefSelfTy(did) if {
|
|
||||||
did == item_id
|
|
||||||
} => {
|
|
||||||
// ok
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
if !is_ty_param {
|
|
||||||
// This was an attempt to access an upvar inside a
|
// This was an attempt to access an upvar inside a
|
||||||
// named function item. This is not allowed, so we
|
// named function item. This is not allowed, so we
|
||||||
// report an error.
|
// report an error.
|
||||||
@ -3908,22 +3892,12 @@ impl<'a> Resolver<'a> {
|
|||||||
span,
|
span,
|
||||||
"can't capture dynamic environment in a fn item; \
|
"can't capture dynamic environment in a fn item; \
|
||||||
use the || { ... } closure form instead");
|
use the || { ... } closure form instead");
|
||||||
} else {
|
|
||||||
// This was an attempt to use a type parameter outside
|
|
||||||
// its scope.
|
|
||||||
|
|
||||||
self.resolve_error(span,
|
|
||||||
"can't use type parameters from \
|
|
||||||
outer function; try using a local \
|
|
||||||
type parameter instead");
|
|
||||||
}
|
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemRibKind => {
|
ItemRibKind => {
|
||||||
if !is_ty_param {
|
|
||||||
// This was an attempt to access an upvar inside a
|
// This was an attempt to access an upvar inside a
|
||||||
// named function item. This is not allowed, so we
|
// named function item. This is not allowed, so we
|
||||||
// report an error.
|
// report an error.
|
||||||
@ -3932,7 +3906,38 @@ impl<'a> Resolver<'a> {
|
|||||||
span,
|
span,
|
||||||
"can't capture dynamic environment in a fn item; \
|
"can't capture dynamic environment in a fn item; \
|
||||||
use the || { ... } closure form instead");
|
use the || { ... } closure form instead");
|
||||||
} else {
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
ConstantItemRibKind => {
|
||||||
|
// Still doesn't deal with upvars
|
||||||
|
self.resolve_error(span,
|
||||||
|
"attempt to use a non-constant \
|
||||||
|
value in a constant");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(DlDef(def))
|
||||||
|
}
|
||||||
|
DlDef(def @ DefTyParam(..)) |
|
||||||
|
DlDef(def @ DefSelfTy(..)) => {
|
||||||
|
for rib in ribs.iter() {
|
||||||
|
match rib.kind {
|
||||||
|
NormalRibKind | ClosureRibKind(..) => {
|
||||||
|
// Nothing to do. Continue.
|
||||||
|
}
|
||||||
|
MethodRibKind(item_id, _) => {
|
||||||
|
// If the def is a ty param, and came from the parent
|
||||||
|
// item, it's ok
|
||||||
|
match def {
|
||||||
|
DefTyParam(_, did, _) if {
|
||||||
|
self.def_map.borrow().find_copy(&did.node)
|
||||||
|
== Some(DefTyParamBinder(item_id))
|
||||||
|
} => {} // ok
|
||||||
|
DefSelfTy(did) if did == item_id => {} // ok
|
||||||
|
|
||||||
|
_ => {
|
||||||
// This was an attempt to use a type parameter outside
|
// This was an attempt to use a type parameter outside
|
||||||
// its scope.
|
// its scope.
|
||||||
|
|
||||||
@ -3940,30 +3945,35 @@ impl<'a> Resolver<'a> {
|
|||||||
"can't use type parameters from \
|
"can't use type parameters from \
|
||||||
outer function; try using a local \
|
outer function; try using a local \
|
||||||
type parameter instead");
|
type parameter instead");
|
||||||
|
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ItemRibKind => {
|
||||||
|
// This was an attempt to use a type parameter outside
|
||||||
|
// its scope.
|
||||||
|
|
||||||
|
self.resolve_error(span,
|
||||||
|
"can't use type parameters from \
|
||||||
|
outer function; try using a local \
|
||||||
|
type parameter instead");
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
ConstantItemRibKind => {
|
ConstantItemRibKind => {
|
||||||
if is_ty_param {
|
|
||||||
// see #9186
|
// see #9186
|
||||||
self.resolve_error(span,
|
self.resolve_error(span,
|
||||||
"cannot use an outer type \
|
"cannot use an outer type \
|
||||||
parameter in this context");
|
parameter in this context");
|
||||||
} else {
|
|
||||||
// Still doesn't deal with upvars
|
|
||||||
self.resolve_error(span,
|
|
||||||
"attempt to use a non-constant \
|
|
||||||
value in a constant");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rib_index += 1;
|
|
||||||
}
|
}
|
||||||
|
Some(DlDef(def))
|
||||||
return Some(DlDef(def));
|
}
|
||||||
|
_ => Some(def_like)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search_ribs(&self,
|
fn search_ribs(&self,
|
||||||
@ -3971,16 +3981,12 @@ impl<'a> Resolver<'a> {
|
|||||||
name: Name,
|
name: Name,
|
||||||
span: Span)
|
span: Span)
|
||||||
-> Option<DefLike> {
|
-> Option<DefLike> {
|
||||||
// FIXME #4950: This should not use a while loop.
|
|
||||||
// FIXME #4950: Try caching?
|
// FIXME #4950: Try caching?
|
||||||
|
|
||||||
let mut i = ribs.len();
|
for (i, rib) in ribs.iter().enumerate().rev() {
|
||||||
while i != 0 {
|
match rib.bindings.borrow().find_copy(&name) {
|
||||||
i -= 1;
|
|
||||||
let binding_opt = ribs[i].bindings.borrow().find_copy(&name);
|
|
||||||
match binding_opt {
|
|
||||||
Some(def_like) => {
|
Some(def_like) => {
|
||||||
return self.upvarify(ribs, i, def_like, span);
|
return self.upvarify(ribs.slice_from(i + 1), def_like, span);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Continue.
|
// Continue.
|
||||||
@ -3988,7 +3994,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_crate(&mut self, krate: &ast::Crate) {
|
fn resolve_crate(&mut self, krate: &ast::Crate) {
|
||||||
@ -5773,13 +5779,23 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExprFnBlock(_, ref fn_decl, ref block) => {
|
ExprFnBlock(_, ref fn_decl, ref block) => {
|
||||||
self.resolve_function(ClosureRibKind(expr.id),
|
// NOTE(stage0): After snapshot, change to:
|
||||||
|
//
|
||||||
|
//self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
|
||||||
|
self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByRef);
|
||||||
|
self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
|
||||||
Some(&**fn_decl), NoTypeParameters,
|
Some(&**fn_decl), NoTypeParameters,
|
||||||
&**block);
|
&**block);
|
||||||
}
|
}
|
||||||
ExprProc(ref fn_decl, ref block) |
|
ExprProc(ref fn_decl, ref block) => {
|
||||||
ExprUnboxedFn(_, _, ref fn_decl, ref block) => {
|
self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByValue);
|
||||||
self.resolve_function(ProcRibKind(expr.id, block.id),
|
self.resolve_function(ClosureRibKind(expr.id, block.id),
|
||||||
|
Some(&**fn_decl), NoTypeParameters,
|
||||||
|
&**block);
|
||||||
|
}
|
||||||
|
ExprUnboxedFn(capture_clause, _, ref fn_decl, ref block) => {
|
||||||
|
self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
|
||||||
|
self.resolve_function(ClosureRibKind(expr.id, block.id),
|
||||||
Some(&**fn_decl), NoTypeParameters,
|
Some(&**fn_decl), NoTypeParameters,
|
||||||
&**block);
|
&**block);
|
||||||
}
|
}
|
||||||
@ -6210,6 +6226,8 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
pub struct CrateMap {
|
pub struct CrateMap {
|
||||||
pub def_map: DefMap,
|
pub def_map: DefMap,
|
||||||
|
pub freevars: RefCell<FreevarMap>,
|
||||||
|
pub capture_mode_map: RefCell<CaptureModeMap>,
|
||||||
pub exp_map2: ExportMap2,
|
pub exp_map2: ExportMap2,
|
||||||
pub trait_map: TraitMap,
|
pub trait_map: TraitMap,
|
||||||
pub external_exports: ExternalExports,
|
pub external_exports: ExternalExports,
|
||||||
@ -6223,13 +6241,13 @@ pub fn resolve_crate(session: &Session,
|
|||||||
-> CrateMap {
|
-> CrateMap {
|
||||||
let mut resolver = Resolver::new(session, krate.span);
|
let mut resolver = Resolver::new(session, krate.span);
|
||||||
resolver.resolve(krate);
|
resolver.resolve(krate);
|
||||||
let Resolver { def_map, export_map2, trait_map, last_private,
|
|
||||||
external_exports, .. } = resolver;
|
|
||||||
CrateMap {
|
CrateMap {
|
||||||
def_map: def_map,
|
def_map: resolver.def_map,
|
||||||
exp_map2: export_map2,
|
freevars: resolver.freevars,
|
||||||
trait_map: trait_map,
|
capture_mode_map: resolver.capture_mode_map,
|
||||||
external_exports: external_exports,
|
exp_map2: resolver.export_map2,
|
||||||
last_private_map: last_private,
|
trait_map: resolver.trait_map,
|
||||||
|
external_exports: resolver.external_exports,
|
||||||
|
last_private_map: resolver.last_private,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ use back::link::mangle_internal_name_by_path_and_seq;
|
|||||||
use driver::config::FullDebugInfo;
|
use driver::config::FullDebugInfo;
|
||||||
use llvm::ValueRef;
|
use llvm::ValueRef;
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::freevars;
|
|
||||||
use middle::mem_categorization::Typer;
|
use middle::mem_categorization::Typer;
|
||||||
use middle::trans::adt;
|
use middle::trans::adt;
|
||||||
use middle::trans::base::*;
|
use middle::trans::base::*;
|
||||||
|
@ -17,7 +17,6 @@ use llvm;
|
|||||||
use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
|
use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
|
||||||
use llvm::{True, False, Bool};
|
use llvm::{True, False, Bool};
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::freevars;
|
|
||||||
use middle::lang_items::LangItem;
|
use middle::lang_items::LangItem;
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
|
@ -1461,8 +1461,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
|||||||
dm: resolve::DefMap,
|
dm: resolve::DefMap,
|
||||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||||
map: ast_map::Map<'tcx>,
|
map: ast_map::Map<'tcx>,
|
||||||
freevars: FreevarMap,
|
freevars: RefCell<FreevarMap>,
|
||||||
capture_modes: CaptureModeMap,
|
capture_modes: RefCell<CaptureModeMap>,
|
||||||
region_maps: middle::region::RegionMaps,
|
region_maps: middle::region::RegionMaps,
|
||||||
lang_items: middle::lang_items::LanguageItems,
|
lang_items: middle::lang_items::LanguageItems,
|
||||||
stability: stability::Index) -> ctxt<'tcx> {
|
stability: stability::Index) -> ctxt<'tcx> {
|
||||||
@ -1483,7 +1483,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
|||||||
object_cast_map: RefCell::new(NodeMap::new()),
|
object_cast_map: RefCell::new(NodeMap::new()),
|
||||||
map: map,
|
map: map,
|
||||||
intrinsic_defs: RefCell::new(DefIdMap::new()),
|
intrinsic_defs: RefCell::new(DefIdMap::new()),
|
||||||
freevars: RefCell::new(freevars),
|
freevars: freevars,
|
||||||
tcache: RefCell::new(DefIdMap::new()),
|
tcache: RefCell::new(DefIdMap::new()),
|
||||||
rcache: RefCell::new(HashMap::new()),
|
rcache: RefCell::new(HashMap::new()),
|
||||||
short_names_cache: RefCell::new(HashMap::new()),
|
short_names_cache: RefCell::new(HashMap::new()),
|
||||||
@ -1520,7 +1520,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
|||||||
node_lint_levels: RefCell::new(HashMap::new()),
|
node_lint_levels: RefCell::new(HashMap::new()),
|
||||||
transmute_restrictions: RefCell::new(Vec::new()),
|
transmute_restrictions: RefCell::new(Vec::new()),
|
||||||
stability: RefCell::new(stability),
|
stability: RefCell::new(stability),
|
||||||
capture_modes: RefCell::new(capture_modes),
|
capture_modes: capture_modes,
|
||||||
associated_types: RefCell::new(DefIdMap::new()),
|
associated_types: RefCell::new(DefIdMap::new()),
|
||||||
trait_associated_types: RefCell::new(DefIdMap::new()),
|
trait_associated_types: RefCell::new(DefIdMap::new()),
|
||||||
}
|
}
|
||||||
@ -4755,7 +4755,7 @@ pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId)
|
|||||||
-> Vec<UnboxedClosureUpvar> {
|
-> Vec<UnboxedClosureUpvar> {
|
||||||
if closure_id.krate == ast::LOCAL_CRATE {
|
if closure_id.krate == ast::LOCAL_CRATE {
|
||||||
match tcx.freevars.borrow().find(&closure_id.node) {
|
match tcx.freevars.borrow().find(&closure_id.node) {
|
||||||
None => tcx.sess.bug("no freevars for unboxed closure?!"),
|
None => vec![],
|
||||||
Some(ref freevars) => {
|
Some(ref freevars) => {
|
||||||
freevars.iter().map(|freevar| {
|
freevars.iter().map(|freevar| {
|
||||||
let freevar_def_id = freevar.def.def_id();
|
let freevar_def_id = freevar.def.def_id();
|
||||||
@ -5701,7 +5701,7 @@ pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
|
|||||||
|
|
||||||
pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
|
pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
|
||||||
match tcx.freevars.borrow().find(&fid) {
|
match tcx.freevars.borrow().find(&fid) {
|
||||||
None => fail!("with_freevars: {} has no freevars", fid),
|
None => f(&[]),
|
||||||
Some(d) => f(d.as_slice())
|
Some(d) => f(d.as_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,6 @@ type parameter).
|
|||||||
|
|
||||||
use middle::const_eval;
|
use middle::const_eval;
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::freevars;
|
|
||||||
use middle::lang_items::IteratorItem;
|
use middle::lang_items::IteratorItem;
|
||||||
use middle::mem_categorization::McResult;
|
use middle::mem_categorization::McResult;
|
||||||
use middle::mem_categorization;
|
use middle::mem_categorization;
|
||||||
|
@ -119,7 +119,6 @@ and report an error, and it just seems like more mess in the end.)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::freevars;
|
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::ty::{ReScope};
|
use middle::ty::{ReScope};
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
|
@ -22,7 +22,6 @@ use driver::diagnostic;
|
|||||||
use driver::diagnostic::Emitter;
|
use driver::diagnostic::Emitter;
|
||||||
use driver::driver;
|
use driver::driver;
|
||||||
use driver::session;
|
use driver::session;
|
||||||
use middle::freevars;
|
|
||||||
use middle::lang_items;
|
use middle::lang_items;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use middle::resolve;
|
use middle::resolve;
|
||||||
@ -125,10 +124,8 @@ fn test_env(_test_name: &str,
|
|||||||
|
|
||||||
// run just enough stuff to build a tcx:
|
// run just enough stuff to build a tcx:
|
||||||
let lang_items = lang_items::collect_language_items(krate, &sess);
|
let lang_items = lang_items::collect_language_items(krate, &sess);
|
||||||
let resolve::CrateMap { def_map: def_map, .. } =
|
let resolve::CrateMap { def_map, freevars, capture_mode_map, .. } =
|
||||||
resolve::resolve_crate(&sess, &lang_items, krate);
|
resolve::resolve_crate(&sess, &lang_items, krate);
|
||||||
let (freevars_map, captures_map) = freevars::annotate_freevars(&def_map,
|
|
||||||
krate);
|
|
||||||
let named_region_map = resolve_lifetime::krate(&sess, krate);
|
let named_region_map = resolve_lifetime::krate(&sess, krate);
|
||||||
let region_map = region::resolve_crate(&sess, krate);
|
let region_map = region::resolve_crate(&sess, krate);
|
||||||
let stability_index = stability::Index::build(krate);
|
let stability_index = stability::Index::build(krate);
|
||||||
@ -138,8 +135,8 @@ fn test_env(_test_name: &str,
|
|||||||
def_map,
|
def_map,
|
||||||
named_region_map,
|
named_region_map,
|
||||||
ast_map,
|
ast_map,
|
||||||
freevars_map,
|
freevars,
|
||||||
captures_map,
|
capture_mode_map,
|
||||||
region_map,
|
region_map,
|
||||||
lang_items,
|
lang_items,
|
||||||
stability_index);
|
stability_index);
|
||||||
|
Loading…
Reference in New Issue
Block a user