Skip to content

librustc: Parse, but do not fully turn on, the ref keyword for #15929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
plugin::build::find_plugin_registrar(
sess.diagnostic(), krate)));

let freevars = time(time_passes, "freevar finding", (), |_|
freevars::annotate_freevars(&def_map, krate));
let (freevars, capture_modes) =
time(time_passes, "freevar finding", (), |_|
freevars::annotate_freevars(&def_map, krate));

let region_map = time(time_passes, "region resolution", (), |_|
middle::region::resolve_crate(&sess, krate));
Expand All @@ -372,8 +373,15 @@ pub fn phase_3_run_analysis_passes(sess: Session,
let stability_index = time(time_passes, "stability index", (), |_|
stability::Index::build(krate));

let ty_cx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map,
freevars, region_map, lang_items, stability_index);
let ty_cx = ty::mk_ctxt(sess,
def_map,
named_region_map,
ast_map,
freevars,
capture_modes,
region_map,
lang_items,
stability_index);

// passes are timed inside typeck
typeck::check_crate(&ty_cx, trait_map, krate);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,10 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
tag_table_capture_map = 0x53,
tag_table_unboxed_closure_type = 0x54,
tag_table_upvar_borrow_map = 0x55,
tag_table_capture_modes = 0x56,
}
static first_astencode_tag: uint = tag_ast as uint;
static last_astencode_tag: uint = tag_table_upvar_borrow_map as uint;
static last_astencode_tag: uint = tag_table_capture_modes as uint;
impl astencode_tag {
pub fn from_uint(value : uint) -> Option<astencode_tag> {
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
Expand Down
28 changes: 27 additions & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use driver::session::Session;
use metadata::decoder;
use middle::def;
use e = metadata::encoder;
use middle::freevars::{CaptureMode, freevar_entry};
use middle::freevars;
use middle::freevars::freevar_entry;
use middle::region;
use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
Expand Down Expand Up @@ -530,9 +530,14 @@ fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &freevar_entry) {
(*fv).encode(rbml_w).unwrap();
}

fn encode_capture_mode(rbml_w: &mut Encoder, cm: CaptureMode) {
cm.encode(rbml_w).unwrap();
}

trait rbml_decoder_helper {
fn read_freevar_entry(&mut self, xcx: &ExtendedDecodeContext)
-> freevar_entry;
fn read_capture_mode(&mut self) -> CaptureMode;
}

impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
Expand All @@ -541,6 +546,11 @@ impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
let fv: freevar_entry = Decodable::decode(self).unwrap();
fv.tr(xcx)
}

fn read_capture_mode(&mut self) -> CaptureMode {
let cm: CaptureMode = Decodable::decode(self).unwrap();
cm
}
}

impl tr for freevar_entry {
Expand Down Expand Up @@ -1096,6 +1106,15 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
}
}

for &cm in tcx.capture_modes.borrow().find(&id).iter() {
rbml_w.tag(c::tag_table_capture_modes, |rbml_w| {
rbml_w.id(id);
rbml_w.tag(c::tag_table_val, |rbml_w| {
encode_capture_mode(rbml_w, *cm);
})
})
}

