about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/config.rs49
-rw-r--r--src/libsyntax/diagnostic.rs11
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/build.rs56
-rw-r--r--src/libsyntax/ext/cfg_attr.rs34
-rw-r--r--src/libsyntax/ext/expand.rs4
-rw-r--r--src/libsyntax/fold.rs32
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/token.rs2
10 files changed, 134 insertions, 58 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f8793f81b19..5979d339e17 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -64,7 +64,6 @@ use parse::token;
 use ptr::P;
 
 use std::fmt;
-use std::fmt::Show;
 use std::num::Int;
 use std::rc::Rc;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index eb845e463a0..7ca0591be50 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -12,7 +12,7 @@ use attr::AttrMetaMethods;
 use diagnostic::SpanHandler;
 use fold::Folder;
 use {ast, fold, attr};
-use codemap::Spanned;
+use codemap::{Spanned, respan};
 use ptr::P;
 
 use util::small_vector::SmallVector;
@@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
 // Support conditional compilation by transforming the AST, stripping out
 // any items that do not belong in the current configuration
 pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
+    let krate = process_cfg_attr(diagnostic, krate);
     let config = krate.config.clone();
     strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs))
 }
@@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
         attr::cfg_matches(diagnostic, cfg, &*mis[0])
     })
 }
+
+struct CfgAttrFolder<'a> {
+    diag: &'a SpanHandler,
+    config: ast::CrateConfig,
+}
+
+// Process `#[cfg_attr]`.
+fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
+    let mut fld = CfgAttrFolder {
+        diag: diagnostic,
+        config: krate.config.clone(),
+    };
+    fld.fold_crate(krate)
+}
+
+impl<'a> fold::Folder for CfgAttrFolder<'a> {
+    fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
+        if !attr.check_name("cfg_attr") {
+            return fold::noop_fold_attribute(attr, self);
+        }
+
+        let (cfg, mi) = match attr.meta_item_list() {
+            Some([ref cfg, ref mi]) => (cfg, mi),
+            _ => {
+                self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
+                return None;
+            }
+        };
+
+        if attr::cfg_matches(self.diag, &self.config[], &cfg) {
+            Some(respan(mi.span, ast::Attribute_ {
+                id: attr::mk_attr_id(),
+                style: attr.node.style,
+                value: mi.clone(),
+                is_sugared_doc: false,
+            }))
+        } else {
+            None
+        }
+    }
+
+    // Need the ability to run pre-expansion.
+    fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+        fold::noop_fold_mac(mac, self)
+    }
+}
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 454209bdba2..83a4d938bb5 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -518,10 +518,11 @@ fn highlight_lines(err: &mut EmitterWriter,
             let count = match lastc {
                 // Most terminals have a tab stop every eight columns by default
                 '\t' => 8 - col%8,
-                _ => lastc.width(false).unwrap_or(1),
+                _ => lastc.width(false).unwrap_or(0),
             };
             col += count;
-            s.extend(::std::iter::repeat('~').take(count - 1));
+            s.extend(::std::iter::repeat('~').take(count));
+
             let hi = cm.lookup_char_pos(sp.hi);
             if hi.col != lo.col {
                 for (pos, ch) in iter {
@@ -534,6 +535,12 @@ fn highlight_lines(err: &mut EmitterWriter,
                     s.extend(::std::iter::repeat('~').take(count));
                 }
             }
+
+            if s.len() > 1 {
+                // One extra squiggly is replaced by a "^"
+                s.pop();
+            }
+
             try!(print_maybe_styled(err,
                                     &format!("{}\n", s)[],
                                     term::attr::ForegroundColor(lvl.color())));
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 778b2cabea6..64ae6162ef4 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -528,8 +528,6 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
     syntax_expanders.insert(intern("cfg"),
                             builtin_normal_expander(
                                     ext::cfg::expand_cfg));
-    syntax_expanders.insert(intern("cfg_attr"),
-                            Modifier(box ext::cfg_attr::expand));
     syntax_expanders.insert(intern("trace_macros"),
                             builtin_normal_expander(
                                     ext::trace_macros::expand_trace_macros));
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 6d9a2fdb9f1..5bfd4a9f611 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -40,6 +40,18 @@ pub trait AstBuilder {
                 bindings: Vec<P<ast::TypeBinding>> )
         -> ast::Path;
 
+    fn qpath(&self, self_type: P<ast::Ty>,
+             trait_ref: P<ast::TraitRef>,
+             ident: ast::Ident )
+        -> P<ast::QPath>;
+    fn qpath_all(&self, self_type: P<ast::Ty>,
+                trait_ref: P<ast::TraitRef>,
+                ident: ast::Ident,
+                lifetimes: Vec<ast::Lifetime>,
+                types: Vec<P<ast::Ty>>,
+                bindings: Vec<P<ast::TypeBinding>> )
+        -> P<ast::QPath>;
+
     // types
     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
 
@@ -102,6 +114,7 @@ pub trait AstBuilder {
     // expressions
     fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>;
     fn expr_path(&self, path: ast::Path) -> P<ast::Expr>;
+    fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr>;
     fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
 
     fn expr_self(&self, span: Span) -> P<ast::Expr>;
@@ -330,6 +343,44 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         }
     }
 
+    /// Constructs a qualified path.
+    ///
+    /// Constructs a path like `<self_type as trait_ref>::ident`.
+    fn qpath(&self,
+             self_type: P<ast::Ty>,
+             trait_ref: P<ast::TraitRef>,
+             ident: ast::Ident)
+             -> P<ast::QPath> {
+        self.qpath_all(self_type, trait_ref, ident, Vec::new(), Vec::new(), Vec::new())
+    }
+
+    /// Constructs a qualified path.
+    ///
+    /// Constructs a path like `<self_type as trait_ref>::ident<a, T, A=Bar>`.
+    fn qpath_all(&self,
+                 self_type: P<ast::Ty>,
+                 trait_ref: P<ast::TraitRef>,
+                 ident: ast::Ident,
+                 lifetimes: Vec<ast::Lifetime>,
+                 types: Vec<P<ast::Ty>>,
+                 bindings: Vec<P<ast::TypeBinding>> )
+                 -> P<ast::QPath> {
+        let segment = ast::PathSegment {
+            identifier: ident,
+            parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
+                lifetimes: lifetimes,
+                types: OwnedSlice::from_vec(types),
+                bindings: OwnedSlice::from_vec(bindings),
+            })
+        };
+
+        P(ast::QPath {
+            self_type: self_type,
+            trait_ref: trait_ref,
+            item_path: segment,
+        })
+    }
+
     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
         ast::MutTy {
             ty: ty,
@@ -554,6 +605,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr(path.span, ast::ExprPath(path))
     }
 
