From 6a3b385cbd6b9044b4447da96aad066e8b257ddf Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 1 Jul 2015 06:05:17 +0300 Subject: [PATCH] Feature-gate #[prelude_import]. --- src/librustc_driver/driver.rs | 2 +- src/libsyntax/feature_gate.rs | 6 ++- src/libsyntax/print/pprust.rs | 4 +- src/libsyntax/std_inject.rs | 48 +++++++++++++------ .../feature-gate-prelude_import.rs | 14 ++++++ src/test/pretty/issue-4264.pp | 2 +- 6 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 src/test/compile-fail/feature-gate-prelude_import.rs diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 80c4fc28703ac..ae6136a049ade 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -547,7 +547,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, sess.diagnostic())); 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| syntax::ext::expand::check_for_macros(&sess.parse_sess, krate)); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3d0cf9236c25c..ab8cf9ae6b64f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -155,6 +155,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ // Allows the definition of `const fn` functions. ("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) @@ -265,7 +268,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ and may be removed in the future")), // 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 // guarantee they'll have already been checked diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3adb73cfa5d6f..6693eed6aced5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -120,11 +120,13 @@ pub fn print_crate<'a>(cm: &'a CodeMap, // of the feature gate, so we fake them up here. 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)] let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), 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)); // #![no_std] diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 021ec4738ed94..3655058653188 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -10,16 +10,35 @@ use ast; use attr; -use codemap::DUMMY_SP; +use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use codemap; use fold::Folder; use fold; use parse::token::InternedString; use parse::token::special_idents; -use parse::token; +use parse::{token, ParseSess}; use ptr::P; 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) -> ast::Crate { if use_std(&krate) { @@ -29,9 +48,12 @@ pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option) } } -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) { - inject_prelude(krate) + let mut fold = PreludeInjector { + span: ignored_span(sess, DUMMY_SP) + }; + fold.fold_crate(krate) } else { krate } @@ -80,8 +102,9 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option) -> ast::Cr fold.fold_crate(krate) } -struct PreludeInjector; - +struct PreludeInjector { + span: Span +} impl fold::Folder for PreludeInjector { 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 { let prelude_path = ast::Path { - span: DUMMY_SP, + span: self.span, global: false, segments: vec![ ast::PathSegment { @@ -131,12 +154,12 @@ impl fold::Folder for PreludeInjector { ident: special_idents::invalid, node: ast::ItemUse(vp), attrs: vec![ast::Attribute { - span: DUMMY_SP, + span: self.span, node: ast::Attribute_ { id: attr::mk_attr_id(), style: ast::AttrOuter, value: P(ast::MetaItem { - span: DUMMY_SP, + span: self.span, node: ast::MetaWord(token::get_name( special_idents::prelude_import.name)), }), @@ -144,14 +167,9 @@ impl fold::Folder for PreludeInjector { }, }], vis: ast::Inherited, - span: DUMMY_SP, + span: self.span, })); fold::noop_fold_mod(mod_, self) } } - -fn inject_prelude(krate: ast::Crate) -> ast::Crate { - let mut fold = PreludeInjector; - fold.fold_crate(krate) -} diff --git a/src/test/compile-fail/feature-gate-prelude_import.rs b/src/test/compile-fail/feature-gate-prelude_import.rs new file mode 100644 index 0000000000000..8bc3df247ec12 --- /dev/null +++ b/src/test/compile-fail/feature-gate-prelude_import.rs @@ -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 or the MIT license +// , 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() {} diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index c2ed10ce6a187..5f7ce68348a3d 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -1,4 +1,4 @@ -#![feature(no_std)] +#![feature(no_std, prelude_import)] #![no_std] #[prelude_import] use std::prelude::v1::*;