"for every macro invocation, print its name and arguments"),
enable_nonzeroing_move_hints: bool = (false, parse_bool,
"force nonzeroing move optimization on"),
- keep_mtwt_tables: bool = (false, parse_bool,
- "don't clear the resolution tables after analysis"),
+ keep_hygiene_data: bool = (false, parse_bool,
+ "don't clear the hygiene data after analysis"),
keep_ast: bool = (false, parse_bool,
"keep the AST after lowering it to HIR"),
show_span: Option<String> = (None, parse_opt_string,
Ok(())
}
-fn keep_mtwt_tables(sess: &Session) -> bool {
- sess.opts.debugging_opts.keep_mtwt_tables
+fn keep_hygiene_data(sess: &Session) -> bool {
+ sess.opts.debugging_opts.keep_hygiene_data
}
fn keep_ast(sess: &Session) -> bool {
input: &Input)
-> PResult<'a, ast::Crate> {
// These may be left in an incoherent state after a previous compile.
- syntax::ext::mtwt::reset_hygiene_data();
+ syntax::ext::hygiene::reset_hygiene_data();
// `clear_ident_interner` can be used to free memory, but it does not restore the initial state.
token::reset_ident_interner();
let continue_after_error = sess.opts.continue_parse_after_error;
hir_map::Forest::new(lower_crate(sess, &krate, &mut resolver), &sess.dep_graph)
});
- // Discard MTWT tables that aren't required past lowering to HIR.
- if !keep_mtwt_tables(sess) {
- syntax::ext::mtwt::reset_hygiene_data();
+ // Discard hygiene data, which isn't required past lowering to HIR.
+ if !keep_hygiene_data(sess) {
+ syntax::ext::hygiene::reset_hygiene_data();
}
Ok(ExpansionResult {
use Resolver;
use rustc::session::Session;
use syntax::ast;
-use syntax::ext::mtwt::Mark;
+use syntax::ext::hygiene::Mark;
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::util::move_map::MoveMap;
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
-use syntax::ext::mtwt::Mark;
+use syntax::ext::hygiene::Mark;
use syntax::ast::{self, FloatTy};
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
use syntax::parse::token::{self, keywords};
use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
use codemap::{respan, Spanned};
use abi::Abi;
-use ext::mtwt::SyntaxContext;
+use ext::hygiene::SyntaxContext;
use parse::token::{self, keywords, InternedString};
use print::pprust;
use ptr::P;
use ast::{Block, Crate, Ident, Mac_, Name, PatKind};
use ast::{MacStmtStyle, Stmt, StmtKind, ItemKind};
use ast;
-use ext::mtwt::Mark;
+use ext::hygiene::Mark;
use attr::{self, HasAttrs};
use attr::AttrMetaMethods;
use codemap::{dummy_spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
--- /dev/null
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Machinery for hygienic macros, inspired by the MTWT[1] paper.
+//!
+//! [1] Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler.
+//! 2012. *Macros that work together: Compile-time bindings, partial expansion,
+//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216.
+//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093
+
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::fmt;
+
+/// A SyntaxContext represents a chain of macro expansions (represented by marks).
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Default)]
+pub struct SyntaxContext(u32);
+
+#[derive(Copy, Clone)]
+pub struct SyntaxContextData {
+ pub outer_mark: Mark,
+ pub prev_ctxt: SyntaxContext,
+}
+
+/// A mark represents a unique id associated with a macro expansion.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
+pub struct Mark(u32);
+
+impl Mark {
+ pub fn fresh() -> Self {
+ HygieneData::with(|data| {
+ let next_mark = Mark(data.next_mark.0 + 1);
+ ::std::mem::replace(&mut data.next_mark, next_mark)
+ })
+ }
+}
+
+struct HygieneData {
+ syntax_contexts: Vec<SyntaxContextData>,
+ markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
+ next_mark: Mark,
+}
+
+impl HygieneData {
+ fn new() -> Self {
+ HygieneData {
+ syntax_contexts: vec![SyntaxContextData {
+ outer_mark: Mark(0), // the null mark
+ prev_ctxt: SyntaxContext(0), // the empty context
+ }],
+ markings: HashMap::new(),
+ next_mark: Mark(1),
+ }
+ }
+
+ fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
+ thread_local! {
+ static HYGIENE_DATA: RefCell<HygieneData> = RefCell::new(HygieneData::new());
+ }
+ HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut()))
+ }
+}
+
+pub fn reset_hygiene_data() {
+ HygieneData::with(|data| *data = HygieneData::new())
+}
+
+impl SyntaxContext {
+ pub const fn empty() -> Self {
+ SyntaxContext(0)
+ }
+
+ pub fn data(self) -> SyntaxContextData {
+ HygieneData::with(|data| data.syntax_contexts[self.0 as usize])
+ }
+
+ /// Extend a syntax context with a given mark
+ pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
+ // Applying the same mark twice is a no-op
+ let ctxt_data = self.data();
+ if mark == ctxt_data.outer_mark {
+ return ctxt_data.prev_ctxt;
+ }
+
+ HygieneData::with(|data| {
+ let syntax_contexts = &mut data.syntax_contexts;
+ *data.markings.entry((self, mark)).or_insert_with(|| {
+ syntax_contexts.push(SyntaxContextData {
+ outer_mark: mark,
+ prev_ctxt: self,
+ });
+ SyntaxContext(syntax_contexts.len() as u32 - 1)
+ })
+ })
+ }
+
+ /// If `ident` is macro expanded, return the source ident from the macro definition
+ /// and the mark of the expansion that created the macro definition.
+ pub fn source(self) -> (Self /* source context */, Mark /* source macro */) {
+ let macro_def_ctxt = self.data().prev_ctxt.data();
+ (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark)
+ }
+}
+
+impl fmt::Debug for SyntaxContext {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "#{}", self.0)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use ast::{EMPTY_CTXT, Mrk, SyntaxContext};
+ use super::{apply_mark_internal, new_sctable_internal, Mark, SCTable};
+
+ // extend a syntax context with a sequence of marks given
+ // in a vector. v[0] will be the outermost mark.
+ fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
+ -> SyntaxContext {
+ mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
+ {apply_mark_internal(*mrk,tail,table)})
+ }
+
+ #[test] fn unfold_marks_test() {
+ let mut t = new_sctable_internal();
+
+ assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),SyntaxContext(2));
+ {
+ let table = t.table.borrow();
+ assert!((*table)[1] == Mark(7,EMPTY_CTXT));
+ assert!((*table)[2] == Mark(3,SyntaxContext(1)));
+ }
+ }
+
+ #[test]
+ fn hashing_tests () {
+ let mut t = new_sctable_internal();
+ assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1));
+ assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),SyntaxContext(2));
+ // using the same one again should result in the same index:
+ assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1));
+ // I'm assuming that the rename table will behave the same....
+ }
+}
+++ /dev/null
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Machinery for hygienic macros, as described in the MTWT[1] paper.
-//!
-//! [1] Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler.
-//! 2012. *Macros that work together: Compile-time bindings, partial expansion,
-//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216.
-//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093
-
-use std::cell::RefCell;
-use std::collections::HashMap;
-use std::fmt;
-
-/// A SyntaxContext represents a chain of macro expansions (represented by marks).
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Default)]
-pub struct SyntaxContext(u32);
-
-#[derive(Copy, Clone)]
-pub struct SyntaxContextData {
- pub outer_mark: Mark,
- pub prev_ctxt: SyntaxContext,
-}
-
-/// A mark represents a unique id associated with a macro expansion.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
-pub struct Mark(u32);
-
-impl Mark {
- pub fn fresh() -> Self {
- HygieneData::with(|data| {
- let next_mark = Mark(data.next_mark.0 + 1);
- ::std::mem::replace(&mut data.next_mark, next_mark)
- })
- }
-}
-
-struct HygieneData {
- syntax_contexts: Vec<SyntaxContextData>,
- markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
- next_mark: Mark,
-}
-
-impl HygieneData {
- fn new() -> Self {
- HygieneData {
- syntax_contexts: vec![SyntaxContextData {
- outer_mark: Mark(0), // the null mark
- prev_ctxt: SyntaxContext(0), // the empty context
- }],
- markings: HashMap::new(),
- next_mark: Mark(1),
- }
- }
-
- fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
- thread_local! {
- static HYGIENE_DATA: RefCell<HygieneData> = RefCell::new(HygieneData::new());
- }
- HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut()))
- }
-}
-
-pub fn reset_hygiene_data() {
- HygieneData::with(|data| *data = HygieneData::new())
-}
-
-impl SyntaxContext {
- pub const fn empty() -> Self {
- SyntaxContext(0)
- }
-
- pub fn data(self) -> SyntaxContextData {
- HygieneData::with(|data| data.syntax_contexts[self.0 as usize])
- }
-
- /// Extend a syntax context with a given mark
- pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
- // Applying the same mark twice is a no-op
- let ctxt_data = self.data();
- if mark == ctxt_data.outer_mark {
- return ctxt_data.prev_ctxt;
- }
-
- HygieneData::with(|data| {
- let syntax_contexts = &mut data.syntax_contexts;
- *data.markings.entry((self, mark)).or_insert_with(|| {
- syntax_contexts.push(SyntaxContextData {
- outer_mark: mark,
- prev_ctxt: self,
- });
- SyntaxContext(syntax_contexts.len() as u32 - 1)
- })
- })
- }
-
- /// If `ident` is macro expanded, return the source ident from the macro definition
- /// and the mark of the expansion that created the macro definition.
- pub fn source(self) -> (Self /* source context */, Mark /* source macro */) {
- let macro_def_ctxt = self.data().prev_ctxt.data();
- (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark)
- }
-}
-
-impl fmt::Debug for SyntaxContext {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "#{}", self.0)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use ast::{EMPTY_CTXT, Mrk, SyntaxContext};
- use super::{apply_mark_internal, new_sctable_internal, Mark, SCTable};
-
- // extend a syntax context with a sequence of marks given
- // in a vector. v[0] will be the outermost mark.
- fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
- -> SyntaxContext {
- mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
- {apply_mark_internal(*mrk,tail,table)})
- }
-
- #[test] fn unfold_marks_test() {
- let mut t = new_sctable_internal();
-
- assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),SyntaxContext(2));
- {
- let table = t.table.borrow();
- assert!((*table)[1] == Mark(7,EMPTY_CTXT));
- assert!((*table)[2] == Mark(3,SyntaxContext(1)));
- }
- }
-
- #[test]
- fn hashing_tests () {
- let mut t = new_sctable_internal();
- assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1));
- assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),SyntaxContext(2));
- // using the same one again should result in the same index:
- assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1));
- // I'm assuming that the rename table will behave the same....
- }
-}
pub mod base;
pub mod build;
pub mod expand;
- pub mod mtwt;
+ pub mod hygiene;
pub mod quote;
pub mod source_util;