1
Fork 0

prepare moving HardwiredLints to rustc_session

This commit is contained in:
Mazdak Farrokhzad 2020-01-05 10:07:26 +01:00
parent 7dbccf5b55
commit 45f27643db
15 changed files with 187 additions and 199 deletions

View file

@ -4,14 +4,9 @@
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.
use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass};
use crate::middle::stability;
use crate::session::Session;
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
use rustc_session::declare_lint;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::lint::FutureIncompatibleInfo;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::source_map::Span;
use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
declare_lint! {
@ -512,125 +507,3 @@ declare_lint_pass! {
SOFT_UNSTABLE,
]
}
impl LateLintPass<'_, '_> for HardwiredLints {}
pub fn add_elided_lifetime_in_path_suggestion(
sess: &Session,
db: &mut DiagnosticBuilder<'_>,
n: usize,
path_span: Span,
incl_angl_brckt: bool,
insertion_span: Span,
anon_lts: String,
) {
let (replace_span, suggestion) = if incl_angl_brckt {
(insertion_span, anon_lts)
} else {
// When possible, prefer a suggestion that replaces the whole
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
// at a point (which makes for an ugly/confusing label)
if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
// But our spans can get out of whack due to macros; if the place we think
// we want to insert `'_` isn't even within the path expression's span, we
// should bail out of making any suggestion rather than panicking on a
// subtract-with-overflow or string-slice-out-out-bounds (!)
// FIXME: can we do better?
if insertion_span.lo().0 < path_span.lo().0 {
return;
}
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
if insertion_index > snippet.len() {
return;
}
let (before, after) = snippet.split_at(insertion_index);
(path_span, format!("{}{}{}", before, anon_lts, after))
} else {
(insertion_span, anon_lts)
}
};
db.span_suggestion(
replace_span,
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
suggestion,
Applicability::MachineApplicable,
);
}
pub fn run_builtin_lint_diagnostics(
this: BuiltinLintDiagnostics,
sess: &Session,
db: &mut DiagnosticBuilder<'_>,
) {
match this {
BuiltinLintDiagnostics::Normal => (),
BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
Ok(s) if is_global => (format!("dyn ({})", s), Applicability::MachineApplicable),
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
};
db.span_suggestion(span, "use `dyn`", sugg, app);
}
BuiltinLintDiagnostics::AbsPathWithModule(span) => {
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
Ok(ref s) => {
// FIXME(Manishearth) ideally the emitting code
// can tell us whether or not this is global
let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
(format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
}
Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
};
db.span_suggestion(span, "use `crate`", sugg, app);
}
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
db.span_label(
span,
"names from parent modules are not accessible without an explicit import",
);
}
BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
db.span_note(span_def, "the macro is defined here");
}
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
n,
path_span,
incl_angl_brckt,
insertion_span,
anon_lts,
) => {
add_elided_lifetime_in_path_suggestion(
sess,
db,
n,
path_span,
incl_angl_brckt,
insertion_span,
anon_lts,
);
}
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
}
BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
if !replaces.is_empty() {
db.tool_only_multipart_suggestion(
&message,
replaces,
Applicability::MachineApplicable,
);
}
}
BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
for (span, is_imported) in spans {
let introduced = if is_imported { "imported" } else { "defined" };
db.span_label(span, format!("the item `{}` is already {} here", ident, introduced));
}
}
BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
stability::deprecation_suggestion(db, suggestion, span)
}
}
}

View file

