Skip to content
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

Add namespace support for rename operation #12563

Closed
wants to merge 1 commit into from
Closed
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
10 changes: 5 additions & 5 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4177,7 +4177,7 @@ impl Resolver {
fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
let mut result = HashMap::new();
pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
let name = mtwt::resolve(path_to_ident(path));
let name = mtwt::resolve(path_to_ident(path), PlainIdent);
result.insert(name,
binding_info {span: sp,
binding_mode: binding_mode});
Expand Down Expand Up @@ -4412,7 +4412,7 @@ impl Resolver {
// what you want).

let ident = path.segments.get(0).identifier;
let renamed = mtwt::resolve(ident);
let renamed = mtwt::resolve(ident, PlainIdent);

match self.resolve_bare_identifier_pattern(ident) {
FoundStructOrEnumVariant(def, lp)
Expand Down Expand Up @@ -4966,7 +4966,7 @@ impl Resolver {
let search_result;
match namespace {
ValueNS => {
let renamed = mtwt::resolve(ident);
let renamed = mtwt::resolve(ident, PlainIdent);
let mut value_ribs = self.value_ribs.borrow_mut();
search_result = self.search_ribs(value_ribs.get(),
renamed,
Expand Down Expand Up @@ -5214,7 +5214,7 @@ impl Resolver {
let rib = label_ribs.get()[label_ribs.get().len() -
1];
let mut bindings = rib.bindings.borrow_mut();
let renamed = mtwt::resolve(label);
let renamed = mtwt::resolve(label, LifetimeIdent);
bindings.get().insert(renamed, def_like);
}

Expand All @@ -5226,7 +5226,7 @@ impl Resolver {

ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
let mut label_ribs = self.label_ribs.borrow_mut();
let renamed = mtwt::resolve(label);
let renamed = mtwt::resolve(label, LifetimeIdent);
match self.search_ribs(label_ribs.get(), renamed, expr.span) {
None =>
self.resolve_error(expr.span,
Expand Down
11 changes: 11 additions & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ impl Eq for Ident {
}
}

// This can not be more fine-grained because of loop label. It starts
// as a `token::LIFETIME` then becomes part of `ExprLoop`, `ExprForLoop`,
// `ExprBreak` or `ExprAgain` and is represented as an `ast::Ident`, not
// an `ast::Lifetime` as others do. Even so, it is still considered to
// be one of LifetimeIdent.
#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
pub enum IdentKind {
PlainIdent,
LifetimeIdent
}

/// A SyntaxContext represents a chain of macro-expandings
/// and renamings. Each macro expansion corresponds to
/// a fresh uint
Expand Down
8 changes: 6 additions & 2 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,20 +148,24 @@ pub struct BlockInfo {
// should macros escape from this scope?
macros_escape: bool,
// what are the pending renames?
pending_renames: RenameList,
pending_renames: RenameLists,
}

impl BlockInfo {
pub fn new() -> BlockInfo {
BlockInfo {
macros_escape: false,
pending_renames: Vec::new(),
pending_renames: RenameLists { plain: Vec::new(), lifetime: Vec::new() },
}
}
}

// a list of ident->name renamings
pub type RenameList = Vec<(ast::Ident, Name)>;
pub struct RenameLists {
plain: RenameList,
lifetime: RenameList
}

// The base map of methods for expanding syntax extension
// AST nodes into full ASTs
Expand Down
62 changes: 35 additions & 27 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use ast::{P, Block, Crate, DeclLocal, ExprMac};
use ast::{Local, Ident, MacInvocTT};
use ast::{ItemMac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi};
use ast::TokenTree;
use ast::{IdentKind, LifetimeIdent, PlainIdent, TokenTree};
use ast;
use ext::mtwt;
use ext::build::AstBuilder;
Expand Down Expand Up @@ -228,15 +228,15 @@ fn expand_loop_block(loop_block: P<Block>,
// syntax context otherwise an unrelated `break` or `continue` in
// the same context will pick that up in the deferred renaming pass
// and be renamed incorrectly.
let mut rename_list = vec!(rename);
let mut rename_list = RenameLists { plain: Vec::new(), lifetime: vec!(rename)};
let mut rename_fld = renames_to_fold(&mut rename_list);
let renamed_ident = rename_fld.fold_ident(label);
let renamed_ident = rename_fld.fold_ident(label, LifetimeIdent);

// The rename *must* be added to the enclosed syntax context for
// `break` or `continue` to pick up because by definition they are
// in a block enclosed by loop head.
fld.extsbox.push_frame();
fld.extsbox.info().pending_renames.push(rename);
fld.extsbox.info().pending_renames.lifetime.push(rename);
let expanded_block = expand_block_elts(loop_block, fld);
fld.extsbox.pop_frame();

Expand Down Expand Up @@ -627,10 +627,11 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
let mut name_finder = new_name_finder(Vec::new());
name_finder.visit_pat(expanded_pat,());
// generate fresh names, push them to a new pending list
let mut new_pending_renames = Vec::new();
let mut new_pending_renames = RenameLists { plain: Vec::new(),
lifetime: Vec::new() };
for ident in name_finder.ident_accumulator.iter() {
let new_name = fresh_name(ident);
new_pending_renames.push((*ident,new_name));
new_pending_renames.plain.push((*ident,new_name));
}
let rewritten_pat = {
let mut rename_fld =
Expand All @@ -640,7 +641,8 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
rename_fld.fold_pat(expanded_pat)
};
// add them to the existing pending renames:
fld.extsbox.info().pending_renames.push_all_move(new_pending_renames);
fld.extsbox.info().pending_renames
.plain.push_all_move(new_pending_renames.plain);
// also, don't forget to expand the init:
let new_init_opt = init.map(|e| fld.fold_expr(e));
let rewritten_local =
Expand Down Expand Up @@ -760,13 +762,17 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
}

pub struct IdentRenamer<'a> {
renames: &'a mut RenameList,
renames: &'a mut RenameLists,
}

impl<'a> Folder for IdentRenamer<'a> {
fn fold_ident(&mut self, id: Ident) -> Ident {
let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| {
mtwt::new_rename(from, to, ctxt)
fn fold_ident(&mut self, id: Ident, ns: IdentKind) -> Ident {
let rs = match ns {
PlainIdent => &self.renames.plain,
LifetimeIdent => &self.renames.lifetime
};
let new_ctxt = rs.iter().fold(id.ctxt, |ctxt, &(from, to)| {
mtwt::new_rename(from, to, ctxt, ns)
});
Ident {
name: id.name,
Expand All @@ -777,7 +783,7 @@ impl<'a> Folder for IdentRenamer<'a> {

// given a mutable list of renames, return a tree-folder that applies those
// renames.
pub fn renames_to_fold<'a>(renames: &'a mut RenameList) -> IdentRenamer<'a> {
pub fn renames_to_fold<'a>(renames: &'a mut RenameLists) -> IdentRenamer<'a> {
IdentRenamer {
renames: renames,
}
Expand Down Expand Up @@ -849,18 +855,18 @@ pub fn expand_crate(parse_sess: @parse::ParseSess,
struct Marker { mark: Mrk }

impl Folder for Marker {
fn fold_ident(&mut self, id: Ident) -> Ident {
fn fold_ident(&mut self, id: Ident, ns: IdentKind) -> Ident {
ast::Ident {
name: id.name,
ctxt: mtwt::new_mark(self.mark, id.ctxt)
ctxt: mtwt::new_mark(self.mark, id.ctxt, ns)
}
}
fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac {
let macro = match m.node {
MacInvocTT(ref path, ref tts, ctxt) => {
MacInvocTT(self.fold_path(path),
fold_tts(tts.as_slice(), self),
mtwt::new_mark(self.mark, ctxt))
mtwt::new_mark(self.mark, ctxt, PlainIdent))
}
};
Spanned {
Expand Down Expand Up @@ -1148,8 +1154,9 @@ mod test {
// must be one check clause for each binding:
assert_eq!(bindings.len(),bound_connections.len());
for (binding_idx,shouldmatch) in bound_connections.iter().enumerate() {
let binding_name = mtwt::resolve(*bindings.get(binding_idx));
let binding_marks = mtwt::marksof(bindings.get(binding_idx).ctxt, invalid_name);
let binding_name = mtwt::resolve(*bindings.get(binding_idx), ast::PlainIdent);
let binding_marks = mtwt::marksof(bindings.get(binding_idx).ctxt,
invalid_name, ast::PlainIdent);
// shouldmatch can't name varrefs that don't exist:
assert!((shouldmatch.len() == 0) ||
(varrefs.len() > *shouldmatch.iter().max().unwrap()));
Expand All @@ -1160,17 +1167,18 @@ mod test {
assert_eq!(varref.segments.len(),1);
let varref_name = mtwt::resolve(varref.segments
.get(0)
.identifier);
.identifier,
ast::PlainIdent);
let varref_marks = mtwt::marksof(varref.segments
.get(0)
.identifier
.ctxt,
invalid_name);
invalid_name, ast::PlainIdent);
if !(varref_name==binding_name) {
println!("uh oh, should match but doesn't:");
println!("varref: {:?}",varref);
println!("binding: {:?}", *bindings.get(binding_idx));
mtwt::with_sctable(|x| mtwt::display_sctable(x));
mtwt::with_sctable(ast::PlainIdent, |x| mtwt::display_sctable(x));
}
assert_eq!(varref_name,binding_name);
if bound_ident_check {
Expand All @@ -1180,7 +1188,7 @@ mod test {
}
} else {
let fail = (varref.segments.len() == 1)
&& (mtwt::resolve(varref.segments.get(0).identifier)
&& (mtwt::resolve(varref.segments.get(0).identifier, ast::PlainIdent)
== binding_name);
// temp debugging:
if fail {
Expand All @@ -1197,7 +1205,7 @@ mod test {
varref.segments.get(0).identifier.name,
string.get());
println!("binding: {:?}", *bindings.get(binding_idx));
mtwt::with_sctable(|x| mtwt::display_sctable(x));
mtwt::with_sctable(ast::PlainIdent, |x| mtwt::display_sctable(x));
}
assert!(!fail);
}
Expand Down Expand Up @@ -1227,7 +1235,7 @@ foo_module!()
[b] => b,
_ => fail!("expected just one binding for ext_cx")
};
let resolved_binding = mtwt::resolve(*cxbind);
let resolved_binding = mtwt::resolve(*cxbind, ast::PlainIdent);
// find all the xx varrefs:
let mut path_finder = new_path_finder(Vec::new());
visit::walk_crate(&mut path_finder, &cr, ());
Expand All @@ -1238,17 +1246,17 @@ foo_module!()
p.segments.len() == 1
&& "xx" == token::get_ident(p.segments.get(0).identifier).get()
}).enumerate() {
if mtwt::resolve(v.segments.get(0).identifier) != resolved_binding {
if mtwt::resolve(v.segments.get(0).identifier, ast::PlainIdent) != resolved_binding {
println!("uh oh, xx binding didn't match xx varref:");
println!("this is xx varref \\# {:?}",idx);
println!("binding: {:?}",cxbind);
println!("resolves to: {:?}",resolved_binding);
println!("varref: {:?}",v.segments.get(0).identifier);
println!("resolves to: {:?}",
mtwt::resolve(v.segments.get(0).identifier));
mtwt::with_sctable(|x| mtwt::display_sctable(x));
mtwt::resolve(v.segments.get(0).identifier, ast::PlainIdent));
mtwt::with_sctable(ast::PlainIdent, |x| mtwt::display_sctable(x));
}
assert_eq!(mtwt::resolve(v.segments.get(0).identifier),
assert_eq!(mtwt::resolve(v.segments.get(0).identifier, ast::PlainIdent),
resolved_binding);
};
}
Expand Down
Loading