Skip to content

Commit

Permalink
Feature-gate #[prelude_import].
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Jul 5, 2015
1 parent 281cfb9 commit 6a3b385
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/librustc_driver/driver.rs
Expand Up @@ -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));
Expand Down
6 changes: 5 additions & 1 deletion src/libsyntax/feature_gate.rs
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/libsyntax/print/pprust.rs
Expand Up @@ -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]
Expand Down
48 changes: 33 additions & 15 deletions src/libsyntax/std_inject.rs
Expand Up @@ -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<String>)
-> ast::Crate {
if use_std(&krate) {
Expand All @@ -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) {
inject_prelude(krate)
let mut fold = PreludeInjector {
span: ignored_span(sess, DUMMY_SP)
};
fold.fold_crate(krate)
} else {
krate
}
Expand Down Expand Up @@ -80,8 +102,9 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> 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 {
Expand All @@ -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 {
Expand All @@ -131,27 +154,22 @@ 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)),
}),
is_sugared_doc: false,
},
}],
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)
}
14 changes: 14 additions & 0 deletions 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 <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() {}
2 changes: 1 addition & 1 deletion 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::*;
Expand Down

0 comments on commit 6a3b385

Please sign in to comment.