@ -20,13 +20,14 @@ use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
use crate::lint::{EarlyLintPassObject, LateLintPassObject};
use crate::middle::privacy::AccessLevels;
use crate::middle::stability;
use crate::session::Session;
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync;
use rustc_error_codes::*;
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_session::lint::BuiltinLintDiagnostics;
@ -466,6 +467,48 @@ impl LintPassObject for EarlyLintPassObject {}
impl LintPassObject for LateLintPassObject {}
pub fn add_elided_lifetime_in_path_suggestion(
sess: &Session,
db: &mut DiagnosticBuilder<'_>,
n: usize,
path_span: Span,
incl_angl_brckt: bool,
insertion_span: Span,
anon_lts: String,
) {
let (replace_span, suggestion) = if incl_angl_brckt {
(insertion_span, anon_lts)
} else {
// When possible, prefer a suggestion that replaces the whole
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
// at a point (which makes for an ugly/confusing label)
if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
// But our spans can get out of whack due to macros; if the place we think
// we want to insert `'_` isn't even within the path expression's span, we
// should bail out of making any suggestion rather than panicking on a
// subtract-with-overflow or string-slice-out-out-bounds (!)
// FIXME: can we do better?
if insertion_span.lo().0 < path_span.lo().0 {
return;
}
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
if insertion_index > snippet.len() {
return;
}
let (before, after) = snippet.split_at(insertion_index);
(path_span, format!("{}{}{}", before, anon_lts, after))
} else {
(insertion_span, anon_lts)
}
};
db.span_suggestion(
replace_span,
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
suggestion,
Applicability::MachineApplicable,
);
}
pub trait LintContext: Sized {
type PassObject: LintPassObject;
@ -484,7 +527,85 @@ pub trait LintContext: Sized {
diagnostic: BuiltinLintDiagnostics,
) {
let mut db = self.lookup(lint, span, msg);
super::builtin::run_builtin_lint_diagnostics(diagnostic, self.sess(), &mut db);
let sess = self.sess();
match diagnostic {
BuiltinLintDiagnostics::Normal => (),
BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
Ok(s) if is_global => {
(format!("dyn ({})", s), Applicability::MachineApplicable)
}
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
};
db.span_suggestion(span, "use `dyn`", sugg, app);
}
BuiltinLintDiagnostics::AbsPathWithModule(span) => {
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
Ok(ref s) => {
// FIXME(Manishearth) ideally the emitting code
// can tell us whether or not this is global
let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
(format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
}
Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
};
db.span_suggestion(span, "use `crate`", sugg, app);
}
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
db.span_label(
span,
"names from parent modules are not accessible without an explicit import",
);
}
BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
db.span_note(span_def, "the macro is defined here");
}
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
n,
path_span,
incl_angl_brckt,
insertion_span,
anon_lts,
) => {
add_elided_lifetime_in_path_suggestion(
sess,
&mut db,
n,
path_span,
incl_angl_brckt,
insertion_span,
anon_lts,
);
}
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
}
BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
if !replaces.is_empty() {
db.tool_only_multipart_suggestion(
&message,
replaces,
Applicability::MachineApplicable,
);
}
}
BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
for (span, is_imported) in spans {
let introduced = if is_imported { "imported" } else { "defined" };
db.span_label(
span,
format!("the item `{}` is already {} here", ident, introduced),
);
}
}
BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
stability::deprecation_suggestion(&mut db, suggestion, span)
}
}
db.emit();
}

View file

@ -1,13 +1,11 @@
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
//! Clippy.
use crate::lint::{
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
};
use crate::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
use rustc_session::declare_tool_lint;
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::{sym, Symbol};
use syntax::ast::{Ident, Item, ItemKind};

View file

