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

Extract rustc_ast_passes, move gating, & refactor linting #67806

Merged
merged 18 commits into from
Jan 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 23 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3374,6 +3374,21 @@ dependencies = [
"syntax",
]

[[package]]
name = "rustc_ast_passes"
version = "0.0.0"
dependencies = [
"log",
"rustc_data_structures",
"rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_parse",
"rustc_session",
"rustc_span",
"syntax",
]

[[package]]
name = "rustc_builtin_macros"
version = "0.0.0"
Expand All @@ -3386,6 +3401,7 @@ dependencies = [
"rustc_expand",
"rustc_feature",
"rustc_parse",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec 1.0.0",
Expand Down Expand Up @@ -3539,11 +3555,13 @@ name = "rustc_expand"
version = "0.0.0"
dependencies = [
"log",
"rustc_ast_passes",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_lexer",
"rustc_parse",
"rustc_session",
"rustc_span",
"serialize",
"smallvec 1.0.0",
Expand Down Expand Up @@ -3613,6 +3631,7 @@ dependencies = [
"rustc",
"rustc-rayon",
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_builtin_macros",
"rustc_codegen_llvm",
"rustc_codegen_ssa",
Expand All @@ -3630,6 +3649,7 @@ dependencies = [
"rustc_plugin_impl",
"rustc_privacy",
"rustc_resolve",
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_traits",
Expand Down Expand Up @@ -3768,6 +3788,7 @@ dependencies = [
"rustc_errors",
"rustc_feature",
"rustc_lexer",
"rustc_session",
"rustc_span",
"smallvec 1.0.0",
"syntax",
Expand All @@ -3786,7 +3807,7 @@ dependencies = [
"rustc_feature",
"rustc_hir",
"rustc_index",
"rustc_parse",
"rustc_session",
"rustc_span",
"rustc_target",
"syntax",
Expand Down Expand Up @@ -3866,6 +3887,7 @@ dependencies = [
"log",
"num_cpus",
"rustc_data_structures",
"rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_fs_util",
Expand Down
140 changes: 125 additions & 15 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@
use self::TargetLint::*;

use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
use crate::lint::{EarlyLintPassObject, LateLintPassObject};
use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
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;
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name;
Expand Down Expand Up @@ -64,17 +65,6 @@ pub struct LintStore {
lint_groups: FxHashMap<&'static str, LintGroup>,
}

/// Lints that are buffered up early on in the `Session` before the
/// `LintLevels` is calculated
#[derive(PartialEq, Debug)]
pub struct BufferedEarlyLint {
pub lint_id: LintId,
pub ast_id: ast::NodeId,
pub span: MultiSpan,
pub msg: String,
pub diagnostic: BuiltinLintDiagnostics,
}

/// The target of the `by_name` map, which accounts for renaming/deprecation.
enum TargetLint {
/// A direct lint target
Expand Down Expand Up @@ -477,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;

Expand All @@ -495,7 +527,85 @@ pub trait LintContext: Sized {
diagnostic: BuiltinLintDiagnostics,
) {
let mut db = self.lookup(lint, span, msg);
diagnostic.run(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();
}

Expand Down
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};

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/lint/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use rustc_span::source_map::MultiSpan;
use rustc_span::symbol::{sym, Symbol};
use syntax::ast;
use syntax::attr;
use syntax::feature_gate;
use syntax::print::pprust;
use syntax::sess::feature_err;

use rustc_error_codes::*;

Expand Down Expand Up @@ -223,7 +223,7 @@ impl<'a> LintLevelsBuilder<'a> {
// don't have any lint names (`#[level(reason = "foo")]`)
if let ast::LitKind::Str(rationale, _) = name_value.kind {
if !self.sess.features_untracked().lint_reasons {
feature_gate::feature_err(
feature_err(
&self.sess.parse_sess,
sym::lint_reasons,
item.span,
Expand Down
Loading