diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index e381b0af47a..0fd93d65b70 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -190,6 +190,9 @@ pub fn phase_2_configure_and_expand(sess: Session, crate = time(time_passes, ~"std injection", || front::std_inject::maybe_inject_libstd_ref(sess, crate)); + crate = time(time_passes, ~"assigning node ids", || + front::assign_node_ids::assign_node_ids(sess, crate)); + return crate; } @@ -207,6 +210,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, crate: @ast::Crate) -> CrateAnalysis { let time_passes = sess.time_passes(); + let ast_map = time(time_passes, ~"ast indexing", || syntax::ast_map::map_crate(sess.diagnostic(), crate)); @@ -812,6 +816,7 @@ pub fn build_session_(sopts: @session::options, building_library: @mut false, working_dir: os::getcwd(), lints: @mut HashMap::new(), + node_id: @mut 1 } } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 5419ed3791b..7f3f1f88a52 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -28,6 +28,7 @@ use syntax::abi; use syntax::parse::token; use syntax; +use std::int; use std::hashmap::HashMap; #[deriving(Eq)] @@ -216,57 +217,58 @@ pub struct Session_ { building_library: @mut bool, working_dir: Path, lints: @mut HashMap, + node_id: @mut uint, } pub type Session = @Session_; impl Session_ { - pub fn span_fatal(@self, sp: Span, msg: &str) -> ! { + pub fn span_fatal(&self, sp: Span, msg: &str) -> ! { self.span_diagnostic.span_fatal(sp, msg) } - pub fn fatal(@self, msg: &str) -> ! { + pub fn fatal(&self, msg: &str) -> ! { self.span_diagnostic.handler().fatal(msg) } - pub fn span_err(@self, sp: Span, msg: &str) { + pub fn span_err(&self, sp: Span, msg: &str) { self.span_diagnostic.span_err(sp, msg) } - pub fn err(@self, msg: &str) { + pub fn err(&self, msg: &str) { self.span_diagnostic.handler().err(msg) } - pub fn err_count(@self) -> uint { + pub fn err_count(&self) -> uint { self.span_diagnostic.handler().err_count() } - pub fn has_errors(@self) -> bool { + pub fn has_errors(&self) -> bool { self.span_diagnostic.handler().has_errors() } - pub fn abort_if_errors(@self) { + pub fn abort_if_errors(&self) { self.span_diagnostic.handler().abort_if_errors() } - pub fn span_warn(@self, sp: Span, msg: &str) { + pub fn span_warn(&self, sp: Span, msg: &str) { self.span_diagnostic.span_warn(sp, msg) } - pub fn warn(@self, msg: &str) { + pub fn warn(&self, msg: &str) { self.span_diagnostic.handler().warn(msg) } - pub fn span_note(@self, sp: Span, msg: &str) { + pub fn span_note(&self, sp: Span, msg: &str) { self.span_diagnostic.span_note(sp, msg) } - pub fn note(@self, msg: &str) { + pub fn note(&self, msg: &str) { self.span_diagnostic.handler().note(msg) } - pub fn span_bug(@self, sp: Span, msg: &str) -> ! { + pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.span_diagnostic.span_bug(sp, msg) } - pub fn bug(@self, msg: &str) -> ! { + pub fn bug(&self, msg: &str) -> ! { self.span_diagnostic.handler().bug(msg) } - pub fn span_unimpl(@self, sp: Span, msg: &str) -> ! { + pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { self.span_diagnostic.span_unimpl(sp, msg) } - pub fn unimpl(@self, msg: &str) -> ! { + pub fn unimpl(&self, msg: &str) -> ! { self.span_diagnostic.handler().unimpl(msg) } - pub fn add_lint(@self, + pub fn add_lint(&self, lint: lint::lint, id: ast::NodeId, sp: Span, @@ -277,77 +279,85 @@ impl Session_ { } self.lints.insert(id, ~[(lint, sp, msg)]); } - pub fn next_node_id(@self) -> ast::NodeId { - return syntax::parse::next_node_id(self.parse_sess); + pub fn next_node_id(&self) -> ast::NodeId { + self.reserve_node_ids(1) } - pub fn diagnostic(@self) -> @mut diagnostic::span_handler { + pub fn reserve_node_ids(&self, count: uint) -> ast::NodeId { + let v = *self.node_id; + *self.node_id += count; + if v > (int::max_value as uint) { + self.bug("Input too large, ran out of node ids!"); + } + v as int + } + pub fn diagnostic(&self) -> @mut diagnostic::span_handler { self.span_diagnostic } - pub fn debugging_opt(@self, opt: uint) -> bool { + pub fn debugging_opt(&self, opt: uint) -> bool { (self.opts.debugging_opts & opt) != 0u } // This exists to help with refactoring to eliminate impossible // cases later on - pub fn impossible_case(@self, sp: Span, msg: &str) -> ! { + pub fn impossible_case(&self, sp: Span, msg: &str) -> ! { self.span_bug(sp, fmt!("Impossible case reached: %s", msg)); } - pub fn verbose(@self) -> bool { self.debugging_opt(verbose) } - pub fn time_passes(@self) -> bool { self.debugging_opt(time_passes) } - pub fn count_llvm_insns(@self) -> bool { + pub fn verbose(&self) -> bool { self.debugging_opt(verbose) } + pub fn time_passes(&self) -> bool { self.debugging_opt(time_passes) } + pub fn count_llvm_insns(&self) -> bool { self.debugging_opt(count_llvm_insns) } - pub fn count_type_sizes(@self) -> bool { + pub fn count_type_sizes(&self) -> bool { self.debugging_opt(count_type_sizes) } - pub fn time_llvm_passes(@self) -> bool { + pub fn time_llvm_passes(&self) -> bool { self.debugging_opt(time_llvm_passes) } - pub fn trans_stats(@self) -> bool { self.debugging_opt(trans_stats) } - pub fn meta_stats(@self) -> bool { self.debugging_opt(meta_stats) } - pub fn asm_comments(@self) -> bool { self.debugging_opt(asm_comments) } - pub fn no_verify(@self) -> bool { self.debugging_opt(no_verify) } - pub fn lint_llvm(@self) -> bool { self.debugging_opt(lint_llvm) } - pub fn trace(@self) -> bool { self.debugging_opt(trace) } - pub fn coherence(@self) -> bool { self.debugging_opt(coherence) } - pub fn borrowck_stats(@self) -> bool { self.debugging_opt(borrowck_stats) } - pub fn borrowck_note_pure(@self) -> bool { + pub fn trans_stats(&self) -> bool { self.debugging_opt(trans_stats) } + pub fn meta_stats(&self) -> bool { self.debugging_opt(meta_stats) } + pub fn asm_comments(&self) -> bool { self.debugging_opt(asm_comments) } + pub fn no_verify(&self) -> bool { self.debugging_opt(no_verify) } + pub fn lint_llvm(&self) -> bool { self.debugging_opt(lint_llvm) } + pub fn trace(&self) -> bool { self.debugging_opt(trace) } + pub fn coherence(&self) -> bool { self.debugging_opt(coherence) } + pub fn borrowck_stats(&self) -> bool { self.debugging_opt(borrowck_stats) } + pub fn borrowck_note_pure(&self) -> bool { self.debugging_opt(borrowck_note_pure) } - pub fn borrowck_note_loan(@self) -> bool { + pub fn borrowck_note_loan(&self) -> bool { self.debugging_opt(borrowck_note_loan) } - pub fn no_monomorphic_collapse(@self) -> bool { + pub fn no_monomorphic_collapse(&self) -> bool { self.debugging_opt(no_monomorphic_collapse) } - pub fn debug_borrows(@self) -> bool { + pub fn debug_borrows(&self) -> bool { self.opts.optimize == No && !self.debugging_opt(no_debug_borrows) } - pub fn once_fns(@self) -> bool { self.debugging_opt(once_fns) } - pub fn print_llvm_passes(@self) -> bool { + pub fn once_fns(&self) -> bool { self.debugging_opt(once_fns) } + pub fn print_llvm_passes(&self) -> bool { self.debugging_opt(print_llvm_passes) } - pub fn no_prepopulate_passes(@self) -> bool { + pub fn no_prepopulate_passes(&self) -> bool { self.debugging_opt(no_prepopulate_passes) } - pub fn no_vectorize_loops(@self) -> bool { + pub fn no_vectorize_loops(&self) -> bool { self.debugging_opt(no_vectorize_loops) } - pub fn no_vectorize_slp(@self) -> bool { + pub fn no_vectorize_slp(&self) -> bool { self.debugging_opt(no_vectorize_slp) } // pointless function, now... - pub fn str_of(@self, id: ast::Ident) -> @str { + pub fn str_of(&self, id: ast::Ident) -> @str { token::ident_to_str(&id) } // pointless function, now... - pub fn ident_of(@self, st: &str) -> ast::Ident { + pub fn ident_of(&self, st: &str) -> ast::Ident { token::str_to_ident(st) } // pointless function, now... - pub fn intr(@self) -> @syntax::parse::token::ident_interner { + pub fn intr(&self) -> @syntax::parse::token::ident_interner { token::get_ident_interner() } } diff --git a/src/librustc/front/assign_node_ids.rs b/src/librustc/front/assign_node_ids.rs new file mode 100644 index 00000000000..446db5c35e9 --- /dev/null +++ b/src/librustc/front/assign_node_ids.rs @@ -0,0 +1,19 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use driver::session::Session; + +use syntax::ast; +use syntax::ast_util; + +pub fn assign_node_ids(sess: Session, crate: @ast::Crate) -> @ast::Crate { + let fold = ast_util::node_id_assigner(|| sess.next_node_id()); + @fold.fold_crate(crate) +} diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 5d536ba7213..d685b8a3e76 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -45,7 +45,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate { let precursor = @fold::AstFoldFns { fold_crate: |crate, fld| { - let n1 = sess.next_node_id(); + let n1 = ast::DUMMY_NODE_ID; let vi1 = ast::view_item { node: ast::view_item_extern_mod( sess.ident_of("std"), None, ~[], n1), @@ -86,7 +86,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate { } }, fold_mod: |module, fld| { - let n2 = sess.next_node_id(); + let n2 = ast::DUMMY_NODE_ID; let prelude_path = ast::Path { span: dummy_sp(), diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 63491c3d413..9c788065133 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -280,10 +280,10 @@ fn mk_std(cx: &TestCtxt) -> ast::view_item { ast::view_item_use( ~[@nospan(ast::view_path_simple(id_extra, path_node(~[id_extra]), - cx.sess.next_node_id()))]) + ast::DUMMY_NODE_ID))]) } else { let mi = attr::mk_name_value_item_str(@"vers", @"0.8-pre"); - ast::view_item_extern_mod(id_extra, None, ~[mi], cx.sess.next_node_id()) + ast::view_item_extern_mod(id_extra, None, ~[mi], ast::DUMMY_NODE_ID) }; ast::view_item { node: vi, @@ -325,7 +325,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { let item = ast::item { ident: cx.sess.ident_of("__test"), attrs: ~[resolve_unexported_attr], - id: cx.sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: item_, vis: ast::public, span: dummy_sp(), @@ -367,7 +367,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { let item = ast::item { ident: cx.sess.ident_of("__test"), attrs: ~[resolve_unexported_attr], - id: cx.sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: item_, vis: ast::public, span: dummy_sp(), @@ -448,15 +448,14 @@ fn mk_test_descs(cx: &TestCtxt) -> @ast::Expr { descs.push(mk_test_desc_and_fn_rec(cx, test)); } - let sess = cx.sess; let inner_expr = @ast::Expr { - id: sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprVec(descs, ast::MutImmutable), span: dummy_sp(), }; @ast::Expr { - id: sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprVstore(inner_expr, ast::ExprVstoreSlice), span: dummy_sp(), } @@ -475,7 +474,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr { nospan(ast::lit_str(ast_util::path_name_i(path).to_managed())); let name_expr = @ast::Expr { - id: cx.sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprLit(@name_lit), span: span }; @@ -483,7 +482,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr { let fn_path = path_node_global(path); let fn_expr = @ast::Expr { - id: cx.sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprPath(fn_path), span: span, }; @@ -529,7 +528,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr { nospan(ast::lit_str(ast_util::path_name_i(path).to_managed())); let name_expr = @ast::Expr { - id: cx.sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprLit(@name_lit), span: span }; @@ -537,7 +536,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr { let fn_path = path_node_global(path); let fn_expr = @ast::Expr { - id: cx.sess.next_node_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprPath(fn_path), span: span, }; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index f6645b1c1d1..b6ccda5e1d1 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -157,10 +157,10 @@ fn reserve_id_range(sess: Session, // Handle the case of an empty range: if from_id_range.empty() { return from_id_range; } let cnt = from_id_range.max - from_id_range.min; - let to_id_min = sess.parse_sess.next_id; - let to_id_max = sess.parse_sess.next_id + cnt; - sess.parse_sess.next_id = to_id_max; - ast_util::id_range { min: to_id_min, max: to_id_min } + assert!(cnt >= 0); + let to_id_min = sess.reserve_node_ids(cnt as uint); + let to_id_max = to_id_min + cnt; + ast_util::id_range { min: to_id_min, max: to_id_max } } impl ExtendedDecodeContext { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 292047d885d..f1d3ecf69e1 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -5403,7 +5403,15 @@ impl Resolver { pub fn record_def(@mut self, node_id: NodeId, def: Def) { debug!("(recording def) recording %? for %?", def, node_id); - self.def_map.insert(node_id, def); + do self.def_map.insert_or_update_with(node_id, def) |_, old_value| { + // Resolve appears to "resolve" the same ID multiple + // times, so here is a sanity check it at least comes to + // the same conclusion! - nmatsakis + if def != *old_value { + self.session.bug(fmt!("node_id %? resolved first to %? \ + and then %?", node_id, *old_value, def)); + } + }; } pub fn enforce_default_binding_mode(@mut self, diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 700b60f1159..61d00dff584 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -45,7 +45,6 @@ use syntax::ast_util::{def_id_of_def, local_def}; use syntax::codemap::Span; use syntax::opt_vec; use syntax::visit; -use syntax::parse; use std::hashmap::HashSet; use std::result::Ok; @@ -334,7 +333,7 @@ impl CoherenceChecker { let provided = ty::provided_trait_methods(tcx, trait_ref.def_id); for trait_method in provided.iter() { // Synthesize an ID. - let new_id = parse::next_node_id(tcx.sess.parse_sess); + let new_id = tcx.sess.next_node_id(); let new_did = local_def(new_id); debug!("new_did=%? trait_method=%s", new_did, trait_method.repr(tcx)); diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 6c5c8631a14..adf11a9fa21 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -80,6 +80,7 @@ pub mod front { pub mod config; pub mod test; pub mod std_inject; + pub mod assign_node_ids; } pub mod back { diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index 287cb6cf15f..b2b7599aae3 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -29,6 +29,7 @@ use rustc::driver::session::{basic_options, options}; use rustc::front; use syntax::ast; use syntax::ast_map; +use syntax::ast_util; use syntax; pub struct Ctxt { @@ -108,6 +109,16 @@ pub fn exec( po.recv() } +fn assign_node_ids(crate: @ast::Crate) -> @ast::Crate { + let next_id = @mut 0; + let fold = ast_util::node_id_assigner(|| { + let i = *next_id; + *next_id += 1; + i + }); + @fold.fold_crate(crate) +} + fn build_ctxt(sess: Session, ast: @ast::Crate) -> Ctxt { @@ -121,6 +132,7 @@ fn build_ctxt(sess: Session, sess.opts.cfg.clone(), ast); let ast = front::test::modify_for_testing(sess, ast); + let ast = assign_node_ids(ast); let ast_map = ast_map::map_crate(sess.diagnostic(), ast); Ctxt { diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index b5503cc51e1..2e7c73d3421 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -281,6 +281,7 @@ mod test { fn should_extract_enum_docs() { let doc = mk_doc(~"#[doc = \"b\"]\ enum a { v }"); + debug!("%?", doc); assert!(doc.cratemod().enums()[0].desc() == Some(~"b")); } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index 88a63a9cb59..2ab0530ccb3 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -285,6 +285,7 @@ mod test { fn mk_doc(source: @str) -> doc::Doc { let ast = parse::from_str(source); + debug!("ast=%?", ast); extract(ast, ~"") } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 36047627289..fd6acf138e1 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -176,6 +176,11 @@ pub struct DefId { pub static LOCAL_CRATE: CrateNum = 0; pub static CRATE_NODE_ID: NodeId = 0; +// When parsing and doing expansions, we initially give all AST nodes this AST +// node value. Then later, in the renumber pass, we renumber them to have +// small, positive ids. +pub static DUMMY_NODE_ID: NodeId = -1; + // The AST represents all type param bounds as types. // typeck::collect::compute_bounds matches these against // the "special" built-in traits (see middle::lang_items) and diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index dcf655871df..040c4cda4c7 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -12,6 +12,7 @@ use ast::*; use ast; use ast_util; use codemap::{Span, dummy_sp}; +use fold; use opt_vec; use parse::token; use visit::{SimpleVisitor, Visitor}; @@ -370,6 +371,21 @@ pub fn empty_generics() -> Generics { ty_params: opt_vec::Empty} } +/////////////////////////////////////////////////////////////////////////// +// Assigning node ids + +fn node_id_assigner(next_id: @fn() -> ast::NodeId) -> @fold::ast_fold { + let precursor = @fold::AstFoldFns { + new_id: |old_id| { + assert_eq!(old_id, ast::DUMMY_NODE_ID); + next_id() + }, + ..*fold::default_ast_fold() + }; + + fold::make_fold(precursor) +} + // ______________________________________________________________________ // Enumerating the IDs which appear in an AST diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 3937cd8e416..b350ef7bb08 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -76,7 +76,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) p.expect(&token::RPAREN); let out = @ast::Expr { - id: cx.next_id(), + id: ast::DUMMY_NODE_ID, span: out.span, node: ast::ExprAddrOf(ast::MutMutable, out) }; @@ -172,7 +172,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) } MRExpr(@ast::Expr { - id: cx.next_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprInlineAsm(ast::inline_asm { asm: asm, clobbers: cons.to_managed(), diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3d5d62aeadf..48a13646686 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -319,9 +319,6 @@ impl ExtCtxt { self.print_backtrace(); self.parse_sess.span_diagnostic.handler().bug(msg); } - pub fn next_id(&self) -> ast::NodeId { - parse::next_node_id(self.parse_sess) - } pub fn trace_macros(&self) -> bool { *self.trace_mac } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 339583ed426..6cb5a93a313 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -13,7 +13,6 @@ use ast::Ident; use ast; use ast_util; use codemap::{Span, respan, dummy_sp}; -use fold; use ext::base::ExtCtxt; use ext::quote::rt::*; use opt_vec; @@ -277,7 +276,7 @@ impl AstBuilder for @ExtCtxt { fn ty(&self, span: Span, ty: ast::ty_) -> ast::Ty { ast::Ty { - id: self.next_id(), + id: ast::DUMMY_NODE_ID, span: span, node: ty } @@ -286,7 +285,7 @@ impl AstBuilder for @ExtCtxt { fn ty_path(&self, path: ast::Path, bounds: Option>) -> ast::Ty { self.ty(path.span, - ast::ty_path(path, bounds, self.next_id())) + ast::ty_path(path, bounds, ast::DUMMY_NODE_ID)) } // Might need to take bounds as an argument in the future, if you ever want @@ -340,14 +339,14 @@ impl AstBuilder for @ExtCtxt { fn ty_nil(&self) -> ast::Ty { ast::Ty { - id: self.next_id(), + id: ast::DUMMY_NODE_ID, node: ast::ty_nil, span: dummy_sp(), } } fn typaram(&self, id: ast::Ident, bounds: OptVec) -> ast::TyParam { - ast::TyParam { ident: id, id: self.next_id(), bounds: bounds } + ast::TyParam { ident: id, id: ast::DUMMY_NODE_ID, bounds: bounds } } // these are strange, and probably shouldn't be used outside of @@ -377,7 +376,7 @@ impl AstBuilder for @ExtCtxt { fn trait_ref(&self, path: ast::Path) -> ast::trait_ref { ast::trait_ref { path: path, - ref_id: self.next_id() + ref_id: ast::DUMMY_NODE_ID } } @@ -386,11 +385,11 @@ impl AstBuilder for @ExtCtxt { } fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime { - ast::Lifetime { id: self.next_id(), span: span, ident: ident } + ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, ident: ident } } fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt { - @respan(expr.span, ast::StmtSemi(expr, self.next_id())) + @respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID)) } fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt { @@ -400,11 +399,11 @@ impl AstBuilder for @ExtCtxt { ty: self.ty_infer(sp), pat: pat, init: Some(ex), - id: self.next_id(), + id: ast::DUMMY_NODE_ID, span: sp, }; let decl = respan(sp, ast::DeclLocal(local)); - @respan(sp, ast::StmtDecl(@decl, self.next_id())) + @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID)) } fn stmt_let_typed(&self, @@ -420,11 +419,11 @@ impl AstBuilder for @ExtCtxt { ty: typ, pat: pat, init: Some(ex), - id: self.next_id(), + id: ast::DUMMY_NODE_ID, span: sp, }; let decl = respan(sp, ast::DeclLocal(local)); - @respan(sp, ast::StmtDecl(@decl, self.next_id())) + @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID)) } fn block(&self, span: Span, stmts: ~[@ast::Stmt], expr: Option<@Expr>) -> ast::Block { @@ -443,7 +442,7 @@ impl AstBuilder for @ExtCtxt { view_items: view_items, stmts: stmts, expr: expr, - id: self.next_id(), + id: ast::DUMMY_NODE_ID, rules: ast::DefaultBlock, span: span, } @@ -451,7 +450,7 @@ impl AstBuilder for @ExtCtxt { fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr { @ast::Expr { - id: self.next_id(), + id: ast::DUMMY_NODE_ID, node: node, span: span, } @@ -470,7 +469,7 @@ impl AstBuilder for @ExtCtxt { fn expr_binary(&self, sp: Span, op: ast::BinOp, lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr { - self.expr(sp, ast::ExprBinary(self.next_id(), op, lhs, rhs)) + self.expr(sp, ast::ExprBinary(ast::DUMMY_NODE_ID, op, lhs, rhs)) } fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { @@ -478,7 +477,7 @@ impl AstBuilder for @ExtCtxt { } fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr { - self.expr(sp, ast::ExprUnary(self.next_id(), op, e)) + self.expr(sp, ast::ExprUnary(ast::DUMMY_NODE_ID, op, e)) } fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { @@ -512,7 +511,7 @@ impl AstBuilder for @ExtCtxt { ident: ast::Ident, args: ~[@ast::Expr]) -> @ast::Expr { self.expr(span, - ast::ExprMethodCall(self.next_id(), expr, ident, ~[], args, ast::NoSugar)) + ast::ExprMethodCall(ast::DUMMY_NODE_ID, expr, ident, ~[], args, ast::NoSugar)) } fn expr_block(&self, b: ast::Block) -> @ast::Expr { self.expr(b.span, ast::ExprBlock(b)) @@ -583,7 +582,7 @@ impl AstBuilder for @ExtCtxt { fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat { - @ast::Pat { id: self.next_id(), node: pat, span: span } + @ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span } } fn pat_wild(&self, span: Span) -> @ast::Pat { self.pat(span, ast::PatWild) @@ -695,7 +694,7 @@ impl AstBuilder for @ExtCtxt { is_mutbl: false, ty: ty, pat: arg_pat, - id: self.next_id() + id: ast::DUMMY_NODE_ID } } @@ -714,7 +713,7 @@ impl AstBuilder for @ExtCtxt { // Rust coding conventions @ast::item { ident: name, attrs: attrs, - id: self.next_id(), + id: ast::DUMMY_NODE_ID, node: node, vis: ast::public, span: span } @@ -755,7 +754,7 @@ impl AstBuilder for @ExtCtxt { fn variant(&self, span: Span, name: Ident, tys: ~[ast::Ty]) -> ast::variant { let args = tys.move_iter().map(|ty| { - ast::variant_arg { ty: ty, id: self.next_id() } + ast::variant_arg { ty: ty, id: ast::DUMMY_NODE_ID } }).collect(); respan(span, @@ -763,7 +762,7 @@ impl AstBuilder for @ExtCtxt { name: name, attrs: ~[], kind: ast::tuple_variant_kind(args), - id: self.next_id(), + id: ast::DUMMY_NODE_ID, disr_expr: None, vis: ast::public }) @@ -860,43 +859,20 @@ impl AstBuilder for @ExtCtxt { fn view_use_list(&self, sp: Span, vis: ast::visibility, path: ~[ast::Ident], imports: &[ast::Ident]) -> ast::view_item { let imports = do imports.map |id| { - respan(sp, ast::path_list_ident_ { name: *id, id: self.next_id() }) + respan(sp, ast::path_list_ident_ { name: *id, id: ast::DUMMY_NODE_ID }) }; self.view_use(sp, vis, ~[@respan(sp, ast::view_path_list(self.path(sp, path), imports, - self.next_id()))]) + ast::DUMMY_NODE_ID))]) } fn view_use_glob(&self, sp: Span, vis: ast::visibility, path: ~[ast::Ident]) -> ast::view_item { self.view_use(sp, vis, ~[@respan(sp, - ast::view_path_glob(self.path(sp, path), self.next_id()))]) - } -} - - -pub trait Duplicate { - // - // Duplication functions - // - // These functions just duplicate AST nodes. - // - - fn duplicate(&self, cx: @ExtCtxt) -> Self; -} - -impl Duplicate for @ast::Expr { - fn duplicate(&self, cx: @ExtCtxt) -> @ast::Expr { - let folder = fold::default_ast_fold(); - let folder = @fold::AstFoldFns { - new_id: |_| cx.next_id(), - ..*folder - }; - let folder = fold::make_fold(folder); - folder.fold_expr(*self) + ast::view_path_glob(self.path(sp, path), ast::DUMMY_NODE_ID))]) } } diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 16e54093a14..0ca18f1208d 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -35,7 +35,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) let res = str_to_ident(res_str); let e = @ast::Expr { - id: cx.next_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprPath( ast::Path { span: sp, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 8221be1bbcb..9222d8160ee 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -539,9 +539,9 @@ impl<'self> MethodDef<'self> { purity: ast::impure_fn, decl: fn_decl, body: body_block, - id: cx.next_id(), + id: ast::DUMMY_NODE_ID, span: span, - self_id: cx.next_id(), + self_id: ast::DUMMY_NODE_ID, vis: ast::inherited, } } diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 8afd99e80af..56f92246d8f 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -12,7 +12,7 @@ use ast; use ast::{MetaItem, item, Expr, Ident}; use codemap::Span; use ext::base::ExtCtxt; -use ext::build::{AstBuilder, Duplicate}; +use ext::build::{AstBuilder}; use ext::deriving::generic::*; use std::vec; @@ -62,7 +62,7 @@ fn rand_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { let rand_call = || { cx.expr_call_global(span, rand_ident.clone(), - ~[ rng[0].duplicate(cx) ]) + ~[ rng[0] ]) }; return match *substr.fields { @@ -86,7 +86,7 @@ fn rand_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { // ::std::rand::Rand::rand(rng) let rv_call = cx.expr_call(span, rand_name, - ~[ rng[0].duplicate(cx) ]); + ~[ rng[0] ]); // need to specify the uint-ness of the random number let uint_ty = cx.ty_ident(span, cx.ident_of("uint")); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 50a14c0fd71..80fd7971efd 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -406,8 +406,8 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, let marked_ctxt = new_mark(fm,ctxt); let expanded = match expandfun(cx, mac.span, marked_tts, marked_ctxt) { MRExpr(e) => - @codemap::Spanned { node: StmtExpr(e, cx.next_id()), - span: e.span}, + @codemap::Spanned { node: StmtExpr(e, ast::DUMMY_NODE_ID), + span: e.span}, MRAny(_,_,stmt_mkr) => stmt_mkr(), _ => cx.span_fatal( pth.span, @@ -1365,8 +1365,8 @@ pub fn fun_to_ctxt_folder(cf: @T) -> @AstFoldFns { match *m { mac_invoc_tt(ref path, ref tts, ctxt) => (mac_invoc_tt(fld.fold_path(path), - fold_tts(*tts,fld), - cf.f(ctxt)), + fold_tts(*tts,fld), + cf.f(ctxt)), sp) } diff --git a/src/libsyntax/ext/ifmt.rs b/src/libsyntax/ext/ifmt.rs index b63b829a392..b7722ffc297 100644 --- a/src/libsyntax/ext/ifmt.rs +++ b/src/libsyntax/ext/ifmt.rs @@ -550,7 +550,7 @@ impl Context { for &method in self.method_statics.iter() { let decl = respan(self.fmtsp, ast::DeclItem(method)); lets.push(@respan(self.fmtsp, - ast::StmtDecl(@decl, self.ecx.next_id()))); + ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))); } // Next, build up the static array which will become our precompiled @@ -581,7 +581,7 @@ impl Context { let unnamed = self.ecx.attribute(self.fmtsp, unnamed); let item = self.ecx.item(self.fmtsp, static_name, ~[unnamed], st); let decl = respan(self.fmtsp, ast::DeclItem(item)); - lets.push(@respan(self.fmtsp, ast::StmtDecl(@decl, self.ecx.next_id()))); + lets.push(@respan(self.fmtsp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))); // Right now there is a bug such that for the expression: // foo(bar(&1)) @@ -631,7 +631,7 @@ impl Context { view_items: ~[], stmts: ~[], expr: Some(result), - id: self.ecx.next_id(), + id: ast::DUMMY_NODE_ID, rules: ast::UnsafeBlock, span: self.fmtsp, }); diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index adc246ab89a..52807009073 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -30,7 +30,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, //trivial expression MRExpr(@ast::Expr { - id: cx.next_id(), + id: ast::DUMMY_NODE_ID, node: ast::ExprLit(@codemap::Spanned { node: ast::lit_nil, span: sp diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 664bd3f128a..0b19e4462f0 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -29,6 +29,7 @@ pub trait ast_fold { fn fold_item(@self, @item) -> Option<@item>; fn fold_struct_field(@self, @struct_field) -> @struct_field; fn fold_item_underscore(@self, &item_) -> item_; + fn fold_type_method(@self, m: &TypeMethod) -> TypeMethod; fn fold_method(@self, @method) -> @method; fn fold_block(@self, &Block) -> Block; fn fold_stmt(@self, &Stmt) -> Option<@Stmt>; @@ -47,6 +48,149 @@ pub trait ast_fold { fn map_exprs(@self, @fn(@Expr) -> @Expr, &[@Expr]) -> ~[@Expr]; fn new_id(@self, NodeId) -> NodeId; fn new_span(@self, Span) -> Span; + + // New style, using default methods: + + fn fold_variant_arg(@self, va: &variant_arg) -> variant_arg { + variant_arg { + ty: self.fold_ty(&va.ty), + id: self.new_id(va.id) + } + } + + fn fold_spanned(@self, s: &Spanned, f: &fn(&T) -> T) -> Spanned { + Spanned { + node: f(&s.node), + span: self.new_span(s.span) + } + } + + fn fold_view_path(@self, vp: &view_path) -> view_path { + self.fold_spanned(vp, |v| self.fold_view_path_(v)) + } + + fn fold_view_paths(@self, vps: &[@view_path]) -> ~[@view_path] { + vps.map(|vp| @self.fold_view_path(*vp)) + } + + fn fold_view_path_(@self, vp: &view_path_) -> view_path_ { + match *vp { + view_path_simple(ident, ref path, node_id) => { + view_path_simple(self.fold_ident(ident), + self.fold_path(path), + self.new_id(node_id)) + } + view_path_glob(ref path, node_id) => { + view_path_glob(self.fold_path(path), + self.new_id(node_id)) + } + view_path_list(ref path, ref idents, node_id) => { + view_path_list(self.fold_path(path), + self.fold_path_list_idents(*idents), + self.new_id(node_id)) + } + } + } + + fn fold_path_list_idents(@self, idents: &[path_list_ident]) -> ~[path_list_ident] { + idents.map(|i| self.fold_path_list_ident(i)) + } + + fn fold_path_list_ident(@self, ident: &path_list_ident) -> path_list_ident { + self.fold_spanned(ident, |i| self.fold_path_list_ident_(i)) + } + + fn fold_path_list_ident_(@self, ident: &path_list_ident_) -> path_list_ident_ { + path_list_ident_ { + name: self.fold_ident(ident.name), + id: self.new_id(ident.id) + } + } + + fn fold_arg(@self, a: &arg) -> arg { + arg { + is_mutbl: a.is_mutbl, + ty: self.fold_ty(&a.ty), + pat: self.fold_pat(a.pat), + id: self.new_id(a.id), + } + } + + fn fold_trait_ref(@self, p: &trait_ref) -> trait_ref { + trait_ref { + path: self.fold_path(&p.path), + ref_id: self.new_id(p.ref_id), + } + } + + fn fold_ty_param_bound(@self, tpb: &TyParamBound) -> TyParamBound { + match *tpb { + TraitTyParamBound(ref ty) => { + TraitTyParamBound(self.fold_trait_ref(ty)) + } + RegionTyParamBound => { + RegionTyParamBound + } + } + } + + fn fold_ty_param(@self, tp: &TyParam) -> TyParam { + TyParam { + ident: self.fold_ident(tp.ident), + id: self.new_id(tp.id), + bounds: tp.bounds.map(|x| self.fold_ty_param_bound(x)) + } + } + + fn fold_ty_params(@self, tps: &OptVec) -> OptVec { + tps.map(|tp| self.fold_ty_param(tp)) + } + + fn fold_lifetime(@self, l: &Lifetime) -> Lifetime { + Lifetime { + id: self.new_id(l.id), + span: self.new_span(l.span), + ident: l.ident, // Folding this ident causes hygiene errors - ndm + } + } + + fn fold_lifetimes(@self, lts: &OptVec) -> OptVec { + lts.map(|l| self.fold_lifetime(l)) + } + + + fn fold_meta_item(@self, mi: &MetaItem) -> @MetaItem { + @self.fold_spanned(mi, |n| match *n { + MetaWord(id) => { + MetaWord(id) + } + MetaList(id, ref mis) => { + MetaList(id, self.fold_meta_items(*mis)) + } + MetaNameValue(id, s) => { + MetaNameValue(id, s) + } + }) + } + + fn fold_meta_items(@self, mis: &[@MetaItem]) -> ~[@MetaItem] { + mis.map(|&mi| self.fold_meta_item(mi)) + } + + fn fold_attribute(@self, at: &Attribute) -> Attribute { + Spanned { + span: self.new_span(at.span), + node: Attribute_ { + style: at.node.style, + value: self.fold_meta_item(at.node.value), + is_sugared_doc: at.node.is_sugared_doc + } + } + } + + fn fold_attributes(@self, attrs: &[Attribute]) -> ~[Attribute] { + attrs.map(|x| self.fold_attribute(x)) + } } // We may eventually want to be able to fold over type parameters, too @@ -59,6 +203,7 @@ pub struct AstFoldFns { fold_item: @fn(@item, @ast_fold) -> Option<@item>, fold_struct_field: @fn(@struct_field, @ast_fold) -> @struct_field, fold_item_underscore: @fn(&item_, @ast_fold) -> item_, + fold_type_method: @fn(&TypeMethod, @ast_fold) -> TypeMethod, fold_method: @fn(@method, @ast_fold) -> @method, fold_block: @fn(&Block, @ast_fold) -> Block, fold_stmt: @fn(&Stmt_, Span, @ast_fold) -> (Option, Span), @@ -83,61 +228,20 @@ pub type ast_fold_fns = @AstFoldFns; /* some little folds that probably aren't useful to have in ast_fold itself*/ -//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive -fn fold_meta_item_(mi: @MetaItem, fld: @ast_fold) -> @MetaItem { - @Spanned { - node: - match mi.node { - MetaWord(id) => MetaWord(id), - MetaList(id, ref mis) => { - let fold_meta_item = |x| fold_meta_item_(x, fld); - MetaList( - id, - mis.map(|e| fold_meta_item(*e)) - ) - } - MetaNameValue(id, s) => MetaNameValue(id, s) - }, - span: fld.new_span(mi.span) } -} -//used in noop_fold_item and noop_fold_crate -fn fold_attribute_(at: Attribute, fld: @ast_fold) -> Attribute { - Spanned { - span: fld.new_span(at.span), - node: ast::Attribute_ { - style: at.node.style, - value: fold_meta_item_(at.node.value, fld), - is_sugared_doc: at.node.is_sugared_doc - } - } -} - -//used in noop_fold_foreign_item and noop_fold_fn_decl -fn fold_arg_(a: arg, fld: @ast_fold) -> arg { - ast::arg { - is_mutbl: a.is_mutbl, - ty: fld.fold_ty(&a.ty), - pat: fld.fold_pat(a.pat), - id: fld.new_id(a.id), - } -} - -// build a new vector of tts by appling the ast_fold's fold_ident to -// all of the identifiers in the token trees. -pub fn fold_tts(tts : &[token_tree], f : @ast_fold) -> ~[token_tree] { +pub fn fold_tts(tts : &[token_tree], fld: @ast_fold) -> ~[token_tree] { do tts.map |tt| { match *tt { tt_tok(span, ref tok) => - tt_tok(span,maybe_fold_ident(tok,f)), + tt_tok(span,maybe_fold_ident(tok,fld)), tt_delim(ref tts) => - tt_delim(@mut fold_tts(**tts, f)), + tt_delim(@mut fold_tts(**tts, fld)), tt_seq(span, ref pattern, ref sep, is_optional) => tt_seq(span, - @mut fold_tts(**pattern, f), - sep.map(|tok|maybe_fold_ident(tok,f)), + @mut fold_tts(**pattern, fld), + sep.map(|tok|maybe_fold_ident(tok,fld)), is_optional), tt_nonterminal(sp,ref ident) => - tt_nonterminal(sp,f.fold_ident(*ident)) + tt_nonterminal(sp,fld.fold_ident(*ident)) } } } @@ -153,82 +257,51 @@ fn maybe_fold_ident(t : &token::Token, f: @ast_fold) -> token::Token { pub fn fold_fn_decl(decl: &ast::fn_decl, fld: @ast_fold) -> ast::fn_decl { ast::fn_decl { - inputs: decl.inputs.map(|x| fold_arg_(/*bad*/ (*x).clone(), fld)), + inputs: decl.inputs.map(|x| fld.fold_arg(x)), output: fld.fold_ty(&decl.output), cf: decl.cf, } } -fn fold_ty_param_bound(tpb: &TyParamBound, fld: @ast_fold) -> TyParamBound { - match *tpb { - TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), - RegionTyParamBound => RegionTyParamBound - } -} - -pub fn fold_ty_param(tp: TyParam, - fld: @ast_fold) -> TyParam { - TyParam {ident: tp.ident, - id: fld.new_id(tp.id), - bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld))} -} - -pub fn fold_ty_params(tps: &OptVec, - fld: @ast_fold) -> OptVec { - let tps = /*bad*/ (*tps).clone(); - tps.map_move(|tp| fold_ty_param(tp, fld)) -} - -pub fn fold_lifetime(l: &Lifetime, - fld: @ast_fold) -> Lifetime { - Lifetime {id: fld.new_id(l.id), - span: fld.new_span(l.span), - ident: l.ident} -} - -pub fn fold_lifetimes(lts: &OptVec, - fld: @ast_fold) -> OptVec { - lts.map(|l| fold_lifetime(l, fld)) -} - pub fn fold_generics(generics: &Generics, fld: @ast_fold) -> Generics { - Generics {ty_params: fold_ty_params(&generics.ty_params, fld), - lifetimes: fold_lifetimes(&generics.lifetimes, fld)} + Generics {ty_params: fld.fold_ty_params(&generics.ty_params), + lifetimes: fld.fold_lifetimes(&generics.lifetimes)} } pub fn noop_fold_crate(c: &Crate, fld: @ast_fold) -> Crate { - let fold_meta_item = |x| fold_meta_item_(x, fld); - let fold_attribute = |x| fold_attribute_(x, fld); - Crate { module: fld.fold_mod(&c.module), - attrs: c.attrs.map(|x| fold_attribute(*x)), - config: c.config.map(|x| fold_meta_item(*x)), + attrs: fld.fold_attributes(c.attrs), + config: fld.fold_meta_items(c.config), span: fld.new_span(c.span), } } -fn noop_fold_view_item(vi: &view_item_, _fld: @ast_fold) -> view_item_ { - // FIXME #7654: doesn't iterate over idents in a view_item_use - return /* FIXME (#2543) */ (*vi).clone(); +fn noop_fold_view_item(vi: &view_item_, fld: @ast_fold) -> view_item_ { + match *vi { + view_item_extern_mod(ident, name, ref meta_items, node_id) => { + view_item_extern_mod(ident, + name, + fld.fold_meta_items(*meta_items), + fld.new_id(node_id)) + } + view_item_use(ref view_paths) => { + view_item_use(fld.fold_view_paths(*view_paths)) + } + } } - fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold) -> @foreign_item { - let fold_arg = |x| fold_arg_(x, fld); - let fold_attribute = |x| fold_attribute_(x, fld); - @ast::foreign_item { ident: fld.fold_ident(ni.ident), - attrs: ni.attrs.map(|x| fold_attribute(*x)), + attrs: fld.fold_attributes(ni.attrs), node: match ni.node { foreign_item_fn(ref fdec, ref generics) => { foreign_item_fn( ast::fn_decl { - inputs: fdec.inputs.map(|a| - fold_arg(/*bad*/(*a).clone())), + inputs: fdec.inputs.map(|a| fld.fold_arg(a)), output: fld.fold_ty(&fdec.output), cf: fdec.cf, }, @@ -245,10 +318,8 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold) } pub fn noop_fold_item(i: @item, fld: @ast_fold) -> Option<@item> { - let fold_attribute = |x| fold_attribute_(x, fld); - Some(@ast::item { ident: fld.fold_ident(i.ident), - attrs: i.attrs.map(|e| fold_attribute(*e)), + attrs: fld.fold_attributes(i.attrs), id: fld.new_id(i.id), node: fld.fold_item_underscore(&i.node), vis: i.vis, @@ -257,22 +328,35 @@ pub fn noop_fold_item(i: @item, fld: @ast_fold) -> Option<@item> { fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold) -> @struct_field { - let fold_attribute = |x| fold_attribute_(x, fld); - @Spanned { node: ast::struct_field_ { kind: sf.node.kind, - id: sf.node.id, + id: fld.new_id(sf.node.id), ty: fld.fold_ty(&sf.node.ty), - attrs: sf.node.attrs.map(|e| fold_attribute(*e)) + attrs: fld.fold_attributes(sf.node.attrs), }, span: sf.span } } +pub fn noop_fold_type_method(m: &TypeMethod, fld: @ast_fold) -> TypeMethod { + TypeMethod { + ident: fld.fold_ident(m.ident), + attrs: fld.fold_attributes(m.attrs), + purity: m.purity, + decl: fold_fn_decl(&m.decl, fld), + generics: fold_generics(&m.generics, fld), + explicit_self: m.explicit_self, + id: fld.new_id(m.id), + span: fld.new_span(m.span), + } +} + pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { match *i { - item_static(ref t, m, e) => item_static(fld.fold_ty(t), m, fld.fold_expr(e)), + item_static(ref t, m, e) => { + item_static(fld.fold_ty(t), m, fld.fold_expr(e)) + } item_fn(ref decl, purity, abi, ref generics, ref body) => { item_fn( fold_fn_decl(decl, fld), @@ -282,7 +366,9 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { fld.fold_block(body) ) } - item_mod(ref m) => item_mod(fld.fold_mod(m)), + item_mod(ref m) => { + item_mod(fld.fold_mod(m)) + } item_foreign_mod(ref nm) => { item_foreign_mod(fld.fold_foreign_mod(nm)) } @@ -300,12 +386,12 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { } item_struct(ref struct_def, ref generics) => { let struct_def = fold_struct_def(*struct_def, fld); - item_struct(struct_def, /* FIXME (#2543) */ (*generics).clone()) + item_struct(struct_def, fold_generics(generics, fld)) } item_impl(ref generics, ref ifce, ref ty, ref methods) => { item_impl( fold_generics(generics, fld), - ifce.map(|p| fold_trait_ref(p, fld)), + ifce.map(|p| fld.fold_trait_ref(p)), fld.fold_ty(ty), methods.map(|x| fld.fold_method(*x)) ) @@ -313,13 +399,13 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { item_trait(ref generics, ref traits, ref methods) => { let methods = do methods.map |method| { match *method { - required(*) => (*method).clone(), + required(ref m) => required(fld.fold_type_method(m)), provided(method) => provided(fld.fold_method(method)) } }; item_trait( fold_generics(generics, fld), - traits.map(|p| fold_trait_ref(p, fld)), + traits.map(|p| fld.fold_trait_ref(p)), methods ) } @@ -337,20 +423,13 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: @ast_fold) } } -fn fold_trait_ref(p: &trait_ref, fld: @ast_fold) -> trait_ref { - ast::trait_ref { - path: fld.fold_path(&p.path), - ref_id: fld.new_id(p.ref_id), - } -} - fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field { @Spanned { node: ast::struct_field_ { kind: f.node.kind, id: fld.new_id(f.node.id), ty: fld.fold_ty(&f.node.ty), - attrs: /* FIXME (#2543) */ f.node.attrs.clone(), + attrs: fld.fold_attributes(f.node.attrs), }, span: fld.new_span(f.span), } @@ -359,7 +438,7 @@ fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field { fn noop_fold_method(m: @method, fld: @ast_fold) -> @method { @ast::method { ident: fld.fold_ident(m.ident), - attrs: /* FIXME (#2543) */ m.attrs.clone(), + attrs: fld.fold_attributes(m.attrs), generics: fold_generics(&m.generics, fld), explicit_self: m.explicit_self, purity: m.purity, @@ -654,7 +733,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { fn fold_opt_bounds(b: &Option>, fld: @ast_fold) -> Option> { do b.map |bounds| { - do bounds.map |bound| { fold_ty_param_bound(bound, fld) } + do bounds.map |bound| { fld.fold_ty_param_bound(bound) } } } match *t { @@ -672,12 +751,12 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { onceness: f.onceness, bounds: fold_opt_bounds(&f.bounds, fld), decl: fold_fn_decl(&f.decl, fld), - lifetimes: f.lifetimes.clone(), + lifetimes: fld.fold_lifetimes(&f.lifetimes) }) } ty_bare_fn(ref f) => { ty_bare_fn(@TyBareFn { - lifetimes: f.lifetimes.clone(), + lifetimes: fld.fold_lifetimes(&f.lifetimes), purity: f.purity, abis: f.abis, decl: fold_fn_decl(&f.decl, fld) @@ -715,29 +794,20 @@ fn noop_fold_foreign_mod(nm: &foreign_mod, fld: @ast_fold) -> foreign_mod { } fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { - fn fold_variant_arg_(va: variant_arg, fld: @ast_fold) -> variant_arg { - ast::variant_arg { ty: fld.fold_ty(&va.ty), id: fld.new_id(va.id) } - } - let fold_variant_arg = |x| fold_variant_arg_(x, fld); - - let kind; - match v.kind { + let kind = match v.kind { tuple_variant_kind(ref variant_args) => { - kind = tuple_variant_kind(do variant_args.map |x| { - fold_variant_arg(/*bad*/ (*x).clone()) - }) + tuple_variant_kind(variant_args.map(|x| fld.fold_variant_arg(x))) } struct_variant_kind(ref struct_def) => { - kind = struct_variant_kind(@ast::struct_def { + struct_variant_kind(@ast::struct_def { fields: struct_def.fields.iter() .map(|f| fld.fold_struct_field(*f)).collect(), ctor_id: struct_def.ctor_id.map(|c| fld.new_id(*c)) }) } - } + }; - let fold_attribute = |x| fold_attribute_(x, fld); - let attrs = v.attrs.map(|x| fold_attribute(*x)); + let attrs = fld.fold_attributes(v.attrs); let de = match v.disr_expr { Some(e) => Some(fld.fold_expr(e)), @@ -811,6 +881,7 @@ pub fn default_ast_fold() -> ast_fold_fns { fold_item: noop_fold_item, fold_struct_field: noop_fold_struct_field, fold_item_underscore: noop_fold_item_underscore, + fold_type_method: noop_fold_type_method, fold_method: noop_fold_method, fold_block: noop_fold_block, fold_stmt: |x, s, fld| (noop_fold_stmt(x, fld), s), @@ -840,7 +911,7 @@ impl ast_fold for AstFoldFns { fn fold_view_item(@self, x: &view_item) -> view_item { ast::view_item { node: (self.fold_view_item)(&x.node, self as @ast_fold), - attrs: x.attrs.iter().map(|a| fold_attribute_(*a, self as @ast_fold)).collect(), + attrs: self.fold_attributes(x.attrs), vis: x.vis, span: (self.new_span)(x.span), } @@ -855,9 +926,9 @@ impl ast_fold for AstFoldFns { @Spanned { node: ast::struct_field_ { kind: sf.node.kind, - id: sf.node.id, + id: (self.new_id)(sf.node.id), ty: self.fold_ty(&sf.node.ty), - attrs: sf.node.attrs.clone(), + attrs: self.fold_attributes(sf.node.attrs), }, span: (self.new_span)(sf.span), } @@ -865,6 +936,9 @@ impl ast_fold for AstFoldFns { fn fold_item_underscore(@self, i: &item_) -> item_ { (self.fold_item_underscore)(i, self as @ast_fold) } + fn fold_type_method(@self, m: &TypeMethod) -> TypeMethod { + (self.fold_type_method)(m, self as @ast_fold) + } fn fold_method(@self, x: @method) -> @method { (self.fold_method)(x, self as @ast_fold) } @@ -949,16 +1023,6 @@ impl ast_fold for AstFoldFns { } } -pub trait AstFoldExtensions { - fn fold_attributes(&self, attrs: ~[Attribute]) -> ~[Attribute]; -} - -impl AstFoldExtensions for @ast_fold { - fn fold_attributes(&self, attrs: ~[Attribute]) -> ~[Attribute] { - attrs.map(|x| fold_attribute_(*x, *self)) - } -} - // brson agrees with me that this function's existence is probably // not a good or useful thing. pub fn make_fold(afp: ast_fold_fns) -> @ast_fold { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 5fa28ff21ae..f7c76fee180 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -11,7 +11,6 @@ //! The main parser interface -use ast::NodeId; use ast; use codemap::{Span, CodeMap, FileMap, FileSubstr}; use codemap; @@ -29,7 +28,6 @@ pub mod token; pub mod comments; pub mod attr; - /// Common routines shared by parser mods pub mod common; @@ -42,7 +40,6 @@ pub mod obsolete; // info about a parsing session. pub struct ParseSess { cm: @codemap::CodeMap, // better be the same as the one in the reader! - next_id: NodeId, span_diagnostic: @mut span_handler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions included_mod_stack: ~[Path], @@ -52,7 +49,6 @@ pub fn new_parse_sess(demitter: Option) -> @mut ParseSess { let cm = @CodeMap::new(); @mut ParseSess { cm: cm, - next_id: 1, span_diagnostic: mk_span_handler(mk_handler(demitter), cm), included_mod_stack: ~[], } @@ -63,7 +59,6 @@ pub fn new_parse_sess_special_handler(sh: @mut span_handler, -> @mut ParseSess { @mut ParseSess { cm: cm, - next_id: 1, span_diagnostic: sh, included_mod_stack: ~[], } @@ -201,15 +196,6 @@ pub fn parse_from_source_str( maybe_aborted(r,p) } -// return the next unused node id. -pub fn next_node_id(sess: @mut ParseSess) -> NodeId { - let rv = sess.next_id; - sess.next_id += 1; - // ID 0 is reserved for the crate and doesn't actually exist in the AST - assert!(rv != 0); - return rv; -} - // Create a new parser from a source string pub fn new_parser_from_source_str(sess: @mut ParseSess, cfg: ast::CrateConfig, @@ -364,7 +350,7 @@ mod test { #[test] fn path_exprs_1() { assert_eq!(string_to_expr(@"a"), @ast::Expr{ - id: 1, + id: ast::DUMMY_NODE_ID, node: ast::ExprPath(ast::Path { span: sp(0, 1), global: false, @@ -383,7 +369,7 @@ mod test { #[test] fn path_exprs_2 () { assert_eq!(string_to_expr(@"::a::b"), @ast::Expr { - id:1, + id: ast::DUMMY_NODE_ID, node: ast::ExprPath(ast::Path { span: sp(0, 6), global: true, @@ -441,9 +427,9 @@ mod test { #[test] fn ret_expr() { assert_eq!(string_to_expr(@"return d"), @ast::Expr{ - id:2, + id: ast::DUMMY_NODE_ID, node:ast::ExprRet(Some(@ast::Expr{ - id:1, + id: ast::DUMMY_NODE_ID, node:ast::ExprPath(ast::Path{ span: sp(7, 8), global: false, @@ -465,7 +451,7 @@ mod test { assert_eq!(string_to_stmt(@"b;"), @Spanned{ node: ast::StmtExpr(@ast::Expr { - id: 1, + id: ast::DUMMY_NODE_ID, node: ast::ExprPath(ast::Path { span:sp(0,1), global:false, @@ -478,7 +464,7 @@ mod test { ], }), span: sp(0,1)}, - 2), // fixme + ast::DUMMY_NODE_ID), span: sp(0,1)}) } @@ -490,7 +476,7 @@ mod test { #[test] fn parse_ident_pat () { let parser = string_to_parser(@"b"); assert_eq!(parser.parse_pat(), - @ast::Pat{id:1, // fixme + @ast::Pat{id: ast::DUMMY_NODE_ID, node: ast::PatIdent( ast::BindInfer, ast::Path { @@ -511,17 +497,16 @@ mod test { // check the contents of the tt manually: #[test] fn parse_fundecl () { - // this test depends on the intern order of "fn" and "int", and on the - // assignment order of the NodeIds. + // this test depends on the intern order of "fn" and "int" assert_eq!(string_to_item(@"fn a (b : int) { b; }"), Some( @ast::item{ident:str_to_ident("a"), attrs:~[], - id: 9, // fixme + id: ast::DUMMY_NODE_ID, node: ast::item_fn(ast::fn_decl{ inputs: ~[ast::arg{ is_mutbl: false, - ty: ast::Ty{id:3, // fixme + ty: ast::Ty{id: ast::DUMMY_NODE_ID, node: ast::ty_path(ast::Path{ span:sp(10,13), global:false, @@ -533,11 +518,11 @@ mod test { types: opt_vec::Empty, } ], - }, None, 2), + }, None, ast::DUMMY_NODE_ID), span:sp(10,13) }, pat: @ast::Pat { - id:1, // fixme + id: ast::DUMMY_NODE_ID, node: ast::PatIdent( ast::BindInfer, ast::Path { @@ -556,9 +541,9 @@ mod test { ), span: sp(6,7) }, - id: 4 // fixme + id: ast::DUMMY_NODE_ID }], - output: ast::Ty{id:5, // fixme + output: ast::Ty{id: ast::DUMMY_NODE_ID, node: ast::ty_nil, span:sp(15,15)}, // not sure cf: ast::return_val @@ -573,7 +558,7 @@ mod test { view_items: ~[], stmts: ~[@Spanned{ node: ast::StmtSemi(@ast::Expr{ - id: 6, + id: ast::DUMMY_NODE_ID, node: ast::ExprPath( ast::Path{ span:sp(17,18), @@ -591,10 +576,10 @@ mod test { ], }), span: sp(17,18)}, - 7), // fixme + ast::DUMMY_NODE_ID), span: sp(17,18)}], expr: None, - id: 8, // fixme + id: ast::DUMMY_NODE_ID, rules: ast::DefaultBlock, // no idea span: sp(15,21), }), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9410d0194c3..9a09a1d9cec 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -41,7 +41,7 @@ use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int, lit_char}; use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local}; use ast::{MutImmutable, MutMutable, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mt, BiMul, Mutability}; -use ast::{named_field, UnNeg, NodeId, noreturn, UnNot, Pat, PatBox, PatEnum}; +use ast::{named_field, UnNeg, noreturn, UnNot, Pat, PatBox, PatEnum}; use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatUniq, PatWild, private}; use ast::{BiRem, required}; @@ -76,7 +76,7 @@ use parse::token::{is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents}; use parse::token::{token_to_binop}; use parse::token; -use parse::{new_sub_parser_from_file, next_node_id, ParseSess}; +use parse::{new_sub_parser_from_file, ParseSess}; use opt_vec; use opt_vec::OptVec; @@ -507,7 +507,7 @@ impl Parser { let ident = self.parse_ident(); let hi = self.last_span.hi; spanned(lo, hi, ast::path_list_ident_ { name: ident, - id: self.get_id() }) + id: ast::DUMMY_NODE_ID }) } // consume token 'tok' if it exists. Returns true if the given @@ -758,7 +758,6 @@ impl Parser { pub fn abort_if_errors(&self) { self.sess.span_diagnostic.handler().abort_if_errors(); } - pub fn get_id(&self) -> NodeId { next_node_id(self.sess) } pub fn id_to_str(&self, id: Ident) -> @str { get_ident_interner().get(id.name) @@ -961,7 +960,7 @@ impl Parser { decl: d, generics: generics, explicit_self: explicit_self, - id: p.get_id(), + id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi) }) } @@ -978,9 +977,9 @@ impl Parser { purity: pur, decl: d, body: body, - id: p.get_id(), + id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - self_id: p.get_id(), + self_id: ast::DUMMY_NODE_ID, vis: vis, }) } @@ -1028,7 +1027,7 @@ impl Parser { ( noreturn, Ty { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ty_bot, span: mk_sp(lo, self.last_span.hi) } @@ -1041,7 +1040,7 @@ impl Parser { ( return_val, Ty { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ty_nil, span: mk_sp(pos, pos), } @@ -1154,14 +1153,14 @@ impl Parser { path, bounds } = self.parse_path(LifetimeAndTypesAndBounds); - ty_path(path, bounds, self.get_id()) + ty_path(path, bounds, ast::DUMMY_NODE_ID) } else { self.fatal(fmt!("expected type, found token %?", *self.token)); }; let sp = mk_sp(lo, self.last_span.hi); - Ty {id: self.get_id(), node: t, span: sp} + Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp} } // parse the type following a @ or a ~ @@ -1275,7 +1274,7 @@ impl Parser { pat } else { debug!("parse_arg_general ident_to_pat"); - ast_util::ident_to_pat(self.get_id(), + ast_util::ident_to_pat(ast::DUMMY_NODE_ID, *self.last_span, special_idents::invalid) }; @@ -1286,7 +1285,7 @@ impl Parser { is_mutbl: is_mutbl, ty: t, pat: pat, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, } } @@ -1304,7 +1303,7 @@ impl Parser { self.parse_ty(false) } else { Ty { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ty_infer, span: mk_sp(self.span.lo, self.span.hi), } @@ -1313,7 +1312,7 @@ impl Parser { is_mutbl: is_mutbl, ty: t, pat: pat, - id: self.get_id() + id: ast::DUMMY_NODE_ID }) } @@ -1562,7 +1561,7 @@ impl Parser { let span = self.span; self.bump(); return ast::Lifetime { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, span: *span, ident: i }; @@ -1575,7 +1574,7 @@ impl Parser { self.expect(&token::BINOP(token::SLASH)); self.obsolete(*self.last_span, ObsoleteLifetimeNotation); return ast::Lifetime { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, span: *span, ident: i }; @@ -1654,18 +1653,18 @@ impl Parser { pub fn mk_expr(&self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr { @Expr { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: node, span: mk_sp(lo, hi), } } pub fn mk_unary(&self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ { - ExprUnary(self.get_id(), unop, expr) + ExprUnary(ast::DUMMY_NODE_ID, unop, expr) } pub fn mk_binary(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { - ExprBinary(self.get_id(), binop, lhs, rhs) + ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs) } pub fn mk_call(&self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ { @@ -1678,11 +1677,11 @@ impl Parser { tps: ~[Ty], args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ { - ExprMethodCall(self.get_id(), rcvr, ident, tps, args, sugar) + ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar) } pub fn mk_index(&self, expr: @Expr, idx: @Expr) -> ast::Expr_ { - ExprIndex(self.get_id(), expr, idx) + ExprIndex(ast::DUMMY_NODE_ID, expr, idx) } pub fn mk_field(&self, expr: @Expr, ident: Ident, tys: ~[Ty]) -> ast::Expr_ { @@ -1690,12 +1689,12 @@ impl Parser { } pub fn mk_assign_op(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { - ExprAssignOp(self.get_id(), binop, lhs, rhs) + ExprAssignOp(ast::DUMMY_NODE_ID, binop, lhs, rhs) } pub fn mk_mac_expr(&self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr { @Expr { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}), span: mk_sp(lo, hi), } @@ -1709,7 +1708,7 @@ impl Parser { }; @Expr { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ExprLit(lv_lit), span: *span, } @@ -2415,7 +2414,7 @@ impl Parser { ast::fn_decl { inputs: ~[], output: Ty { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span }, @@ -2450,7 +2449,7 @@ impl Parser { view_items: ~[], stmts: ~[], expr: Some(body), - id: self.get_id(), + id: ast::DUMMY_NODE_ID, rules: DefaultBlock, span: body.span, }; @@ -2631,7 +2630,7 @@ impl Parser { view_items: ~[], stmts: ~[], expr: Some(expr), - id: self.get_id(), + id: ast::DUMMY_NODE_ID, rules: DefaultBlock, span: expr.span, }; @@ -2764,7 +2763,7 @@ impl Parser { subpat = self.parse_pat(); } else { subpat = @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: PatIdent(BindInfer, fieldpath, None), span: *self.last_span }; @@ -2788,7 +2787,7 @@ impl Parser { pat = PatWild; hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -2806,7 +2805,7 @@ impl Parser { span: _}), _ }) => { let vst = @Expr { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ExprVstore(e, ExprVstoreBox), span: mk_sp(lo, hi), }; @@ -2816,7 +2815,7 @@ impl Parser { }; hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -2834,7 +2833,7 @@ impl Parser { span: _}), _ }) => { let vst = @Expr { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ExprVstore(e, ExprVstoreUniq), span: mk_sp(lo, hi), }; @@ -2844,7 +2843,7 @@ impl Parser { }; hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -2862,7 +2861,7 @@ impl Parser { node: lit_str(_), span: _}), _ }) => { let vst = @Expr { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ExprVstore(e, ExprVstoreSlice), span: mk_sp(lo, hi) }; @@ -2872,7 +2871,7 @@ impl Parser { }; hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -2885,7 +2884,7 @@ impl Parser { pat = PatWild; hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -2915,7 +2914,7 @@ impl Parser { } hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -2930,7 +2929,7 @@ impl Parser { pat = ast::PatVec(before, slice, after); hi = self.last_span.hi; return @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) } @@ -3046,7 +3045,7 @@ impl Parser { } hi = self.last_span.hi; @ast::Pat { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi), } @@ -3095,7 +3094,7 @@ impl Parser { } let mut ty = Ty { - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: ty_infer, span: mk_sp(lo, lo), }; @@ -3106,7 +3105,7 @@ impl Parser { ty: ty, pat: pat, init: init, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, span: mk_sp(lo, self.last_span.hi), } } @@ -3136,7 +3135,7 @@ impl Parser { let ty = self.parse_ty(false); @spanned(lo, self.last_span.hi, ast::struct_field_ { kind: named_field(name, pr), - id: self.get_id(), + id: ast::DUMMY_NODE_ID, ty: ty, attrs: attrs, }) @@ -3159,7 +3158,7 @@ impl Parser { check_expected_item(self, !item_attrs.is_empty()); self.expect_keyword(keywords::Let); let decl = self.parse_let(); - return @spanned(lo, decl.span.hi, StmtDecl(decl, self.get_id())); + return @spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); } else if is_ident(&*self.token) && !token::is_any_keyword(self.token) && self.look_ahead(1, |t| *t == token::NOT) { @@ -3208,7 +3207,7 @@ impl Parser { lo, hi, id /*id is good here*/, item_mac(spanned(lo, hi, mac_invoc_tt(pth, tts, EMPTY_CTXT))), inherited, ~[/*no attrs*/]))), - self.get_id())); + ast::DUMMY_NODE_ID)); } } else { @@ -3217,7 +3216,7 @@ impl Parser { iovi_item(i) => { let hi = i.span.hi; let decl = @spanned(lo, hi, DeclItem(i)); - return @spanned(lo, hi, StmtDecl(decl, self.get_id())); + return @spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); } iovi_view_item(vi) => { self.span_fatal(vi.span, @@ -3233,7 +3232,7 @@ impl Parser { // Remainder are line-expr stmts. let e = self.parse_expr_res(RESTRICT_STMT_EXPR); - return @spanned(lo, e.span.hi, StmtExpr(e, self.get_id())); + return @spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)); } } @@ -3298,7 +3297,7 @@ impl Parser { for item in items.iter() { let decl = @spanned(item.span.lo, item.span.hi, DeclItem(*item)); stmts.push(@spanned(item.span.lo, item.span.hi, - StmtDecl(decl, self.get_id()))); + StmtDecl(decl, ast::DUMMY_NODE_ID))); } let mut attributes_box = attrs_remaining; @@ -3397,7 +3396,7 @@ impl Parser { view_items: view_items, stmts: stmts, expr: expr, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, rules: s, span: mk_sp(lo, hi), } @@ -3463,7 +3462,7 @@ impl Parser { let opt_bounds = self.parse_optional_ty_param_bounds(); // For typarams we don't care about the difference b/w "" and "". let bounds = opt_bounds.unwrap_or_default(opt_vec::Empty); - ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } + ast::TyParam { ident: ident, id: ast::DUMMY_NODE_ID, bounds: bounds } } // parse a set of optional generic type parameter declarations @@ -3717,7 +3716,7 @@ impl Parser { let output = if self.eat(&token::RARROW) { self.parse_ty(false) } else { - Ty { id: self.get_id(), node: ty_infer, span: *self.span } + Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span } }; ast::fn_decl { @@ -3739,7 +3738,7 @@ impl Parser { attrs: ~[Attribute]) -> @item { @ast::item { ident: ident, attrs: attrs, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, node: node, vis: vis, span: mk_sp(lo, hi) } @@ -3779,9 +3778,9 @@ impl Parser { purity: pur, decl: decl, body: body, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - self_id: self.get_id(), + self_id: ast::DUMMY_NODE_ID, vis: visa, } } @@ -3873,7 +3872,7 @@ impl Parser { fn parse_trait_ref(&self) -> trait_ref { ast::trait_ref { path: self.parse_path(LifetimeAndTypesWithoutColons).path, - ref_id: self.get_id(), + ref_id: ast::DUMMY_NODE_ID, } } @@ -3926,7 +3925,7 @@ impl Parser { let lo = p.span.lo; let struct_field_ = ast::struct_field_ { kind: unnamed_field, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, ty: p.parse_ty(false), attrs: attrs, }; @@ -3947,8 +3946,8 @@ impl Parser { ); } - let _ = self.get_id(); // XXX: Workaround for crazy bug. - let new_id = self.get_id(); + let _ = ast::DUMMY_NODE_ID; // XXX: Workaround for crazy bug. + let new_id = ast::DUMMY_NODE_ID; (class_name, item_struct(@ast::struct_def { fields: fields, @@ -4238,7 +4237,7 @@ impl Parser { @ast::foreign_item { ident: ident, attrs: attrs, node: foreign_item_fn(decl, generics), - id: self.get_id(), + id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), vis: vis } } @@ -4264,7 +4263,7 @@ impl Parser { @ast::foreign_item { ident: ident, attrs: attrs, node: foreign_item_static(ty, mutbl), - id: self.get_id(), + id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), vis: vis } } @@ -4386,7 +4385,7 @@ impl Parser { let metadata = self.parse_optional_meta(); self.expect(&token::SEMI); iovi_view_item(ast::view_item { - node: view_item_extern_mod(ident, maybe_path, metadata, self.get_id()), + node: view_item_extern_mod(ident, maybe_path, metadata, ast::DUMMY_NODE_ID), attrs: attrs, vis: visibility, span: mk_sp(lo, self.last_span.hi) @@ -4461,7 +4460,7 @@ impl Parser { for ty in arg_tys.move_iter() { args.push(ast::variant_arg { ty: ty, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, }); } kind = tuple_variant_kind(args); @@ -4477,7 +4476,7 @@ impl Parser { name: ident, attrs: variant_attrs, kind: kind, - id: self.get_id(), + id: ast::DUMMY_NODE_ID, disr_expr: disr_expr, vis: vis, }; @@ -4509,9 +4508,9 @@ impl Parser { name: id, attrs: ~[], kind: tuple_variant_kind( - ~[ast::variant_arg {ty: ty, id: self.get_id()}] + ~[ast::variant_arg {ty: ty, id: ast::DUMMY_NODE_ID}] ), - id: self.get_id(), + id: ast::DUMMY_NODE_ID, disr_expr: None, vis: public, }); @@ -4886,7 +4885,7 @@ impl Parser { return @spanned(lo, self.span.hi, view_path_simple(first_ident, path, - self.get_id())); + ast::DUMMY_NODE_ID)); } token::MOD_SEP => { @@ -4920,7 +4919,7 @@ impl Parser { }).collect() }; return @spanned(lo, self.span.hi, - view_path_list(path, idents, self.get_id())); + view_path_list(path, idents, ast::DUMMY_NODE_ID)); } // foo::bar::* @@ -4938,7 +4937,7 @@ impl Parser { }).collect() }; return @spanned(lo, self.span.hi, - view_path_glob(path, self.get_id())); + view_path_glob(path, ast::DUMMY_NODE_ID)); } _ => break @@ -4961,7 +4960,7 @@ impl Parser { }; return @spanned(lo, self.last_span.hi, - view_path_simple(last, path, self.get_id())); + view_path_simple(last, path, ast::DUMMY_NODE_ID)); } // matches view_paths = view_path | view_path , view_paths @@ -5008,7 +5007,7 @@ impl Parser { } else { None }; let metadata = self.parse_optional_meta(); - view_item_extern_mod(ident, path, metadata, self.get_id()) + view_item_extern_mod(ident, path, metadata, ast::DUMMY_NODE_ID) } else { self.bug("expected view item"); }; diff --git a/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs b/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs new file mode 100644 index 00000000000..65d377173c8 --- /dev/null +++ b/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs @@ -0,0 +1,29 @@ +// Check that we do not ICE when compiling this +// macro, which reuses the expression `$id` + +struct Foo { + a: int +} + +pub enum Bar { + Bar1, Bar2(int, ~Bar), +} + +impl Foo { + fn elaborate_stm(&mut self, s: ~Bar) -> ~Bar { + macro_rules! declare( + ($id:expr, $rest:expr) => ({ + self.check_id($id); + ~Bar2($id, $rest) + }) + ); + match s { + ~Bar2(id, rest) => declare!(id, self.elaborate_stm(rest)), + _ => fail!() + } + } + + fn check_id(&mut self, s: int) { fail!() } +} + +fn main() { } diff --git a/src/test/run-pass/typeck-macro-interaction-issue-8852.rs b/src/test/run-pass/typeck-macro-interaction-issue-8852.rs new file mode 100644 index 00000000000..a1368365c40 --- /dev/null +++ b/src/test/run-pass/typeck-macro-interaction-issue-8852.rs @@ -0,0 +1,22 @@ +enum T { + A(int), + B(float) +} + +macro_rules! test( + ($e:expr) => ( + fn foo(a:T, b:T) -> T { + match (a, b) { + (A(x), A(y)) => A($e), + (B(x), B(y)) => B($e), + _ => fail!() + } + } + ) +) + +test!(x + y) + +fn main() { + foo(A(1), A(2)); +} \ No newline at end of file