Skip to content

Commit

Permalink
Rollup merge of rust-lang#67806 - Centril:splitsynmore, r=petrochenkov
Browse files Browse the repository at this point in the history
Extract `rustc_ast_passes`, move gating, & refactor linting

Based on rust-lang#67770.

This PR extracts a crate `rustc_ast_passes`:

- `ast_validation.rs`, which is contributed by `rustc_passes` (now only has HIR based passes) -- the goal here is to improve recompilation of the parser,
- `feature_gate.rs`, which is contributed by `syntax` and performs post-expansion-gating & final erroring for pre-expansion gating,
- `show_span`, which is contributed by `syntax`.

To facilitate this, we first have to also:

- Move `{leveled_}feature_err{_err}` from `syntax::feature_gate::check` into `rustc_session::parse`.
- Move `get_features` into `rustc_parse::config`, the only place it is used.
- Move some some lint datatypes and traits, e.g. `LintBuffer`, `BufferedEarlyLint`, `BuiltinLintDiagnostics`, `LintPass`, and `LintArray` into `rustc_session::lint`.
- Move all the hard-wired lint `static`s into `rustc_session::lint::builtin`.
  • Loading branch information
Centril authored Jan 11, 2020
2 parents 76edc5c + 682f500 commit 9634e1f
Show file tree
Hide file tree
Showing 59 changed files with 711 additions and 679 deletions.
24 changes: 23 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3363,6 +3363,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 @@ -3375,6 +3390,7 @@ dependencies = [
"rustc_expand",
"rustc_feature",
"rustc_parse",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec 1.0.0",
Expand Down Expand Up @@ -3528,11 +3544,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 @@ -3602,6 +3620,7 @@ dependencies = [
"rustc",
"rustc-rayon",
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_builtin_macros",
"rustc_codegen_llvm",
"rustc_codegen_ssa",
Expand All @@ -3619,6 +3638,7 @@ dependencies = [
"rustc_plugin_impl",
"rustc_privacy",
"rustc_resolve",
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_traits",
Expand Down Expand Up @@ -3735,6 +3755,7 @@ dependencies = [
"rustc_errors",
"rustc_feature",
"rustc_lexer",
"rustc_session",
"rustc_span",
"smallvec 1.0.0",
"syntax",
Expand All @@ -3753,7 +3774,7 @@ dependencies = [
"rustc_feature",
"rustc_hir",
"rustc_index",
"rustc_parse",
"rustc_session",
"rustc_span",
"rustc_target",
"syntax",
Expand Down Expand Up @@ -3833,6 +3854,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

0 comments on commit 9634e1f

Please sign in to comment.