Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #68115

Merged
merged 46 commits into from
Jan 11, 2020
Merged
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b650e91
Label unmarked time
Zoxc Jan 9, 2020
5918c18
Tweak timers
Zoxc Jan 9, 2020
1c9f999
Add llvm-skip-rebuild to opts
Jan 9, 2020
fcd850f
Do not ICE on unicode next point
estebank Jan 10, 2020
0bbbd5d
Match llvm-skip-rebuild flag
Jan 9, 2020
7e50b59
Prefer llvm-skip-rebuild flag value over config.toml
Jan 9, 2020
cd9a73d
make use of pointer::is_null
tesuji Jan 10, 2020
8ca5564
Clarify suggestion for E0013
varkor Jan 10, 2020
137a31d
Inline to make OsStr::is_empty zero cost
tesuji Jan 10, 2020
eca1e8b
Inline PathBuf::deref to make it zero cost
tesuji Jan 10, 2020
ea6bb7f
Inline `AsRef<Path> for str`
tesuji Jan 10, 2020
bf1d20c
Inline `impl From<OsString> for PathBuf`
tesuji Jan 10, 2020
3250057
Fix `next_point` to be unicode aware
estebank Jan 10, 2020
d558f6a
Fix invalid bounding box
estebank Jan 10, 2020
cd5ab97
inline `impl AsRef<OsStr> for OsString`
tesuji Jan 10, 2020
76e698f
inline `impl AsRef<Path> for PathBuf`
tesuji Jan 10, 2020
b93ef68
Change `next_point` when `shrink_to_hi` is more appropriate
estebank Jan 10, 2020
f6e9fd0
Add ICE regression tests
estebank Jan 10, 2020
5f3f1a3
inline `impl From<String> for Box<dyn Error + Send + Sync>`
tesuji Jan 10, 2020
799efd3
Fix issue with using `self` module via indirection
varkor Jan 10, 2020
6007641
gating diagnostics -> rustc_session::parse
Centril Jan 2, 2020
c944e6a
document feature_err et. al
Centril Jan 2, 2020
7c78090
get_features -> rustc_parse::config
Centril Jan 2, 2020
1af8c10
simplify feature_err imports
Centril Jan 2, 2020
fff5ef6
canonicalize rustc::session import
Centril Jan 2, 2020
d247ac4
Remove unused derives
Centril Jan 5, 2020
82eeb85
prepare for moving BuiltinLintDiagnostics to rustc_session
Centril Jan 5, 2020
7dbccf5
buffered lint infra -> rustc_session
Centril Jan 5, 2020
45f2764
prepare moving HardwiredLints to rustc_session
Centril Jan 5, 2020
2b44a6c
move {rustc -> rustc_session}::lint::builtin
Centril Jan 5, 2020
f361b71
nix syntax::early_buffered_lints
Centril Jan 5, 2020
ed69fbb
ast_validation -> new crate rustc_ast_passes
Centril Jan 5, 2020
6cbcb83
{syntax -> rustc_ast_passes}::feature_gate
Centril Jan 5, 2020
ae213db
{syntax -> rustc_ast_passes}::show_span
Centril Jan 5, 2020
7d6548a
rustc_passes: remove unused rustc_parse dep
Centril Jan 5, 2020
b4809d0
appease rustfmt
Centril Jan 5, 2020
d0d1c60
pacify tidy by nixing added docs :(
Centril Jan 5, 2020
682f500
fix fallout in ui-fulldeps
Centril Jan 8, 2020
76edc5c
Rollup merge of #67666 - lzutao:ptr-null-cmp, r=dtolnay
Centril Jan 11, 2020
9634e1f
Rollup merge of #67806 - Centril:splitsynmore, r=petrochenkov
Centril Jan 11, 2020
8c0c5c7
Rollup merge of #68043 - Zoxc:missing-timers, r=wesleywiser
Centril Jan 11, 2020
ef3e360
Rollup merge of #68074 - matthew-healy:skip-llvm-rebuild-option, r=Ce…
Centril Jan 11, 2020
ba14f94
Rollup merge of #68079 - varkor:E0013-clarify, r=Centril
Centril Jan 11, 2020
cacda2d
Rollup merge of #68084 - estebank:ice-68000, r=varkor
Centril Jan 11, 2020
c960c3e
Rollup merge of #68102 - lzutao:inline, r=alexcrichton
Centril Jan 11, 2020
04a340f
Rollup merge of #68106 - varkor:self_self_use, r=estebank
Centril Jan 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 2 additions & 129 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
125 changes: 123 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
@@ -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();
}

6 changes: 2 additions & 4 deletions src/librustc/lint/internal.rs
Original file line number Diff line number Diff line change
@@ -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};

45 changes: 6 additions & 39 deletions src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
@@ -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) => ({
2 changes: 1 addition & 1 deletion src/librustc_ast_lowering/path.rs
Original file line number Diff line number Diff line change
@@ -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,
3 changes: 1 addition & 2 deletions src/librustc_lint/array_into_iter.rs
Original file line number Diff line number Diff line change
@@ -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;
9 changes: 3 additions & 6 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -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::*;
6 changes: 3 additions & 3 deletions src/librustc_lint/late.rs
Original file line number Diff line number Diff line change
@@ -16,20 +16,20 @@
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};
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),*);
3 changes: 2 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 1 addition & 1 deletion src/librustc_lint/non_ascii_idents.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
use syntax::ast;

declare_lint! {
4 changes: 1 addition & 3 deletions src/librustc_lint/nonstandard_style.rs
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 1 addition & 1 deletion src/librustc_lint/redundant_semicolon.rs
Original file line number Diff line number Diff line change
@@ -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};

6 changes: 2 additions & 4 deletions src/librustc_lint/types.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
#![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;
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;
4 changes: 1 addition & 3 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
@@ -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;
38 changes: 38 additions & 0 deletions src/librustc_session/lint.rs
Original file line number Diff line number Diff line change
@@ -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),*]);
};
}