auto merge of #9088 : nikomatsakis/rust/issue-6304-AST-tree-not-DAG, r=catamorphism
Ensures that each AST node has a unique id. Fixes numerous bugs in macro expansion and deriving. Add two representative tests. Fixes #7971 Fixes #6304 Fixes #8367 Fixes #8754 Fixes #8852 Fixes #2543 Fixes #7654
This commit is contained in:
commit
753d8c226c
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<ast::NodeId, ~[(lint::lint, codemap::Span, ~str)]>,
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
19
src/librustc/front/assign_node_ids.rs
Normal file
19
src/librustc/front/assign_node_ids.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
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)
|
||||
}
|
@ -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(),
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
@ -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<T:Send>(
|
||||
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 {
|
||||
|
@ -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"));
|
||||
}
|
||||
|
||||
|
@ -285,6 +285,7 @@ mod test {
|
||||
|
||||
fn mk_doc(source: @str) -> doc::Doc {
|
||||
let ast = parse::from_str(source);
|
||||
debug!("ast=%?", ast);
|
||||
extract(ast, ~"")
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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<OptVec<ast::TyParamBound>>)
|
||||
-> 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::TyParamBound>) -> 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))])
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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"));
|
||||
|
@ -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<T : 'static + CtxtFn>(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)
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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<T>(@self, s: &Spanned<T>, f: &fn(&T) -> T) -> Spanned<T> {
|
||||
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<TyParam>) -> OptVec<TyParam> {
|
||||
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<Lifetime>) -> OptVec<Lifetime> {
|
||||
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<Stmt_>, 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<TyParam>,
|
||||
fld: @ast_fold) -> OptVec<TyParam> {
|
||||
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<Lifetime>,
|
||||
fld: @ast_fold) -> OptVec<Lifetime> {
|
||||
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<OptVec<TyParamBound>>, fld: @ast_fold)
|
||||
-> Option<OptVec<TyParamBound>> {
|
||||
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 {
|
||||
|
@ -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<Emitter>) -> @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<T>(
|
||||
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),
|
||||
}),
|
||||
|
@ -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 "<T>" and "<T:>".
|
||||
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");
|
||||
};
|
||||
|
29
src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
Normal file
29
src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
Normal file
@ -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() { }
|
22
src/test/run-pass/typeck-macro-interaction-issue-8852.rs
Normal file
22
src/test/run-pass/typeck-macro-interaction-issue-8852.rs
Normal file
@ -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));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user