提交 da9dc050 编写于 作者: M Manish Goregaokar

Allow future-incompat lints to mention an epoch

上级 d9438c30
......@@ -99,7 +99,11 @@ pub struct BufferedEarlyLint {
/// guidelines.
pub struct FutureIncompatibleInfo {
pub id: LintId,
pub reference: &'static str // e.g., a URL for an issue/PR/RFC or error code
/// e.g., a URL for an issue/PR/RFC or error code
pub reference: &'static str,
/// If this is an epoch fixing lint, the epoch in which
/// this lint becomes obsolete
pub epoch: Option<config::Epoch>,
}
/// The target of the `by_name` map, which accounts for renaming/deprecation.
......@@ -194,11 +198,24 @@ fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
pub fn register_future_incompatible(&mut self,
sess: Option<&Session>,
lints: Vec<FutureIncompatibleInfo>) {
let ids = lints.iter().map(|f| f.id).collect();
self.register_group(sess, false, "future_incompatible", ids);
for info in lints {
self.future_incompatible.insert(info.id, info);
for epoch in config::ALL_EPOCHS {
let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id)
.collect::<Vec<_>>();
if !lints.is_empty() {
self.register_group(sess, false, epoch.lint_name(), lints)
}
}
let mut future_incompatible = vec![];
for lint in lints {
future_incompatible.push(lint.id);
self.future_incompatible.insert(lint.id, lint);
}
self.register_group(sess, false, "future_incompatible", future_incompatible);
}
pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> {
......
......@@ -89,14 +89,15 @@ fn process_command_line(&mut self, sess: &Session) {
fn get_lint_level(&self,
lint: &'static Lint,
idx: u32,
aux: Option<&FxHashMap<LintId, (Level, LintSource)>>)
aux: Option<&FxHashMap<LintId, (Level, LintSource)>>,
sess: &Session)
-> (Level, LintSource)
{
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
// If `level` is none then we actually assume the default level for this
// lint.
let mut level = level.unwrap_or(lint.default_level);
let mut level = level.unwrap_or(lint.default_level(sess));
// If we're about to issue a warning, check at the last minute for any
// directives against the warnings "lint". If, for example, there's an
......@@ -235,7 +236,8 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
let lint = builtin::RENAMED_AND_REMOVED_LINTS;
let (level, src) = self.sets.get_lint_level(lint,
self.cur,
Some(&specs));
Some(&specs),
&sess);
lint::struct_lint_level(self.sess,
lint,
level,
......@@ -248,7 +250,8 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
let lint = builtin::UNKNOWN_LINTS;
let (level, src) = self.sets.get_lint_level(lint,
self.cur,
Some(&specs));
Some(&specs),
self.sess);
let msg = format!("unknown lint: `{}`", name);
let mut db = lint::struct_lint_level(self.sess,
lint,
......@@ -342,7 +345,7 @@ pub fn struct_lint(&self,
msg: &str)
-> DiagnosticBuilder<'a>
{
let (level, src) = self.sets.get_lint_level(lint, self.cur, None);
let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess);
lint::struct_lint_level(self.sess, lint, level, src, span, msg)
}
......@@ -377,11 +380,11 @@ impl LintLevelMap {
/// If the `id` was not previously registered, returns `None`. If `None` is
/// returned then the parent of `id` should be acquired and this function
/// should be called again.
pub fn level_and_source(&self, lint: &'static Lint, id: HirId)
pub fn level_and_source(&self, lint: &'static Lint, id: HirId, session: &Session)
-> Option<(Level, LintSource)>
{
self.id_to_set.get(&id).map(|idx| {
self.sets.get_lint_level(lint, *idx, None)
self.sets.get_lint_level(lint, *idx, None, session)
})
}
......
......@@ -37,7 +37,7 @@
use hir::def_id::{CrateNum, LOCAL_CRATE};
use hir::intravisit::{self, FnKind};
use hir;
use session::{Session, DiagnosticMessageId};
use session::{config, Session, DiagnosticMessageId};
use std::hash;
use syntax::ast;
use syntax::codemap::MultiSpan;
......@@ -74,6 +74,9 @@ pub struct Lint {
///
/// e.g. "imports that are never used"
pub desc: &'static str,
/// Deny lint after this epoch
pub epoch_deny: Option<config::Epoch>,
}
impl Lint {
......@@ -81,18 +84,36 @@ impl Lint {
pub fn name_lower(&self) -> String {
self.name.to_ascii_lowercase()
}
pub fn default_level(&self, session: &Session) -> Level {
if let Some(epoch_deny) = self.epoch_deny {
if session.epoch() >= epoch_deny {
return Level::Deny
}
}
self.default_level
}
}
/// Declare a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint {
($vis: vis $NAME: ident, $Level: ident, $desc: expr, $epoch: expr) => (
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: stringify!($NAME),
default_level: $crate::lint::$Level,
desc: $desc,
epoch_deny: Some($epoch)
};
);
($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: stringify!($NAME),
default_level: $crate::lint::$Level,
desc: $desc
desc: $desc,
epoch_deny: None,
};
)
);
}
/// Declare a static `LintArray` and return it as an expression.
......@@ -304,7 +325,7 @@ pub fn to_string(&self) -> String {
/// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Level {
Allow, Warn, Deny, Forbid
Allow, Warn, Deny, Forbid,
}
impl_stable_hash_for!(enum self::Level {
......
......@@ -113,7 +113,7 @@ pub enum OutputType {
}
/// The epoch of the compiler (RFC 2052)
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)]
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum Epoch {
// epochs must be kept in order, newest to oldest
......@@ -148,6 +148,15 @@ fn to_string(&self) -> String {
}
}
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, ()> {
......
......@@ -869,6 +869,10 @@ pub fn teach(&self, code: &DiagnosticId) -> bool {
pub fn rust_2018(&self) -> bool {
self.opts.debugging_opts.epoch >= Epoch::Epoch2018
}
pub fn epoch(&self) -> Epoch {
self.opts.debugging_opts.epoch
}
}
pub fn build_session(sopts: config::Options,
......
......@@ -2234,7 +2234,7 @@ pub fn lint_level_at_node(self, lint: &'static Lint, mut id: NodeId)
let sets = self.lint_levels(LOCAL_CRATE);
loop {
let hir_id = self.hir.definitions().node_to_hir_id(id);
if let Some(pair) = sets.level_and_source(lint, hir_id) {
if let Some(pair) = sets.level_and_source(lint, hir_id, self.sess) {
return pair
}
let next = self.hir.get_parent_node(id);
......
......@@ -735,7 +735,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
super::describe_lints(&sess.lint_store.borrow(), true);
super::describe_lints(&sess, &sess.lint_store.borrow(), true);
return Err(CompileIncomplete::Stopped);
}
......
......@@ -774,15 +774,15 @@ fn no_input(&mut self,
-> Option<(Input, Option<PathBuf>)> {
match matches.free.len() {
0 => {
let mut sess = build_session(sopts.clone(),
None,
descriptions.clone());
if sopts.describe_lints {
let mut ls = lint::LintStore::new();
rustc_lint::register_builtins(&mut ls, None);
describe_lints(&ls, false);
rustc_lint::register_builtins(&mut ls, Some(&sess));
describe_lints(&sess, &ls, false);
return None;
}
let mut sess = build_session(sopts.clone(),
None,
descriptions.clone());
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess, cfg.clone());
let trans = get_trans(&sess);
......@@ -1121,7 +1121,7 @@ fn usage(verbose: bool, include_unstable_options: bool) {
verbose_help);
}
fn describe_lints(lint_store: &lint::LintStore, loaded_plugins: bool) {
fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins: bool) {
println!("
Available lint options:
-W <foo> Warn about <foo>
......@@ -1133,10 +1133,10 @@ fn describe_lints(lint_store: &lint::LintStore, loaded_plugins: bool) {
");
fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
lints.sort_by(|x: &&Lint, y: &&Lint| {
match x.default_level.cmp(&y.default_level) {
match x.default_level(sess).cmp(&y.default_level(sess)) {
// The sort doesn't case-fold but it's doubtful we care.
Equal => x.name.cmp(y.name),
r => r,
......@@ -1159,8 +1159,8 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
.iter()
.cloned()
.partition(|&(_, p)| p);
let plugin = sort_lints(plugin);
let builtin = sort_lints(builtin);
let plugin = sort_lints(sess, plugin);
let builtin = sort_lints(sess, builtin);
let (plugin_groups, builtin_groups): (Vec<_>, _) = lint_store.get_lint_groups()
.iter()
......
......@@ -185,74 +185,92 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
FutureIncompatibleInfo {
id: LintId::of(PRIVATE_IN_PUBLIC),
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE),
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(SAFE_EXTERN_STATICS),
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(LEGACY_IMPORTS),
reference: "issue #38260 <https://github.com/rust-lang/rust/issues/38260>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT),
reference: "issue #39216 <https://github.com/rust-lang/rust/issues/39216>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(ANONYMOUS_PARAMETERS),
reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS),
reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(SAFE_PACKED_BORROWS),
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(COERCE_NEVER),
reference: "issue #46325 <https://github.com/rust-lang/rust/issues/46325>",
epoch: None,
},
FutureIncompatibleInfo {
id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
epoch: None,
},
]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册