+    /// Constructs a QPath expression.
+    fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr> {
+        self.expr(span, ast::ExprQPath(qpath))
+    }
+
     fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
         self.expr_path(self.path_ident(span, id))
     }
diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs
deleted file mode 100644
index 72eaa3e47be..00000000000
--- a/src/libsyntax/ext/cfg_attr.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 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.
-
-use ast;
-use attr;
-use codemap::Span;
-use ext::base::ExtCtxt;
-use ext::build::AstBuilder;
-use ptr::P;
-
-pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P<ast::Item>) -> P<ast::Item> {
-    let (cfg, attr) = match mi.node {
-        ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]),
-        _ => {
-            cx.span_err(sp, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
-            return it;
-        }
-    };
-
-    let mut out = (*it).clone();
-    if attr::cfg_matches(&cx.parse_sess.span_diagnostic, &cx.cfg, &**cfg) {
-        out.attrs.push(cx.attribute(attr.span, attr.clone()));
-    }
-
-    P(out)
-}
-
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index fd7593f2a3b..131bbc41005 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -844,7 +844,7 @@ fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
         arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
     let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
     ast::Arm {
-        attrs: arm.attrs.move_map(|x| fld.fold_attribute(x)),
+        attrs: fold::fold_attrs(arm.attrs, fld),
         pats: rewritten_pats,
         guard: rewritten_guard,
         body: rewritten_body,
@@ -1273,7 +1273,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as
             let (rewritten_fn_decl, rewritten_body)
                 = expand_and_rename_fn_decl_and_block(decl, body, fld);
             SmallVector::one(P(ast::Method {
-                    attrs: m.attrs.move_map(|a| fld.fold_attribute(a)),
+                    attrs: fold::fold_attrs(m.attrs, fld),
                     id: id,
                     span: fld.new_span(m.span),
                     node: ast::MethDecl(fld.fold_ident(ident),
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 8f1d15f6da8..1fb0642d24f 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -223,7 +223,7 @@ pub trait Folder : Sized {
         noop_fold_lifetime_def(l, self)
     }
 
-    fn fold_attribute(&mut self, at: Attribute) -> Attribute {
+    fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> {
         noop_fold_attribute(at, self)
     }
 
@@ -373,9 +373,13 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
     })
 }
 
+pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> {
+    attrs.into_iter().flat_map(|x| fld.fold_attribute(x).into_iter()).collect()
+}
+
 pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
     Arm {
-        attrs: attrs.move_map(|x| fld.fold_attribute(x)),
+        attrs: fold_attrs(attrs, fld),
         pats: pats.move_map(|x| fld.fold_pat(x)),
         guard: guard.map(|x| fld.fold_expr(x)),
         body: fld.fold_expr(body),
@@ -475,7 +479,7 @@ pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
         node: Variant_ {
             id: fld.new_id(id),
             name: name,
-            attrs: attrs.move_map(|x| fld.fold_attribute(x)),
+            attrs: fold_attrs(attrs, fld),
             kind: match kind {
                 TupleVariantKind(variant_args) => {
                     TupleVariantKind(variant_args.move_map(|x|
@@ -553,9 +557,9 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
     })
 }
 
-pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
+pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> {
     let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at;
-    Spanned {
+    Some(Spanned {
         node: Attribute_ {
             id: id,
             style: style,
@@ -563,7 +567,7 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
             is_sugared_doc: is_sugared_doc
         },
         span: fld.new_span(span)
-    }
+    })
 }
 
 pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_, fld: &mut T)
@@ -845,8 +849,8 @@ pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
                             where T: Folder {
     let new_id = folder.new_id(t.id);
     let new_span = folder.new_span(t.span);
-    let new_attrs = t.attrs.iter().map(|attr| {
-        folder.fold_attribute((*attr).clone())
+    let new_attrs = t.attrs.iter().flat_map(|attr| {
+        folder.fold_attribute((*attr).clone()).into_iter()
     }).collect();
     let new_ident = folder.fold_ident(t.ident);
     let new_type = folder.fold_ty(t.typ);
@@ -866,7 +870,7 @@ pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
 {
     let new_attrs = at.attrs
                       .iter()
-                      .map(|attr| folder.fold_attribute((*attr).clone()))
+                      .flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter())
                       .collect();
     let new_param = folder.fold_ty_param(at.ty_param);
     ast::AssociatedType {
@@ -909,7 +913,7 @@ pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructF
             id: fld.new_id(id),
             kind: kind,
             ty: fld.fold_ty(ty),
-            attrs: attrs.move_map(|a| fld.fold_attribute(a))
+            attrs: fold_attrs(attrs, fld),
         },
         span: fld.new_span(span)
     }
@@ -1072,7 +1076,7 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho
     TypeMethod {
         id: fld.new_id(id),
         ident: fld.fold_ident(ident),
-        attrs: attrs.move_map(|a| fld.fold_attribute(a)),
+        attrs: fold_attrs(attrs, fld),
         unsafety: unsafety,
         abi: abi,
         decl: fld.fold_fn_decl(decl),
@@ -1154,7 +1158,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
     Item {
         id: id,
         ident: folder.fold_ident(ident),
-        attrs: attrs.move_map(|e| folder.fold_attribute(e)),
+        attrs: fold_attrs(attrs, folder),
         node: node,
         vis: vis,
         span: folder.new_span(span)
@@ -1165,7 +1169,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
     ni.map(|ForeignItem {id, ident, attrs, node, span, vis}| ForeignItem {
         id: folder.new_id(id),
         ident: folder.fold_ident(ident),
-        attrs: attrs.move_map(|x| folder.fold_attribute(x)),
+        attrs: fold_attrs(attrs, folder),
         node: match node {
             ForeignItemFn(fdec, generics) => {
                 ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics))
@@ -1184,7 +1188,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
 pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> {
     SmallVector::one(m.map(|Method {id, attrs, node, span}| Method {
         id: folder.new_id(id),
-        attrs: attrs.move_map(|a| folder.fold_attribute(a)),
+        attrs: fold_attrs(attrs, folder),
         node: match node {
             MethDecl(ident,
                      generics,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 08e795ef80d..41850ada3e6 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -96,7 +96,6 @@ pub mod ext {
     pub mod base;
     pub mod build;
     pub mod cfg;
-    pub mod cfg_attr;
     pub mod concat;
     pub mod concat_idents;
     pub mod deriving;
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 45f4f044ea4..4c988164528 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -562,7 +562,7 @@ declare_special_idents_and_keywords! {
         (45,                         Where,      "where");
         'reserved:
         (46,                         Alignof,    "alignof");
-        (47,                         Be,         "be");
+        (47,                         Become,     "become");
         (48,                         Offsetof,   "offsetof");
         (49,                         Priv,       "priv");
         (50,                         Pure,       "pure");