let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
for &pty in tcx.tcache.borrow().find(&lid).iter() {
rbml_w.tag(c::tag_table_tcache, |rbml_w| {
Expand Down Expand Up @@ -1509,6 +1528,13 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
let ub: ty::UpvarBorrow = Decodable::decode(val_dsr).unwrap();
dcx.tcx.upvar_borrow_map.borrow_mut().insert(upvar_id, ub.tr(xcx));
}
c::tag_table_capture_modes => {
let capture_mode = val_dsr.read_capture_mode();
dcx.tcx
.capture_modes
.borrow_mut()
.insert(id, capture_mode);
}
c::tag_table_tcache => {
let pty = val_dsr.read_polytype(xcx);
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ pub fn closure_to_block(closure_id: ast::NodeId,
match tcx.map.get(closure_id) {
ast_map::NodeExpr(expr) => match expr.node {
ast::ExprProc(_decl, block) |
ast::ExprFnBlock(_decl, block) => { block.id }
ast::ExprFnBlock(_, _decl, block) => { block.id }
_ => fail!("encountered non-closure id: {}", closure_id)
},
_ => fail!("encountered non-expr id: {}", closure_id)
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/check_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
self.visit_expr(&**e, cx);
self.visit_block(&**b, Loop);
}
ast::ExprFnBlock(_, ref b) |
ast::ExprFnBlock(_, _, ref b) |
ast::ExprProc(_, ref b) |
ast::ExprUnboxedFn(_, ref b) => {
ast::ExprUnboxedFn(_, _, ref b) => {
self.visit_block(&**b, Closure);
}
ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
Expand Down
67 changes: 48 additions & 19 deletions src/librustc/middle/freevars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ use middle::def;
use middle::mem_categorization::Typer;
use middle::resolve;
use middle::ty;
use util::nodemap::{DefIdSet, NodeMap, NodeSet};
use util::nodemap::{NodeMap, NodeSet};

use syntax::ast;
use syntax::codemap::Span;
use syntax::{ast};
use syntax::visit;
use syntax::visit::Visitor;
use syntax::visit;

#[deriving(Show)]
#[deriving(Clone, Decodable, Encodable, Show)]
pub enum CaptureMode {
/// Copy/move the value from this llvm ValueRef into the environment.
CaptureByValue,
Expand All @@ -43,12 +43,13 @@ pub struct freevar_entry {

pub type freevar_map = NodeMap<Vec<freevar_entry>>;

pub type UnboxedClosureList = DefIdSet;
pub type CaptureModeMap = NodeMap<CaptureMode>;

struct CollectFreevarsVisitor<'a> {
seen: NodeSet,
refs: Vec<freevar_entry>,
def_map: &'a resolve::DefMap,
capture_mode_map: &'a mut CaptureModeMap,
}

impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
Expand All @@ -58,8 +59,27 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {

fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
match expr.node {
ast::ExprFnBlock(..) | ast::ExprProc(..) |
ast::ExprUnboxedFn(..) => {
ast::ExprProc(..) => {
self.capture_mode_map.insert(expr.id, CaptureByValue);
visit::walk_expr(self, expr, depth + 1)
}
ast::ExprFnBlock(_, _, _) => {
// NOTE(stage0): After snapshot, change to:
//
//let capture_mode = match capture_clause {
// ast::CaptureByValue => CaptureByValue,
// ast::CaptureByRef => CaptureByRef,
//};
let capture_mode = CaptureByRef;
self.capture_mode_map.insert(expr.id, capture_mode);
visit::walk_expr(self, expr, depth + 1)
}
ast::ExprUnboxedFn(capture_clause, _, _) => {
let capture_mode = match capture_clause {
ast::CaptureByValue => CaptureByValue,
ast::CaptureByRef => CaptureByRef,
};
self.capture_mode_map.insert(expr.id, capture_mode);
visit::walk_expr(self, expr, depth + 1)
}
ast::ExprPath(..) => {
Expand Down Expand Up @@ -91,35 +111,41 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
_ => visit::walk_expr(self, expr, depth)
}
}


}

// Searches through part of the AST for all references to locals or
// upvars in this frame and returns the list of definition IDs thus found.
// Since we want to be able to collect upvars in some arbitrary piece
// of the AST, we take a walker function that we invoke with a visitor
// in order to start the search.
fn collect_freevars(def_map: &resolve::DefMap, blk: &ast::Block) -> Vec<freevar_entry> {
fn collect_freevars(def_map: &resolve::DefMap,
blk: &ast::Block,
capture_mode_map: &mut CaptureModeMap)
-> Vec<freevar_entry> {
let mut v = CollectFreevarsVisitor {
seen: NodeSet::new(),
refs: Vec::new(),
def_map: def_map,
capture_mode_map: &mut *capture_mode_map,
};

v.visit_block(blk, 1);

v.refs
}

struct AnnotateFreevarsVisitor<'a> {
def_map: &'a resolve::DefMap,
freevars: freevar_map,
capture_mode_map: CaptureModeMap,
}

impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> {
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
blk: &ast::Block, s: Span, nid: ast::NodeId, _: ()) {
let vars = collect_freevars(self.def_map, blk);
let vars = collect_freevars(self.def_map,
blk,
&mut self.capture_mode_map);
self.freevars.insert(nid, vars);
visit::walk_fn(self, fk, fd, blk, s, ());
}
Expand All @@ -131,14 +157,20 @@ impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> {
// 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)
-> freevar_map {
-> (freevar_map, 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
let AnnotateFreevarsVisitor {
freevars,
capture_mode_map,
..
} = visitor;
(freevars, capture_mode_map)
}

pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| -> T) -> T {
Expand All @@ -148,10 +180,7 @@ pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]|
}
}

pub fn get_capture_mode<T: Typer>(tcx: &T, closure_expr_id: ast::NodeId) -> CaptureMode {
let fn_ty = tcx.node_ty(closure_expr_id).ok().expect("couldn't find closure ty?");
match ty::ty_closure_store(fn_ty) {
ty::RegionTraitStore(..) => CaptureByRef,
ty::UniqTraitStore => CaptureByValue
}
pub fn get_capture_mode<T:Typer>(tcx: &T, closure_expr_id: ast::NodeId)
-> CaptureMode {
tcx.capture_mode(closure_expr_id)
}
4 changes: 2 additions & 2 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,9 +965,9 @@ impl<'a> Liveness<'a> {
self.propagate_through_expr(&**e, succ)
}

ExprFnBlock(_, ref blk) |
ExprFnBlock(_, _, ref blk) |
ExprProc(_, ref blk) |
ExprUnboxedFn(_, ref blk) => {
ExprUnboxedFn(_, _, ref blk) => {
debug!("{} is an ExprFnBlock, ExprProc, or ExprUnboxedFn",
expr_to_string(expr));

Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#![allow(non_camel_case_types)]

use middle::def;
use middle::freevars;
use middle::ty;
use middle::typeck;
use util::nodemap::NodeMap;
Expand Down Expand Up @@ -270,6 +271,8 @@ pub trait Typer {
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId>;
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> freevars::CaptureMode;
}

impl MutabilityCategory {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5287,9 +5287,9 @@ impl<'a> Resolver<'a> {
visit::walk_expr(self, expr, ());
}

ExprFnBlock(fn_decl, block) |
ExprFnBlock(_, fn_decl, block) |
ExprProc(fn_decl, block) |
ExprUnboxedFn(fn_decl, block) => {
ExprUnboxedFn(_, fn_decl, block) => {
self.resolve_function(FunctionRibKind(expr.id, block.id),
Some(fn_decl), NoTypeParameters,
block);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/save/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ impl<'l> Visitor<DxrVisitorEnv> for DxrVisitor<'l> {
"Expected struct type, but not ty_struct"),
}
},
ast::ExprFnBlock(decl, body) => {
ast::ExprFnBlock(_, decl, body) => {
if generated_code(body.span) {
return
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,9 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
}
Some(ast_map::NodeExpr(e)) => {
match e.node {
ast::ExprFnBlock(_, blk) | ast::ExprProc(_, blk) | ast::ExprUnboxedFn(_, blk) => {
ast::ExprFnBlock(_, _, blk) |
ast::ExprProc(_, blk) |
ast::ExprUnboxedFn(_, _, blk) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false };
let mut implicit = CheckForNestedReturnsVisitor { found: false };
visit::walk_expr(&mut explicit, &*e, false);
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use llvm::{ValueRef, BasicBlockRef, BuilderRef};
use llvm::{True, False, Bool};
use mc = middle::mem_categorization;
use middle::def;
use middle::freevars;
use middle::lang_items::LangItem;
use middle::subst;
use middle::subst::Subst;
Expand Down Expand Up @@ -516,6 +517,11 @@ impl<'a> mc::Typer for Block<'a> {
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
self.tcx().upvar_borrow_map.borrow().get_copy(&upvar_id)
}

fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> freevars::CaptureMode {
self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
}
}

pub struct Result<'a> {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,9 +1150,9 @@ pub fn create_function_debug_context(cx: &CrateContext,
}
ast_map::NodeExpr(ref expr) => {
match expr.node {
ast::ExprFnBlock(fn_decl, top_level_block) |
ast::ExprFnBlock(_, fn_decl, top_level_block) |
ast::ExprProc(fn_decl, top_level_block) |
ast::ExprUnboxedFn(fn_decl, top_level_block) => {
ast::ExprUnboxedFn(_, fn_decl, top_level_block) => {
let name = format!("fn{}", token::gensym("fn"));
let name = token::str_to_ident(name.as_slice());
(name, fn_decl,
Expand Down Expand Up @@ -3618,9 +3618,9 @@ fn populate_scope_map(cx: &CrateContext,
})
}

ast::ExprFnBlock(ref decl, ref block) |
ast::ExprFnBlock(_, ref decl, ref block) |
ast::ExprProc(ref decl, ref block) |
ast::ExprUnboxedFn(ref decl, ref block) => {
ast::ExprUnboxedFn(_, ref decl, ref block) => {
with_new_scope(cx,
block.span,
scope_stack,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,15 +782,15 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
ast::ExprVec(..) | ast::ExprRepeat(..) => {
tvec::trans_fixed_vstore(bcx, expr, expr, dest)
}
ast::ExprFnBlock(ref decl, ref body) |
ast::ExprFnBlock(_, ref decl, ref body) |
ast::ExprProc(ref decl, ref body) => {
let expr_ty = expr_ty(bcx, expr);
let store = ty::ty_closure_store(expr_ty);
debug!("translating block function {} with type {}",
expr_to_string(expr), expr_ty.repr(tcx));
closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
}
ast::ExprUnboxedFn(decl, body) => {
ast::ExprUnboxedFn(_, decl, body) => {
closure::trans_unboxed_closure(bcx, &*decl, &*body, expr.id, dest)
}
ast::ExprCall(ref f, ref args) => {
Expand Down
Loading