Skip to content

Commit

Permalink
Rollup merge of rust-lang#48801 - Manishearth:epoch-features, r=nikom…
Browse files Browse the repository at this point in the history
…atsakis

Add functionality for gating feature flags on epochs ; rejigger epoch lints

fixes rust-lang#48794

r? @nikomatsakis
  • Loading branch information
Manishearth authored Mar 9, 2018
2 parents b0bc601 + a08cfc4 commit 68e7282
Show file tree
Hide file tree
Showing 14 changed files with 328 additions and 263 deletions.
6 changes: 2 additions & 4 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use errors::DiagnosticBuilder;
use lint::{LintPass, LateLintPass, LintArray};
use session::Session;
use session::config::Epoch;
use syntax::codemap::Span;

declare_lint! {
Expand Down Expand Up @@ -264,9 +263,8 @@ declare_lint! {

declare_lint! {
pub BARE_TRAIT_OBJECT,
Warn,
"suggest using `dyn Trait` for trait objects",
Epoch::Epoch2018
Allow,
"suggest using `dyn Trait` for trait objects"
}

declare_lint! {
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use util::nodemap::FxHashMap;
use std::default::Default as StdDefault;
use std::cell::{Ref, RefCell};
use syntax::ast;
use syntax::epoch;
use syntax_pos::{MultiSpan, Span};
use errors::DiagnosticBuilder;
use hir;
Expand Down Expand Up @@ -105,7 +106,7 @@ pub struct FutureIncompatibleInfo {
pub reference: &'static str,
/// If this is an epoch fixing lint, the epoch in which
/// this lint becomes obsolete
pub epoch: Option<config::Epoch>,
pub epoch: Option<epoch::Epoch>,
}

/// The target of the `by_name` map, which accounts for renaming/deprecation.
Expand Down Expand Up @@ -201,7 +202,7 @@ impl LintStore {
sess: Option<&Session>,
lints: Vec<FutureIncompatibleInfo>) {

for epoch in config::ALL_EPOCHS {
for epoch in epoch::ALL_EPOCHS {
let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id)
.collect::<Vec<_>>();
if !lints.is_empty() {
Expand Down
12 changes: 9 additions & 3 deletions src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ use hir::def_id::{CrateNum, LOCAL_CRATE};
use hir::intravisit::{self, FnKind};
use hir;
use lint::builtin::BuiltinLintDiagnostics;
use session::{config, Session, DiagnosticMessageId};
use session::{Session, DiagnosticMessageId};
use std::hash;
use syntax::ast;
use syntax::codemap::MultiSpan;
use syntax::epoch::Epoch;
use syntax::symbol::Symbol;
use syntax::visit as ast_visit;
use syntax_pos::Span;
Expand Down Expand Up @@ -77,7 +78,7 @@ pub struct Lint {
pub desc: &'static str,

/// Deny lint after this epoch
pub epoch_deny: Option<config::Epoch>,
pub epoch_deny: Option<Epoch>,
}

impl Lint {
Expand Down Expand Up @@ -492,9 +493,14 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
// Check for future incompatibility lints and issue a stronger warning.
let lints = sess.lint_store.borrow();
if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
let future = if let Some(epoch) = future_incompatible.epoch {
format!("the {} epoch", epoch)
} else {
"a future release".to_owned()
};
let explanation = format!("this was previously accepted by the compiler \
but is being phased out; \
it will become a hard error in a future release!");
it will become a hard error in {}!", future);
let citation = format!("for more information, see {}",
future_incompatible.reference);
err.warn(&explanation);
Expand Down
57 changes: 3 additions & 54 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use middle::cstore;

use syntax::ast::{self, IntTy, UintTy};
use syntax::codemap::{FileName, FilePathMapping};
use syntax::epoch::Epoch;
use syntax::parse::token;
use syntax::parse;
use syntax::symbol::Symbol;
Expand Down Expand Up @@ -111,59 +112,6 @@ pub enum OutputType {
DepInfo,
}

/// The epoch of the compiler (RFC 2052)
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum Epoch {
// epochs must be kept in order, newest to oldest
/// The 2015 epoch
Epoch2015,
/// The 2018 epoch
Epoch2018,
// when adding new epochs, be sure to update:
//
// - the list in the `parse_epoch` static
// - the match in the `parse_epoch` function
// - add a `rust_####()` function to the session
// - update the enum in Cargo's sources as well
//
// When -Zepoch becomes --epoch, there will
// also be a check for the epoch being nightly-only
// somewhere. That will need to be updated
// whenever we're stabilizing/introducing a new epoch
// as well as changing the default Cargo template.
}

pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018];

impl ToString for Epoch {
fn to_string(&self) -> String {
match *self {
Epoch::Epoch2015 => "2015".into(),
Epoch::Epoch2018 => "2018".into(),
}
}
}

impl Epoch {
pub fn lint_name(&self) -> &'static str {
match *self {
Epoch::Epoch2015 => "epoch_2015",
Epoch::Epoch2018 => "epoch_2018",
}
}
}

impl str::FromStr for Epoch {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s {
"2015" => Ok(Epoch::Epoch2015),
"2018" => Ok(Epoch::Epoch2018),
_ => Err(()),
}
}
}

impl_stable_hash_for!(enum self::OutputType {
Bitcode,
Expand Down Expand Up @@ -829,9 +777,10 @@ macro_rules! options {

#[allow(dead_code)]
mod $mod_set {
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto, Epoch};
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto};
use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
use std::path::PathBuf;
use syntax::epoch::Epoch;

$(
pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use lint::builtin::BuiltinLintDiagnostics;
use middle::allocator::AllocatorKind;
use middle::dependency_format;
use session::search_paths::PathKind;
use session::config::{DebugInfoLevel, Epoch, OutputType};
use session::config::{DebugInfoLevel, OutputType};
use ty::tls;
use util::nodemap::{FxHashMap, FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};
Expand All @@ -30,6 +30,7 @@ use rustc_data_structures::sync::Lrc;
use syntax::ast::NodeId;
use errors::{self, DiagnosticBuilder, DiagnosticId};
use errors::emitter::{Emitter, EmitterWriter};
use syntax::epoch::Epoch;
use syntax::json::JsonEmitter;
use syntax::feature_gate;
use syntax::symbol::Symbol;
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
{
let time_passes = sess.time_passes();

let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test);
let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess,
sess.opts.test,
sess.opts.debugging_opts.epoch);
// these need to be set "early" so that expansion sees `quote` if enabled.
sess.init_features(features);

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
pub struct UnreachablePub;

declare_lint! {
UNREACHABLE_PUB,
pub UNREACHABLE_PUB,
Allow,
"`pub` items not reachable from crate root"
}
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ extern crate rustc_mir;
extern crate syntax_pos;

use rustc::lint;
use rustc::lint::builtin::BARE_TRAIT_OBJECT;
use rustc::session;
use rustc::util;

use session::Session;
use syntax::epoch::Epoch;
use lint::LintId;
use lint::FutureIncompatibleInfo;

Expand Down Expand Up @@ -176,6 +178,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
UNUSED_FEATURES,
UNUSED_PARENS);

add_lint_group!(sess,
"rust_2018_idioms",
BARE_TRAIT_OBJECT,
UNREACHABLE_PUB);

// Guidelines for creating a future incompatibility lint:
//
// - Create a lint defaulting to warn as normal, with ideally the same error
Expand Down Expand Up @@ -274,13 +281,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
FutureIncompatibleInfo {
id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(lint::builtin::BARE_TRAIT_OBJECT),
reference: "issue #48457 <https://github.com/rust-lang/rust/issues/48457>",
epoch: Some(session::config::Epoch::Epoch2018),
}
epoch: Some(Epoch::Epoch2018),
}
]);

// Register renamed and removed lints
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features
use {fold, attr};
use ast;
use codemap::Spanned;
use epoch::Epoch;
use parse::{token, ParseSess};

use ptr::P;
Expand All @@ -26,7 +27,7 @@ pub struct StripUnconfigured<'a> {
}

// `cfg_attr`-process the crate's attributes and compute the crate's features.
pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoch: Epoch)
-> (ast::Crate, Features) {
let features;
{
Expand All @@ -46,7 +47,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
return (krate, Features::new());
}

features = get_features(&sess.span_diagnostic, &krate.attrs);
features = get_features(&sess.span_diagnostic, &krate.attrs, epoch);

// Avoid reconfiguring malformed `cfg_attr`s
if err_count == sess.span_diagnostic.err_count() {
Expand Down
69 changes: 69 additions & 0 deletions src/libsyntax/epoch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2018 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 std::fmt;
use std::str::FromStr;

/// The epoch of the compiler (RFC 2052)
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum Epoch {
// epochs must be kept in order, newest to oldest

/// The 2015 epoch
Epoch2015,
/// The 2018 epoch
Epoch2018,

// when adding new epochs, be sure to update:
//
// - the list in the `parse_epoch` static in librustc::session::config
// - add a `rust_####()` function to the session
// - update the enum in Cargo's sources as well
//
// When -Zepoch becomes --epoch, there will
// also be a check for the epoch being nightly-only
// somewhere. That will need to be updated
// whenever we're stabilizing/introducing a new epoch
// as well as changing the default Cargo template.
}

// must be in order from oldest to newest
pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018];

impl fmt::Display for Epoch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match *self {
Epoch::Epoch2015 => "2015",
Epoch::Epoch2018 => "2018",
};
write!(f, "{}", s)
}
}

impl Epoch {
pub fn lint_name(&self) -> &'static str {
match *self {
Epoch::Epoch2015 => "epoch_2015",
Epoch::Epoch2018 => "epoch_2018",
}
}
}

impl FromStr for Epoch {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s {
"2015" => Ok(Epoch::Epoch2015),
"2018" => Ok(Epoch::Epoch2018),
_ => Err(())
}
}
}
Loading

0 comments on commit 68e7282

Please sign in to comment.