about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-05-20 21:25:42 -0700
committerKevin Ballard <kevin@sb.org>2014-05-20 22:44:58 -0700
commit23ca66ecd2e10d0c6de2e3a657f58f6db35d0a9a (patch)
tree23080e165636b6b8845413e5eedf42b69bd1cba2 /src
parente546452727379f701f2104eb826141a29d4b39fd (diff)
downloadrust-23ca66ecd2e10d0c6de2e3a657f58f6db35d0a9a.tar.gz
rust-23ca66ecd2e10d0c6de2e3a657f58f6db35d0a9a.zip
Change std inject attributes to outer attributes
The #[phase(syntax,link)] attribute on `extern crate std` needs to be an
outer attribute so it can pretty-print properly.

Also add `#![no_std]` and `#[feature(phase)]` so compiling the
pretty-printed source will work.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/front/std_inject.rs52
-rw-r--r--src/librustc/front/test.rs2
-rw-r--r--src/librustc/metadata/encoder.rs2
-rw-r--r--src/librustc/middle/trans/base.rs2
-rw-r--r--src/libsyntax/attr.rs18
5 files changed, 48 insertions, 28 deletions
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index f6e6875f0e7..92bd81a40f2 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -22,6 +22,8 @@ use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::util::small_vector::SmallVector;
 
+use std::mem;
+
 pub static VERSION: &'static str = "0.11.0-pre";
 
 pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
@@ -70,13 +72,13 @@ pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
 }
 
 impl<'a> fold::Folder for StandardLibraryInjector<'a> {
-    fn fold_crate(&mut self, krate: ast::Crate) -> ast::Crate {
+    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         let mut vis = vec!(ast::ViewItem {
             node: ast::ViewItemExternCrate(token::str_to_ident("std"),
                                          with_version("std"),
                                          ast::DUMMY_NODE_ID),
             attrs: vec!(
-                attr::mk_attr(attr::mk_list_item(
+                attr::mk_attr_outer(attr::mk_list_item(
                         InternedString::new("phase"),
                         vec!(
                             attr::mk_word_item(InternedString::new("syntax")),
@@ -101,16 +103,20 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
         }
 
         // `extern crate` must be precede `use` items
-        vis.push_all_move(krate.module.view_items.clone());
-        let new_module = ast::Mod {
-            view_items: vis,
-            ..krate.module.clone()
-        };
+        mem::swap(&mut vis, &mut krate.module.view_items);
+        krate.module.view_items.push_all_move(vis);
 
-        ast::Crate {
-            module: new_module,
-            ..krate
-        }
+        // don't add #![no_std] here, that will block the prelude injection later.
+        // Add it during the prelude injection instead.
+
+        // Add #![feature(phase)] here, because we use #[phase] on extern crate std.
+        let feat_phase_attr = attr::mk_attr_inner(attr::mk_list_item(
+                                  InternedString::new("feature"),
+                                  vec![attr::mk_word_item(InternedString::new("phase"))],
+                              ));
+        krate.attrs.push(feat_phase_attr);
+
+        krate
     }
 }
 
@@ -127,29 +133,29 @@ struct PreludeInjector<'a> {
 
 
 impl<'a> fold::Folder for PreludeInjector<'a> {
-    fn fold_crate(&mut self, krate: ast::Crate) -> ast::Crate {
+    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
+        // Add #![no_std] here, so we don't re-inject when compiling pretty-printed source.
+        // This must happen here and not in StandardLibraryInjector because this
+        // fold happens second.
+
+        let no_std_attr = attr::mk_attr_inner(attr::mk_word_item(InternedString::new("no_std")));
+        krate.attrs.push(no_std_attr);
+
         if !no_prelude(krate.attrs.as_slice()) {
             // only add `use std::prelude::*;` if there wasn't a
             // `#![no_implicit_prelude]` at the crate level.
 
-            let mut attrs = krate.attrs.clone();
-
             // fold_mod() will insert glob path.
-            let globs_attr = attr::mk_attr(attr::mk_list_item(
+            let globs_attr = attr::mk_attr_inner(attr::mk_list_item(
                 InternedString::new("feature"),
                 vec!(
                     attr::mk_word_item(InternedString::new("globs")),
                 )));
-            attrs.push(globs_attr);
+            krate.attrs.push(globs_attr);
 
-            ast::Crate {
-                module: self.fold_mod(&krate.module),
-                attrs: attrs,
-                ..krate
-            }
-        } else {
-            krate
+            krate.module = self.fold_mod(&krate.module);
         }
+        krate
     }
 
     fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index 0d532d7cec1..0ebd392e582 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -341,7 +341,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::Item {
     // This attribute tells resolve to let us call unexported functions
     let resolve_unexported_str = InternedString::new("!resolve_unexported");
     let resolve_unexported_attr =
-        attr::mk_attr(attr::mk_word_item(resolve_unexported_str));
+        attr::mk_attr_inner(attr::mk_word_item(resolve_unexported_str));
 
     let item = ast::Item {
         ident: token::str_to_ident("__test"),
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index a7ba8300aed..e3ded05e17b 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1436,7 +1436,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext,
     fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
         assert!(!ecx.link_meta.crateid.name.is_empty());
 
-        attr::mk_attr(
+        attr::mk_attr_inner(
             attr::mk_name_value_item_str(
                 InternedString::new("crate_id"),
                 token::intern_and_get_ident(ecx.link_meta.crateid.to_str())))
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 92e3b95abad..0eabebc9226 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -231,7 +231,7 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
 
     let f = decl_rust_fn(ccx, false, inputs, output, name);
     csearch::get_item_attrs(&ccx.sess().cstore, did, |meta_items| {
-        set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x))
+        set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr_outer(x))
                                     .collect::<Vec<_>>().as_slice(), f)
     });
 
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index cf5163af717..5a57c2d6cc6 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -126,7 +126,11 @@ impl AttributeMethods for Attribute {
                 InternedString::new("doc"),
                 token::intern_and_get_ident(strip_doc_comment_decoration(
                         comment.get()).as_slice()));
-            mk_attr(meta)
+            if self.node.style == ast::AttrOuter {
+                mk_attr_outer(meta)
+            } else {
+                mk_attr_inner(meta)
+            }
         } else {
             *self
         }
@@ -154,7 +158,8 @@ pub fn mk_word_item(name: InternedString) -> @MetaItem {
     @dummy_spanned(MetaWord(name))
 }
 
-pub fn mk_attr(item: @MetaItem) -> Attribute {
+/// Returns an inner attribute with the given value.
+pub fn mk_attr_inner(item: @MetaItem) -> Attribute {
     dummy_spanned(Attribute_ {
         style: ast::AttrInner,
         value: item,
@@ -162,6 +167,15 @@ pub fn mk_attr(item: @MetaItem) -> Attribute {
     })
 }
 
+/// Returns an outer attribute with the given value.
+pub fn mk_attr_outer(item: @MetaItem) -> Attribute {
+    dummy_spanned(Attribute_ {
+        style: ast::AttrOuter,
+        value: item,
+        is_sugared_doc: false,
+    })
+}
+
 pub fn mk_sugared_doc_attr(text: InternedString, lo: BytePos, hi: BytePos)
                            -> Attribute {
     let style = doc_comment_style(text.get());