Feature-gate #[prelude_import].

This commit is contained in:
Eduard Burtescu 2015-07-01 06:05:17 +03:00
parent 281cfb93ab
commit 6a3b385cbd
6 changed files with 57 additions and 19 deletions

View file

@ -547,7 +547,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
sess.diagnostic())); sess.diagnostic()));
krate = time(time_passes, "prelude injection", krate, |krate| krate = time(time_passes, "prelude injection", krate, |krate|
syntax::std_inject::maybe_inject_prelude(krate)); syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate));
time(time_passes, "checking that all macro invocations are gone", &krate, |krate| time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
syntax::ext::expand::check_for_macros(&sess.parse_sess, krate)); syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));

View file

@ -155,6 +155,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
// Allows the definition of `const fn` functions. // Allows the definition of `const fn` functions.
("const_fn", "1.2.0", Active), ("const_fn", "1.2.0", Active),
// Allows using #[prelude_import] on glob `use` items.
("prelude_import", "1.2.0", Active),
]; ];
// (changing above list without updating src/doc/reference.md makes @cmr sad) // (changing above list without updating src/doc/reference.md makes @cmr sad)
@ -265,7 +268,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
and may be removed in the future")), and may be removed in the future")),
// used in resolve // used in resolve
("prelude_import", Whitelisted), ("prelude_import", Gated("prelude_import",
"`#[prelude_import]` is for use by rustc only")),
// FIXME: #14407 these are only looked at on-demand so we can't // FIXME: #14407 these are only looked at on-demand so we can't
// guarantee they'll have already been checked // guarantee they'll have already been checked

View file

@ -120,11 +120,13 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
// of the feature gate, so we fake them up here. // of the feature gate, so we fake them up here.
let no_std_meta = attr::mk_word_item(InternedString::new("no_std")); let no_std_meta = attr::mk_word_item(InternedString::new("no_std"));
let prelude_import_meta = attr::mk_word_item(InternedString::new("prelude_import"));
// #![feature(no_std)] // #![feature(no_std)]
let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(),
attr::mk_list_item(InternedString::new("feature"), attr::mk_list_item(InternedString::new("feature"),
vec![no_std_meta.clone()])); vec![no_std_meta.clone(),
prelude_import_meta]));
try!(s.print_attribute(&fake_attr)); try!(s.print_attribute(&fake_attr));
// #![no_std] // #![no_std]

View file

@ -10,16 +10,35 @@
use ast; use ast;
use attr; use attr;
use codemap::DUMMY_SP; use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
use codemap; use codemap;
use fold::Folder; use fold::Folder;
use fold; use fold;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token::special_idents; use parse::token::special_idents;
use parse::token; use parse::{token, ParseSess};
use ptr::P; use ptr::P;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
/// Craft a span that will be ignored by the stability lint's
/// call to codemap's is_internal check.
/// The expanded code uses the unstable `#[prelude_import]` attribute.
fn ignored_span(sess: &ParseSess, sp: Span) -> Span {
let info = ExpnInfo {
call_site: DUMMY_SP,
callee: NameAndSpan {
name: "std_inject".to_string(),
format: MacroAttribute,
span: None,
allow_internal_unstable: true,
}
};
let expn_id = sess.codemap().record_expansion(info);
let mut sp = sp;
sp.expn_id = expn_id;
return sp;
}
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
-> ast::Crate { -> ast::Crate {
if use_std(&krate) { if use_std(&krate) {
@ -29,9 +48,12 @@ pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
} }
} }
pub fn maybe_inject_prelude(krate: ast::Crate) -> ast::Crate { pub fn maybe_inject_prelude(sess: &ParseSess, krate: ast::Crate) -> ast::Crate {
if use_std(&krate) { if use_std(&krate) {
inject_prelude(krate) let mut fold = PreludeInjector {
span: ignored_span(sess, DUMMY_SP)
};
fold.fold_crate(krate)
} else { } else {
krate krate
} }
@ -80,8 +102,9 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Cr
fold.fold_crate(krate) fold.fold_crate(krate)
} }
struct PreludeInjector; struct PreludeInjector {
span: Span
}
impl fold::Folder for PreludeInjector { impl fold::Folder for PreludeInjector {
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
@ -107,7 +130,7 @@ impl fold::Folder for PreludeInjector {
fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod { fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
let prelude_path = ast::Path { let prelude_path = ast::Path {
span: DUMMY_SP, span: self.span,
global: false, global: false,
segments: vec![ segments: vec![
ast::PathSegment { ast::PathSegment {
@ -131,12 +154,12 @@ impl fold::Folder for PreludeInjector {
ident: special_idents::invalid, ident: special_idents::invalid,
node: ast::ItemUse(vp), node: ast::ItemUse(vp),
attrs: vec![ast::Attribute { attrs: vec![ast::Attribute {
span: DUMMY_SP, span: self.span,
node: ast::Attribute_ { node: ast::Attribute_ {
id: attr::mk_attr_id(), id: attr::mk_attr_id(),
style: ast::AttrOuter, style: ast::AttrOuter,
value: P(ast::MetaItem { value: P(ast::MetaItem {
span: DUMMY_SP, span: self.span,
node: ast::MetaWord(token::get_name( node: ast::MetaWord(token::get_name(
special_idents::prelude_import.name)), special_idents::prelude_import.name)),
}), }),
@ -144,14 +167,9 @@ impl fold::Folder for PreludeInjector {
}, },
}], }],
vis: ast::Inherited, vis: ast::Inherited,
span: DUMMY_SP, span: self.span,
})); }));
fold::noop_fold_mod(mod_, self) fold::noop_fold_mod(mod_, self)
} }
} }
fn inject_prelude(krate: ast::Crate) -> ast::Crate {
let mut fold = PreludeInjector;
fold.fold_crate(krate)
}

View file

@ -0,0 +1,14 @@
// Copyright 2015 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.
#[prelude_import] //~ ERROR `#[prelude_import]` is for use by rustc only
use std::prelude::v1::*;
fn main() {}

View file

@ -1,4 +1,4 @@
#![feature(no_std)] #![feature(no_std, prelude_import)]
#![no_std] #![no_std]
#[prelude_import] #[prelude_import]
use std::prelude::v1::*; use std::prelude::v1::*;