@ -21,6 +21,7 @@
pub use self::Level::*;
pub use self::LintSource::*;
use crate::lint::builtin::HardwiredLints;
use crate::ty::TyCtxt;
use rustc_data_structures::sync;
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
@ -33,48 +34,12 @@ use rustc_span::Span;
use syntax::ast;
pub use crate::lint::context::{
CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore,
add_elided_lifetime_in_path_suggestion, CheckLintNameResult, EarlyContext, LateContext,
LintContext, LintStore,
};
pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId};
/// Declares a static `LintArray` and return it as an expression.
#[macro_export]
macro_rules! lint_array {
($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
($( $lint:expr ),*) => {{
vec![$($lint),*]
}}
}
pub type LintArray = Vec<&'static Lint>;
pub trait LintPass {
fn name(&self) -> &'static str;
}
/// Implements `LintPass for $name` with the given list of `Lint` statics.
#[macro_export]
macro_rules! impl_lint_pass {
($name:ident => [$($lint:expr),* $(,)?]) => {
impl LintPass for $name {
fn name(&self) -> &'static str { stringify!($name) }
}
impl $name {
pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) }
}
};
}
/// Declares a type named `$name` which implements `LintPass`.
/// To the right of `=>` a comma separated list of `Lint` statics is given.
#[macro_export]
macro_rules! declare_lint_pass {
($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
$(#[$m])* #[derive(Copy, Clone)] pub struct $name;
$crate::impl_lint_pass!($name => [$($lint),*]);
};
}
pub use rustc_session::lint::{LintArray, LintPass};
#[macro_export]
macro_rules! late_lint_methods {
@ -166,6 +131,8 @@ macro_rules! declare_late_lint_pass {
late_lint_methods!(declare_late_lint_pass, [], ['tcx]);
impl LateLintPass<'_, '_> for HardwiredLints {}
#[macro_export]
macro_rules! expand_combined_late_lint_pass_method {
([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({

View file

@ -305,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
E0726,
"implicit elided lifetime not allowed here"
);
rustc::lint::builtin::add_elided_lifetime_in_path_suggestion(
rustc::lint::add_elided_lifetime_in_path_suggestion(
&self.sess,
&mut err,
expected_lifetimes,

View file

@ -1,5 +1,4 @@
use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
use rustc::lint::FutureIncompatibleInfo;
use rustc::lint::{FutureIncompatibleInfo, LateContext, LateLintPass, LintContext};
use rustc::ty;
use rustc::ty::adjustment::{Adjust, Adjustment};
use rustc_errors::Applicability;

View file

@ -21,13 +21,8 @@
//! If you define a new `LateLintPass`, you will also need to add it to the
//! `late_lint_methods!` invocation in `lib.rs`.
use std::fmt::Write;
use lint::{EarlyContext, EarlyLintPass, LateLintPass, LintPass};
use lint::{LateContext, LintArray, LintContext};
use rustc::hir::map::Map;
use rustc::lint;
use rustc::lint::FutureIncompatibleInfo;
use rustc::lint::{self, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc::traits::misc::can_type_implement_copy;
use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
@ -39,6 +34,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{GenericParamKind, PatKind};
use rustc_hir::{HirIdSet, Node};
use rustc_session::lint::FutureIncompatibleInfo;
use rustc_span::edition::Edition;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Symbol};
@ -52,6 +48,7 @@ use syntax::visit::FnKind;
use crate::nonstandard_style::{method_context, MethodLateContext};
use log::debug;
use std::fmt::Write;
// hardwired lints from librustc
pub use lint::builtin::*;

View file

@ -16,7 +16,6 @@
use rustc::hir::map::Map;
use rustc::lint::LateContext;
use rustc::lint::LintPass;
use rustc::lint::{LateLintPass, LateLintPassObject};
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::sync::{join, par_iter, ParallelIterator};
@ -24,12 +23,13 @@ use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::intravisit as hir_visit;
use rustc_hir::intravisit::Visitor;
use rustc_session::lint::LintPass;
use rustc_span::Span;
use std::slice;
use syntax::ast;
use syntax::walk_list;
use log::debug;
use syntax::walk_list;
use std::slice;
macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
$cx.pass.$f(&$cx.context, $($args),*);

View file

@ -38,11 +38,12 @@ use rustc::lint::builtin::{
BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
};
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
use rustc::ty::query::Providers;
use rustc::ty::TyCtxt;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_session::lint::{LintArray, LintPass};
use rustc_span::Span;
use syntax::ast;

View file

@ -1,4 +1,4 @@
use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
use syntax::ast;
declare_lint! {

View file

@ -1,6 +1,4 @@
use lint::{EarlyContext, LateContext, LintArray, LintContext};
use lint::{EarlyLintPass, LateLintPass, LintPass};
use rustc::lint;
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc::ty;
use rustc_errors::Applicability;
use rustc_hir as hir;

View file

@ -1,4 +1,4 @@
use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_errors::Applicability;
use syntax::ast::{ExprKind, Stmt, StmtKind};

View file

@ -1,9 +1,6 @@
#![allow(non_snake_case)]
use crate::hir::def_id::DefId;
use lint::{LateContext, LintArray, LintContext};
use lint::{LateLintPass, LintPass};
use rustc::lint;
use rustc::lint::{LateContext, LateLintPass, LintContext};
use rustc::mir::interpret::{sign_extend, truncate};
use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
use rustc::ty::subst::SubstsRef;
@ -11,6 +8,7 @@ use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{is_range_literal, ExprKind, Node};
use rustc_index::vec::Idx;
use rustc_span::source_map;

View file

@ -1,7 +1,5 @@
use lint::{EarlyContext, LateContext, LintArray, LintContext};
use lint::{EarlyLintPass, LateLintPass, LintPass};
use rustc::lint;
use rustc::lint::builtin::UNUSED_ATTRIBUTES;
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc::ty::adjustment;
use rustc::ty::{self, Ty};
use rustc_data_structures::fx::FxHashMap;

View file

@ -326,3 +326,41 @@ macro_rules! declare_tool_lint {
};
);
}
/// Declares a static `LintArray` and return it as an expression.
#[macro_export]
macro_rules! lint_array {
($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
($( $lint:expr ),*) => {{
vec![$($lint),*]
}}
}
pub type LintArray = Vec<&'static Lint>;
pub trait LintPass {
fn name(&self) -> &'static str;
}
/// Implements `LintPass for $name` with the given list of `Lint` statics.
#[macro_export]
macro_rules! impl_lint_pass {
($name:ident => [$($lint:expr),* $(,)?]) => {
impl $crate::lint::LintPass for $name {
fn name(&self) -> &'static str { stringify!($name) }
}
impl $name {
pub fn get_lints() -> $crate::lint::LintArray { $crate::lint_array!($($lint),*) }
}
};
}
/// Declares a type named `$name` which implements `LintPass`.
/// To the right of `=>` a comma separated list of `Lint` statics is given.
#[macro_export]
macro_rules! declare_lint_pass {
($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
$(#[$m])* #[derive(Copy, Clone)] pub struct $name;
$crate::impl_lint_pass!($name => [$($lint),*]);
};
}