diff options
| author | bors <bors@rust-lang.org> | 2014-12-22 00:12:47 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-12-22 00:12:47 +0000 |
| commit | 34d680009205de2302b902d8f9f5f7ae7a042f1a (patch) | |
| tree | 2b7eb92a4d5a0d997871020964fe539390737dd3 /src/libsyntax/ext | |
| parent | 1bdcfd64629930c09b942025e242e51e784c447d (diff) | |
| parent | fb7c08876e7b29c1b9d57df905f3ee0deec46aa1 (diff) | |
auto merge of #20104 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 61 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/ext/mtwt.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/transcribe.rs | 24 |
7 files changed, 60 insertions, 34 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3947a602809..aefbb2a1fea 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -490,7 +490,7 @@ impl<'a> ExtCtxt<'a> { /// Returns a `Folder` for deeply expanding all macros in a AST node. pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> { - expand::MacroExpander { cx: self } + expand::MacroExpander::new(self) } pub fn new_parser_from_tts(&self, tts: &[ast::TokenTree]) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index d35091f8ab0..9d4992f7453 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -868,7 +868,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { - self.expr(span, ast::ExprMatch(arg, arms, ast::MatchNormal)) + self.expr(span, ast::ExprMatch(arg, arms, ast::MatchSource::Normal)) } fn expr_if(&self, span: Span, cond: P<ast::Expr>, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 20c8ff20b71..b10ae7a09db 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -15,6 +15,7 @@ use ast::{ItemMac, MacStmtWithSemicolon, Mrk, Stmt, StmtDecl, StmtMac}; use ast::{StmtExpr, StmtSemi}; use ast::TokenTree; use ast; +use ast_util::path_to_ident; use ext::mtwt; use ext::build::AstBuilder; use attr; @@ -37,6 +38,30 @@ enum Either<L,R> { Right(R) } +pub fn expand_type(t: P<ast::Ty>, + fld: &mut MacroExpander, + impl_ty: Option<P<ast::Ty>>) + -> P<ast::Ty> { + debug!("expanding type {} with impl_ty {}", t, impl_ty); + let t = match (t.node.clone(), impl_ty) { + // Expand uses of `Self` in impls to the concrete type. + (ast::Ty_::TyPath(ref path, _), Some(ref impl_ty)) => { + let path_as_ident = path_to_ident(path); + // Note unhygenic comparison here. I think this is correct, since + // even though `Self` is almost just a type parameter, the treatment + // for this expansion is as if it were a keyword. + if path_as_ident.is_some() && + path_as_ident.unwrap().name == token::special_idents::type_self.name { + impl_ty.clone() + } else { + t + } + } + _ => t + }; + fold::noop_fold_ty(t, fld) +} + pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { e.and_then(|ast::Expr {id, node, span}| match node { // expr_mac should really be expr_ext or something; it's the @@ -97,7 +122,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { // `match <expr> { ... }` let arms = vec![pat_arm, break_arm]; let match_expr = fld.cx.expr(span, - ast::ExprMatch(expr, arms, ast::MatchWhileLetDesugar)); + ast::ExprMatch(expr, arms, ast::MatchSource::WhileLetDesugar)); // `[opt_ident]: loop { ... }` let loop_block = fld.cx.block_expr(match_expr); @@ -158,6 +183,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { arms }; + let contains_else_clause = elseopt.is_some(); + // `_ => [<elseopt> | ()]` let else_arm = { let pat_under = fld.cx.pat_wild(span); @@ -170,7 +197,11 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { arms.extend(else_if_arms.into_iter()); arms.push(else_arm); - let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, arms, ast::MatchIfLetDesugar)); + let match_expr = fld.cx.expr(span, + ast::ExprMatch(expr, arms, + ast::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + })); fld.fold_expr(match_expr) } @@ -1059,6 +1090,14 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl /// A tree-folder that performs macro expansion pub struct MacroExpander<'a, 'b:'a> { pub cx: &'a mut ExtCtxt<'b>, + // The type of the impl currently being expanded. + current_impl_type: Option<P<ast::Ty>>, +} + +impl<'a, 'b> MacroExpander<'a, 'b> { + pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> { + MacroExpander { cx: cx, current_impl_type: None } + } } impl<'a, 'b> Folder for MacroExpander<'a, 'b> { @@ -1071,7 +1110,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { } fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> { - expand_item(item, self) + let prev_type = self.current_impl_type.clone(); + if let ast::Item_::ItemImpl(_, _, _, ref ty, _) = item.node { + self.current_impl_type = Some(ty.clone()); + } + + let result = expand_item(item, self); + self.current_impl_type = prev_type; + result } fn fold_item_underscore(&mut self, item: ast::Item_) -> ast::Item_ { @@ -1094,6 +1140,11 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_method(method, self) } + fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> { + let impl_type = self.current_impl_type.clone(); + expand_type(t, self, impl_type) + } + fn new_span(&mut self, span: Span) -> Span { new_span(self.cx, span) } @@ -1138,9 +1189,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, user_exts: Vec<NamedSyntaxExtension>, c: Crate) -> Crate { let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); - let mut expander = MacroExpander { - cx: &mut cx, - }; + let mut expander = MacroExpander::new(&mut cx); for ExportedMacros { crate_name, macros } in imported_macros.into_iter() { let name = format!("<{} macros>", token::get_ident(crate_name)) diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 5d595474e9c..95c7fcc564a 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -654,6 +654,7 @@ impl<'a, 'b> Context<'a, 'b> { Known(ref tyname) => { match tyname.as_slice() { "" => "Show", + "?" => "Show", "e" => "LowerExp", "E" => "UpperExp", "o" => "Octal", diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index ae979020bc7..f0392912878 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -21,7 +21,7 @@ use ast::{Ident, Mrk, Name, SyntaxContext}; use std::cell::RefCell; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; /// The SCTable contains a table of SyntaxContext_'s. It /// represents a flattened tree structure, to avoid having diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 4785fe37293..bc639c32380 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -98,7 +98,7 @@ use ptr::P; use std::mem; use std::rc::Rc; use std::collections::HashMap; -use std::collections::hash_map::{Vacant, Occupied}; +use std::collections::hash_map::Entry::{Vacant, Occupied}; // To avoid costly uniqueness checks, we require that `MatchSeq` always has // a nonempty body. diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index e2439bad178..378dbba07fa 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -106,30 +106,6 @@ enum LockstepIterSize { LisContradiction(String), } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize { - fn add(&self, other: &LockstepIterSize) -> LockstepIterSize { - match *self { - LisUnconstrained => other.clone(), - LisContradiction(_) => self.clone(), - LisConstraint(l_len, l_id) => match *other { - LisUnconstrained => self.clone(), - LisContradiction(_) => other.clone(), - LisConstraint(r_len, _) if l_len == r_len => self.clone(), - LisConstraint(r_len, r_id) => { - let l_n = token::get_ident(l_id); - let r_n = token::get_ident(r_id); - LisContradiction(format!("inconsistent lockstep iteration: \ - '{}' has {} items, but '{}' has {}", - l_n, l_len, r_n, r_len).to_string()) - } - }, - } - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize { fn add(self, other: LockstepIterSize) -> LockstepIterSize { match self { |
