diff --git a/Cargo.lock b/Cargo.lock index 214114240af..0008a4a3615 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3789,6 +3789,7 @@ dependencies = [ "rustc_error_codes", "rustc_errors", "rustc_hir", + "rustc_lint", "rustc_metadata", "rustc_span", "syntax", diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index cf424ffe7b2..ef22c6621ae 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -72,8 +72,6 @@ extern crate rustc_data_structures; #[macro_use] extern crate log; #[macro_use] -extern crate syntax; -#[macro_use] extern crate smallvec; #[cfg(test)] diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs index b85982ac3ff..2ed6cd5283b 100644 --- a/src/librustc/lint.rs +++ b/src/librustc/lint.rs @@ -1,30 +1,15 @@ use std::cmp; use crate::ich::StableHashingContext; -use crate::lint::context::CheckLintNameResult; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir::HirId; pub use rustc_session::lint::{builtin, Level, Lint, LintId, LintPass}; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; -use rustc_span::symbol::{sym, Symbol}; -use rustc_span::Span; -use syntax::ast; -use syntax::attr; -use syntax::print::pprust; -use syntax::sess::feature_err; - -use rustc_error_codes::*; - -mod context; -mod passes; - -pub use context::add_elided_lifetime_in_path_suggestion; -pub use context::{EarlyContext, LateContext, LintContext, LintStore}; -pub use passes::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject}; +use rustc_span::{Span, Symbol}; /// How a lint level was set. #[derive(Clone, Copy, PartialEq, Eq, HashStable)] @@ -43,11 +28,11 @@ pub enum LintSource { pub type LevelSource = (Level, LintSource); pub struct LintLevelSets { - list: Vec, - lint_cap: Level, + pub list: Vec, + pub lint_cap: Level, } -enum LintSet { +pub enum LintSet { CommandLine { // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which // flag. @@ -133,381 +118,9 @@ impl LintLevelSets { } } -pub struct LintLevelsBuilder<'a> { - sess: &'a Session, - sets: LintLevelSets, - id_to_set: FxHashMap, - cur: u32, - warn_about_weird_lints: bool, -} - -pub struct BuilderPush { - prev: u32, - pub changed: bool, -} - -impl<'a> LintLevelsBuilder<'a> { - pub fn new(sess: &'a Session, warn_about_weird_lints: bool, store: &LintStore) -> Self { - let mut builder = LintLevelsBuilder { - sess, - sets: LintLevelSets::new(), - cur: 0, - id_to_set: Default::default(), - warn_about_weird_lints, - }; - builder.process_command_line(sess, store); - assert_eq!(builder.sets.list.len(), 1); - builder - } - - fn process_command_line(&mut self, sess: &Session, store: &LintStore) { - let mut specs = FxHashMap::default(); - self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); - - for &(ref lint_name, level) in &sess.opts.lint_opts { - store.check_lint_name_cmdline(sess, &lint_name, level); - - // If the cap is less than this specified level, e.g., if we've got - // `--cap-lints allow` but we've also got `-D foo` then we ignore - // this specification as the lint cap will set it to allow anyway. - let level = cmp::min(level, self.sets.lint_cap); - - let lint_flag_val = Symbol::intern(lint_name); - let ids = match store.find_lints(&lint_name) { - Ok(ids) => ids, - Err(_) => continue, // errors handled in check_lint_name_cmdline above - }; - for id in ids { - let src = LintSource::CommandLine(lint_flag_val); - specs.insert(id, (level, src)); - } - } - - self.sets.list.push(LintSet::CommandLine { specs }); - } - - /// Pushes a list of AST lint attributes onto this context. - /// - /// This function will return a `BuilderPush` object which should be passed - /// to `pop` when this scope for the attributes provided is exited. - /// - /// This function will perform a number of tasks: - /// - /// * It'll validate all lint-related attributes in `attrs` - /// * It'll mark all lint-related attributes as used - /// * Lint levels will be updated based on the attributes provided - /// * Lint attributes are validated, e.g., a #[forbid] can't be switched to - /// #[allow] - /// - /// Don't forget to call `pop`! - pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { - let mut specs = FxHashMap::default(); - let sess = self.sess; - let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); - for attr in attrs { - let level = match Level::from_symbol(attr.name_or_empty()) { - None => continue, - Some(lvl) => lvl, - }; - - let meta = unwrap_or!(attr.meta(), continue); - attr::mark_used(attr); - - let mut metas = unwrap_or!(meta.meta_item_list(), continue); - - if metas.is_empty() { - // FIXME (#55112): issue unused-attributes lint for `#[level()]` - continue; - } - - // Before processing the lint names, look for a reason (RFC 2383) - // at the end. - let mut reason = None; - let tail_li = &metas[metas.len() - 1]; - if let Some(item) = tail_li.meta_item() { - match item.kind { - ast::MetaItemKind::Word => {} // actual lint names handled later - ast::MetaItemKind::NameValue(ref name_value) => { - if item.path == sym::reason { - // found reason, reslice meta list to exclude it - metas = &metas[0..metas.len() - 1]; - // FIXME (#55112): issue unused-attributes lint if we thereby - // 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_err( - &self.sess.parse_sess, - sym::lint_reasons, - item.span, - "lint reasons are experimental", - ) - .emit(); - } - reason = Some(rationale); - } else { - bad_attr(name_value.span) - .span_label(name_value.span, "reason must be a string literal") - .emit(); - } - } else { - bad_attr(item.span) - .span_label(item.span, "bad attribute argument") - .emit(); - } - } - ast::MetaItemKind::List(_) => { - bad_attr(item.span).span_label(item.span, "bad attribute argument").emit(); - } - } - } - - for li in metas { - let meta_item = match li.meta_item() { - Some(meta_item) if meta_item.is_word() => meta_item, - _ => { - let sp = li.span(); - let mut err = bad_attr(sp); - let mut add_label = true; - if let Some(item) = li.meta_item() { - if let ast::MetaItemKind::NameValue(_) = item.kind { - if item.path == sym::reason { - err.span_label(sp, "reason in lint attribute must come last"); - add_label = false; - } - } - } - if add_label { - err.span_label(sp, "bad attribute argument"); - } - err.emit(); - continue; - } - }; - let tool_name = if meta_item.path.segments.len() > 1 { - let tool_ident = meta_item.path.segments[0].ident; - if !attr::is_known_lint_tool(tool_ident) { - struct_span_err!( - sess, - tool_ident.span, - E0710, - "an unknown tool name found in scoped lint: `{}`", - pprust::path_to_string(&meta_item.path), - ) - .emit(); - continue; - } - - Some(tool_ident.name) - } else { - None - }; - let name = meta_item.path.segments.last().expect("empty lint name").ident.name; - match store.check_lint_name(&name.as_str(), tool_name) { - CheckLintNameResult::Ok(ids) => { - let src = LintSource::Node(name, li.span(), reason); - for id in ids { - specs.insert(*id, (level, src)); - } - } - - CheckLintNameResult::Tool(result) => { - match result { - Ok(ids) => { - let complete_name = &format!("{}::{}", tool_name.unwrap(), name); - let src = LintSource::Node( - Symbol::intern(complete_name), - li.span(), - reason, - ); - for id in ids { - specs.insert(*id, (level, src)); - } - } - Err((Some(ids), new_lint_name)) => { - let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (lvl, src) = - self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); - let msg = format!( - "lint name `{}` is deprecated \ - and may not have an effect in the future. \ - Also `cfg_attr(cargo-clippy)` won't be necessary anymore", - name - ); - struct_lint_level( - self.sess, - lint, - lvl, - src, - Some(li.span().into()), - &msg, - ) - .span_suggestion( - li.span(), - "change it to", - new_lint_name.to_string(), - Applicability::MachineApplicable, - ) - .emit(); - - let src = LintSource::Node( - Symbol::intern(&new_lint_name), - li.span(), - reason, - ); - for id in ids { - specs.insert(*id, (level, src)); - } - } - Err((None, _)) => { - // If Tool(Err(None, _)) is returned, then either the lint does not - // exist in the tool or the code was not compiled with the tool and - // therefore the lint was never added to the `LintStore`. To detect - // this is the responsibility of the lint tool. - } - } - } - - _ if !self.warn_about_weird_lints => {} - - CheckLintNameResult::Warning(msg, renamed) => { - let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (level, src) = - self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); - let mut err = struct_lint_level( - self.sess, - lint, - level, - src, - Some(li.span().into()), - &msg, - ); - if let Some(new_name) = renamed { - err.span_suggestion( - li.span(), - "use the new name", - new_name, - Applicability::MachineApplicable, - ); - } - err.emit(); - } - CheckLintNameResult::NoLint(suggestion) => { - let lint = builtin::UNKNOWN_LINTS; - let (level, src) = - self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); - let msg = format!("unknown lint: `{}`", name); - let mut db = struct_lint_level( - self.sess, - lint, - level, - src, - Some(li.span().into()), - &msg, - ); - - if let Some(suggestion) = suggestion { - db.span_suggestion( - li.span(), - "did you mean", - suggestion.to_string(), - Applicability::MachineApplicable, - ); - } - - db.emit(); - } - } - } - } - - for (id, &(level, ref src)) in specs.iter() { - if level == Level::Forbid { - continue; - } - let forbid_src = match self.sets.get_lint_id_level(*id, self.cur, None) { - (Some(Level::Forbid), src) => src, - _ => continue, - }; - let forbidden_lint_name = match forbid_src { - LintSource::Default => id.to_string(), - LintSource::Node(name, _, _) => name.to_string(), - LintSource::CommandLine(name) => name.to_string(), - }; - let (lint_attr_name, lint_attr_span) = match *src { - LintSource::Node(name, span, _) => (name, span), - _ => continue, - }; - let mut diag_builder = struct_span_err!( - self.sess, - lint_attr_span, - E0453, - "{}({}) overruled by outer forbid({})", - level.as_str(), - lint_attr_name, - forbidden_lint_name - ); - diag_builder.span_label(lint_attr_span, "overruled by previous forbid"); - match forbid_src { - LintSource::Default => {} - LintSource::Node(_, forbid_source_span, reason) => { - diag_builder.span_label(forbid_source_span, "`forbid` level set here"); - if let Some(rationale) = reason { - diag_builder.note(&rationale.as_str()); - } - } - LintSource::CommandLine(_) => { - diag_builder.note("`forbid` lint level was set on command line"); - } - } - diag_builder.emit(); - // don't set a separate error for every lint in the group - break; - } - - let prev = self.cur; - if specs.len() > 0 { - self.cur = self.sets.list.len() as u32; - self.sets.list.push(LintSet::Node { specs: specs, parent: prev }); - } - - BuilderPush { prev: prev, changed: prev != self.cur } - } - - /// Called after `push` when the scope of a set of attributes are exited. - pub fn pop(&mut self, push: BuilderPush) { - self.cur = push.prev; - } - - /// Used to emit a lint-related diagnostic based on the current state of - /// this lint context. - pub fn struct_lint( - &self, - lint: &'static Lint, - span: Option, - msg: &str, - ) -> DiagnosticBuilder<'a> { - let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess); - struct_lint_level(self.sess, lint, level, src, span, msg) - } - - /// Registers the ID provided with the current set of lints stored in - /// this context. - pub fn register_id(&mut self, id: HirId) { - self.id_to_set.insert(id, self.cur); - } - - pub fn build(self) -> LintLevelSets { - self.sets - } - - pub fn build_map(self) -> LintLevelMap { - LintLevelMap { sets: self.sets, id_to_set: self.id_to_set } - } -} - pub struct LintLevelMap { - sets: LintLevelSets, - id_to_set: FxHashMap, + pub sets: LintLevelSets, + pub id_to_set: FxHashMap, } impl LintLevelMap { @@ -712,3 +325,45 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { ExpnKind::Macro(..) => true, // definitely a plugin } } + +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` 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, + ); +} diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 58b8e8a089a..d30d0bd8345 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -37,7 +37,6 @@ use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; -use rustc::lint::builtin; use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -51,7 +50,7 @@ use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_index::vec::IndexVec; use rustc_session::config::nightly_options; -use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::lint::{builtin, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::node_id::NodeMap; use rustc_session::Session; use rustc_span::hygiene::ExpnId; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3d31f240a34..072b85d716d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -23,9 +23,7 @@ extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; -//use rustc_resolve as resolve; -use rustc::lint; -use rustc::lint::Lint; +use rustc::lint::{Lint, LintId}; use rustc::middle::cstore::MetadataLoader; use rustc::session::config::nightly_options; use rustc::session::config::{ErrorOutputType, Input, OutputType, PrintRequest}; @@ -41,6 +39,7 @@ use rustc_feature::{find_gated_cfg, UnstableFeatures}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::util::get_builtin_codegen_backend; use rustc_interface::{interface, Queries}; +use rustc_lint::LintStore; use rustc_metadata::locator; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; @@ -811,7 +810,7 @@ the command line flag directly. ); } -fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins: bool) { +fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_plugins: bool) { println!( " Available lint options: @@ -832,8 +831,8 @@ Available lint options: } fn sort_lint_groups( - lints: Vec<(&'static str, Vec, bool)>, - ) -> Vec<(&'static str, Vec)> { + lints: Vec<(&'static str, Vec, bool)>, + ) -> Vec<(&'static str, Vec)> { let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect(); lints.sort_by_key(|l| l.0); lints @@ -892,7 +891,7 @@ Available lint options: println!(" {} {}", padded("----"), "---------"); println!(" {} {}", padded("warnings"), "all lints that are set to issue warnings"); - let print_lint_groups = |lints: Vec<(&'static str, Vec)>| { + let print_lint_groups = |lints: Vec<(&'static str, Vec)>| { for (name, to) in lints { let name = name.to_lowercase().replace("_", "-"); let desc = to diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index d00875f6fee..9cd9eb66cf6 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -12,6 +12,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; +use rustc_lint::LintStore; use rustc_parse::new_parser_from_source_str; use rustc_span::edition; use rustc_span::source_map::{FileLoader, FileName, SourceMap}; @@ -36,7 +37,7 @@ pub struct Compiler { pub(crate) output_dir: Option, pub(crate) output_file: Option, pub(crate) crate_name: Option, - pub(crate) register_lints: Option>, + pub(crate) register_lints: Option>, pub(crate) override_queries: Option, &mut ty::query::Providers<'_>)>, } @@ -136,7 +137,7 @@ pub struct Config { /// /// Note that if you find a Some here you probably want to call that function in the new /// function being registered. - pub register_lints: Option>, + pub register_lints: Option>, /// This is a callback from the driver that is called just after we have populated /// the list of queries. diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc0..67f9819f331 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -27,6 +27,7 @@ use rustc_errors::PResult; use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_incremental; +use rustc_lint::LintStore; use rustc_mir as mir; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; @@ -100,7 +101,7 @@ declare_box_region_type!( /// Returns `None` if we're aborting after handling -W help. pub fn configure_and_expand( sess: Lrc, - lint_store: Lrc, + lint_store: Lrc, metadata_loader: Box, krate: ast::Crate, crate_name: &str, @@ -150,10 +151,10 @@ impl BoxedResolver { pub fn register_plugins<'a>( sess: &'a Session, metadata_loader: &'a dyn MetadataLoader, - register_lints: impl Fn(&Session, &mut lint::LintStore), + register_lints: impl Fn(&Session, &mut LintStore), mut krate: ast::Crate, crate_name: &str, -) -> Result<(ast::Crate, Lrc)> { +) -> Result<(ast::Crate, Lrc)> { krate = sess.time("attributes_injection", || { rustc_builtin_macros::cmdline_attrs::inject( krate, @@ -214,7 +215,7 @@ pub fn register_plugins<'a>( fn configure_and_expand_inner<'a>( sess: &'a Session, - lint_store: &'a lint::LintStore, + lint_store: &'a LintStore, mut krate: ast::Crate, crate_name: &str, resolver_arenas: &'a ResolverArenas<'a>, @@ -420,7 +421,7 @@ fn configure_and_expand_inner<'a>( pub fn lower_to_hir<'res, 'tcx>( sess: &'tcx Session, - lint_store: &lint::LintStore, + lint_store: &LintStore, resolver: &'res mut Resolver<'_>, dep_graph: &'res DepGraph, krate: &'res ast::Crate, @@ -705,7 +706,7 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, - lint_store: Lrc, + lint_store: Lrc, hir_forest: &'tcx map::Forest<'tcx>, mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 7de1c36ce4b..bd9717d3f3d 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -4,8 +4,6 @@ use crate::passes::{self, BoxedResolver, QueryContext}; use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir::map; -use rustc::lint; -use rustc::lint::LintStore; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::session::Session; use rustc::ty::steal::Steal; @@ -15,6 +13,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_incremental::DepGraphFuture; +use rustc_lint::LintStore; use std::any::Any; use std::cell::{Ref, RefCell, RefMut}; use std::mem; @@ -133,7 +132,7 @@ impl<'tcx> Queries<'tcx> { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); - let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; + let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), &*self.codegen_backend().metadata_loader(), diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index 7f053f9de29..fb11b6771e9 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -1,4 +1,4 @@ -use rustc::lint::{LateContext, LateLintPass, LintContext}; +use crate::{LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc::ty::adjustment::{Adjust, Adjustment}; use rustc_errors::Applicability; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index befeb84e57c..15a8332a284 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -21,8 +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 crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::hir::map::Map; -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; @@ -51,7 +51,7 @@ use log::debug; use std::fmt::Write; // hardwired lints from librustc -pub use lint::builtin::*; +pub use rustc_session::lint::builtin::*; declare_lint! { WHILE_TRUE, diff --git a/src/librustc/lint/context.rs b/src/librustc_lint/context.rs similarity index 93% rename from src/librustc/lint/context.rs rename to src/librustc_lint/context.rs index 702d707346b..2b514c301f2 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc_lint/context.rs @@ -16,17 +16,18 @@ use self::TargetLint::*; -use crate::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; -use crate::lint::passes::{EarlyLintPassObject, LateLintPassObject}; -use crate::lint::LintLevelsBuilder; -use crate::middle::privacy::AccessLevels; -use crate::middle::stability; -use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; -use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; +use crate::levels::LintLevelsBuilder; +use crate::passes::{EarlyLintPassObject, LateLintPassObject}; +use rustc::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc::lint::add_elided_lifetime_in_path_suggestion; +use rustc::middle::privacy::AccessLevels; +use rustc::middle::stability; +use rustc::ty::layout::{LayoutError, LayoutOf, TyLayout}; +use rustc::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::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_session::lint::BuiltinLintDiagnostics; @@ -467,48 +468,6 @@ 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` 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; diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 9a901719851..490114b2d4d 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -14,10 +14,9 @@ //! upon. As the ast is traversed, this keeps track of the current lint level //! for all lint attributes. -use rustc::lint::{EarlyContext, LintStore}; -use rustc::lint::{EarlyLintPass, EarlyLintPassObject}; -use rustc::lint::{LintContext, LintPass}; -use rustc_session::lint::LintBuffer; +use crate::context::{EarlyContext, LintContext, LintStore}; +use crate::passes::{EarlyLintPass, EarlyLintPassObject}; +use rustc_session::lint::{LintBuffer, LintPass}; use rustc_session::Session; use rustc_span::Span; use syntax::ast; @@ -291,7 +290,7 @@ macro_rules! early_lint_pass_impl { ) } -early_lint_methods!(early_lint_pass_impl, []); +crate::early_lint_methods!(early_lint_pass_impl, []); fn early_lint_crate( sess: &Session, diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 30417bf5a24..2f8393bd906 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -1,8 +1,7 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use crate::lint::{EarlyContext, LateContext, LintContext}; -use crate::lint::{EarlyLintPass, LateLintPass}; +use crate::{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}; diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index e3ab604d398..eb5f89c9507 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -14,8 +14,8 @@ //! upon. As the ast is traversed, this keeps track of the current lint level //! for all lint attributes. +use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; use rustc::hir::map::Map; -use rustc::lint::{LateContext, LateLintPass, LateLintPassObject, LintStore}; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; use rustc_hir as hir; @@ -347,7 +347,7 @@ macro_rules! late_lint_pass_impl { ) } -late_lint_methods!(late_lint_pass_impl, [], ['tcx]); +crate::late_lint_methods!(late_lint_pass_impl, [], ['tcx]); fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( tcx: TyCtxt<'tcx>, diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index 46ea04e5ccf..bbc3e57f5dd 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -1,14 +1,27 @@ -use super::late::unerased_lint_store; +use crate::context::{CheckLintNameResult, LintStore}; +use crate::late::unerased_lint_store; use rustc::hir::map::Map; -use rustc::lint::{LintLevelMap, LintLevelsBuilder, LintStore}; +use rustc::lint::struct_lint_level; +use rustc::lint::{LintLevelMap, LintLevelSets, LintSet, LintSource}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_data_structures::fx::FxHashMap; +use rustc_error_codes::*; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; +use rustc_session::lint::{builtin, Level, Lint}; +use rustc_session::Session; +use rustc_span::{sym, MultiSpan, Symbol}; use syntax::ast; +use syntax::attr; +use syntax::print::pprust; +use syntax::sess::feature_err; +use syntax::unwrap_or; -pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId}; +use std::cmp; fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); @@ -28,6 +41,378 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { tcx.arena.alloc(builder.levels.build_map()) } +pub struct LintLevelsBuilder<'a> { + sess: &'a Session, + sets: LintLevelSets, + id_to_set: FxHashMap, + cur: u32, + warn_about_weird_lints: bool, +} + +pub struct BuilderPush { + prev: u32, + pub changed: bool, +} + +impl<'a> LintLevelsBuilder<'a> { + pub fn new(sess: &'a Session, warn_about_weird_lints: bool, store: &LintStore) -> Self { + let mut builder = LintLevelsBuilder { + sess, + sets: LintLevelSets::new(), + cur: 0, + id_to_set: Default::default(), + warn_about_weird_lints, + }; + builder.process_command_line(sess, store); + assert_eq!(builder.sets.list.len(), 1); + builder + } + + fn process_command_line(&mut self, sess: &Session, store: &LintStore) { + let mut specs = FxHashMap::default(); + self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); + + for &(ref lint_name, level) in &sess.opts.lint_opts { + store.check_lint_name_cmdline(sess, &lint_name, level); + + // If the cap is less than this specified level, e.g., if we've got + // `--cap-lints allow` but we've also got `-D foo` then we ignore + // this specification as the lint cap will set it to allow anyway. + let level = cmp::min(level, self.sets.lint_cap); + + let lint_flag_val = Symbol::intern(lint_name); + let ids = match store.find_lints(&lint_name) { + Ok(ids) => ids, + Err(_) => continue, // errors handled in check_lint_name_cmdline above + }; + for id in ids { + let src = LintSource::CommandLine(lint_flag_val); + specs.insert(id, (level, src)); + } + } + + self.sets.list.push(LintSet::CommandLine { specs }); + } + + /// Pushes a list of AST lint attributes onto this context. + /// + /// This function will return a `BuilderPush` object which should be passed + /// to `pop` when this scope for the attributes provided is exited. + /// + /// This function will perform a number of tasks: + /// + /// * It'll validate all lint-related attributes in `attrs` + /// * It'll mark all lint-related attributes as used + /// * Lint levels will be updated based on the attributes provided + /// * Lint attributes are validated, e.g., a #[forbid] can't be switched to + /// #[allow] + /// + /// Don't forget to call `pop`! + pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { + let mut specs = FxHashMap::default(); + let sess = self.sess; + let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); + for attr in attrs { + let level = match Level::from_symbol(attr.name_or_empty()) { + None => continue, + Some(lvl) => lvl, + }; + + let meta = unwrap_or!(attr.meta(), continue); + attr::mark_used(attr); + + let mut metas = unwrap_or!(meta.meta_item_list(), continue); + + if metas.is_empty() { + // FIXME (#55112): issue unused-attributes lint for `#[level()]` + continue; + } + + // Before processing the lint names, look for a reason (RFC 2383) + // at the end. + let mut reason = None; + let tail_li = &metas[metas.len() - 1]; + if let Some(item) = tail_li.meta_item() { + match item.kind { + ast::MetaItemKind::Word => {} // actual lint names handled later + ast::MetaItemKind::NameValue(ref name_value) => { + if item.path == sym::reason { + // found reason, reslice meta list to exclude it + metas = &metas[0..metas.len() - 1]; + // FIXME (#55112): issue unused-attributes lint if we thereby + // 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_err( + &self.sess.parse_sess, + sym::lint_reasons, + item.span, + "lint reasons are experimental", + ) + .emit(); + } + reason = Some(rationale); + } else { + bad_attr(name_value.span) + .span_label(name_value.span, "reason must be a string literal") + .emit(); + } + } else { + bad_attr(item.span) + .span_label(item.span, "bad attribute argument") + .emit(); + } + } + ast::MetaItemKind::List(_) => { + bad_attr(item.span).span_label(item.span, "bad attribute argument").emit(); + } + } + } + + for li in metas { + let meta_item = match li.meta_item() { + Some(meta_item) if meta_item.is_word() => meta_item, + _ => { + let sp = li.span(); + let mut err = bad_attr(sp); + let mut add_label = true; + if let Some(item) = li.meta_item() { + if let ast::MetaItemKind::NameValue(_) = item.kind { + if item.path == sym::reason { + err.span_label(sp, "reason in lint attribute must come last"); + add_label = false; + } + } + } + if add_label { + err.span_label(sp, "bad attribute argument"); + } + err.emit(); + continue; + } + }; + let tool_name = if meta_item.path.segments.len() > 1 { + let tool_ident = meta_item.path.segments[0].ident; + if !attr::is_known_lint_tool(tool_ident) { + struct_span_err!( + sess, + tool_ident.span, + E0710, + "an unknown tool name found in scoped lint: `{}`", + pprust::path_to_string(&meta_item.path), + ) + .emit(); + continue; + } + + Some(tool_ident.name) + } else { + None + }; + let name = meta_item.path.segments.last().expect("empty lint name").ident.name; + match store.check_lint_name(&name.as_str(), tool_name) { + CheckLintNameResult::Ok(ids) => { + let src = LintSource::Node(name, li.span(), reason); + for id in ids { + specs.insert(*id, (level, src)); + } + } + + CheckLintNameResult::Tool(result) => { + match result { + Ok(ids) => { + let complete_name = &format!("{}::{}", tool_name.unwrap(), name); + let src = LintSource::Node( + Symbol::intern(complete_name), + li.span(), + reason, + ); + for id in ids { + specs.insert(*id, (level, src)); + } + } + Err((Some(ids), new_lint_name)) => { + let lint = builtin::RENAMED_AND_REMOVED_LINTS; + let (lvl, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); + let msg = format!( + "lint name `{}` is deprecated \ + and may not have an effect in the future. \ + Also `cfg_attr(cargo-clippy)` won't be necessary anymore", + name + ); + struct_lint_level( + self.sess, + lint, + lvl, + src, + Some(li.span().into()), + &msg, + ) + .span_suggestion( + li.span(), + "change it to", + new_lint_name.to_string(), + Applicability::MachineApplicable, + ) + .emit(); + + let src = LintSource::Node( + Symbol::intern(&new_lint_name), + li.span(), + reason, + ); + for id in ids { + specs.insert(*id, (level, src)); + } + } + Err((None, _)) => { + // If Tool(Err(None, _)) is returned, then either the lint does not + // exist in the tool or the code was not compiled with the tool and + // therefore the lint was never added to the `LintStore`. To detect + // this is the responsibility of the lint tool. + } + } + } + + _ if !self.warn_about_weird_lints => {} + + CheckLintNameResult::Warning(msg, renamed) => { + let lint = builtin::RENAMED_AND_REMOVED_LINTS; + let (level, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); + let mut err = struct_lint_level( + self.sess, + lint, + level, + src, + Some(li.span().into()), + &msg, + ); + if let Some(new_name) = renamed { + err.span_suggestion( + li.span(), + "use the new name", + new_name, + Applicability::MachineApplicable, + ); + } + err.emit(); + } + CheckLintNameResult::NoLint(suggestion) => { + let lint = builtin::UNKNOWN_LINTS; + let (level, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); + let msg = format!("unknown lint: `{}`", name); + let mut db = struct_lint_level( + self.sess, + lint, + level, + src, + Some(li.span().into()), + &msg, + ); + + if let Some(suggestion) = suggestion { + db.span_suggestion( + li.span(), + "did you mean", + suggestion.to_string(), + Applicability::MachineApplicable, + ); + } + + db.emit(); + } + } + } + } + + for (id, &(level, ref src)) in specs.iter() { + if level == Level::Forbid { + continue; + } + let forbid_src = match self.sets.get_lint_id_level(*id, self.cur, None) { + (Some(Level::Forbid), src) => src, + _ => continue, + }; + let forbidden_lint_name = match forbid_src { + LintSource::Default => id.to_string(), + LintSource::Node(name, _, _) => name.to_string(), + LintSource::CommandLine(name) => name.to_string(), + }; + let (lint_attr_name, lint_attr_span) = match *src { + LintSource::Node(name, span, _) => (name, span), + _ => continue, + }; + let mut diag_builder = struct_span_err!( + self.sess, + lint_attr_span, + E0453, + "{}({}) overruled by outer forbid({})", + level.as_str(), + lint_attr_name, + forbidden_lint_name + ); + diag_builder.span_label(lint_attr_span, "overruled by previous forbid"); + match forbid_src { + LintSource::Default => {} + LintSource::Node(_, forbid_source_span, reason) => { + diag_builder.span_label(forbid_source_span, "`forbid` level set here"); + if let Some(rationale) = reason { + diag_builder.note(&rationale.as_str()); + } + } + LintSource::CommandLine(_) => { + diag_builder.note("`forbid` lint level was set on command line"); + } + } + diag_builder.emit(); + // don't set a separate error for every lint in the group + break; + } + + let prev = self.cur; + if specs.len() > 0 { + self.cur = self.sets.list.len() as u32; + self.sets.list.push(LintSet::Node { specs: specs, parent: prev }); + } + + BuilderPush { prev: prev, changed: prev != self.cur } + } + + /// Called after `push` when the scope of a set of attributes are exited. + pub fn pop(&mut self, push: BuilderPush) { + self.cur = push.prev; + } + + /// Used to emit a lint-related diagnostic based on the current state of + /// this lint context. + pub fn struct_lint( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + ) -> DiagnosticBuilder<'a> { + let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess); + struct_lint_level(self.sess, lint, level, src, span, msg) + } + + /// Registers the ID provided with the current set of lints stored in + /// this context. + pub fn register_id(&mut self, id: HirId) { + self.id_to_set.insert(id, self.cur); + } + + pub fn build(self) -> LintLevelSets { + self.sets + } + + pub fn build_map(self) -> LintLevelMap { + LintLevelMap { sets: self.sets, id_to_set: self.id_to_set } + } +} + struct LintLevelMapBuilder<'a, 'tcx> { levels: LintLevelsBuilder<'tcx>, tcx: TyCtxt<'tcx>, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index e11472e1136..93eae1d6c1a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] +#![feature(never_type)] #![feature(nll)] #![recursion_limit = "256"] @@ -25,33 +26,29 @@ extern crate rustc_session; mod array_into_iter; pub mod builtin; +mod context; mod early; mod internal; mod late; mod levels; mod non_ascii_idents; mod nonstandard_style; +mod passes; mod redundant_semicolon; mod types; mod unused; -use rustc::lint; -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}; 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_session::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_span::Span; use syntax::ast; -use lint::LintId; - use array_into_iter::ArrayIntoIter; use builtin::*; use internal::*; @@ -61,10 +58,15 @@ use redundant_semicolon::*; use types::*; use unused::*; -/// Useful for other parts of the compiler. +/// Useful for other parts of the compiler / Clippy. pub use builtin::SoftLints; +pub use context::{EarlyContext, LateContext, LintContext, LintStore}; pub use early::check_ast_crate; pub use late::check_crate; +pub use passes::{EarlyLintPass, LateLintPass}; +pub use rustc_session::lint::Level::{self, *}; +pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId}; +pub use rustc_session::lint::{LintArray, LintPass}; pub fn provide(providers: &mut Providers<'_>) { levels::provide(providers); @@ -181,8 +183,8 @@ late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]) late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]); -pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore { - let mut lint_store = lint::LintStore::new(); +pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> LintStore { + let mut lint_store = LintStore::new(); register_builtins(&mut lint_store, no_interleave_lints); if internal_lints { @@ -195,7 +197,7 @@ pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint:: /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). -fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { +fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { ($name:expr, $($lint:ident),*) => ( store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); @@ -392,7 +394,7 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { store.register_removed("plugin_as_library", "plugins have been deprecated and retired"); } -fn register_internals(store: &mut lint::LintStore) { +fn register_internals(store: &mut LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs index 522aeb6b144..3c85a1b31b2 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/src/librustc_lint/non_ascii_idents.rs @@ -1,4 +1,4 @@ -use rustc::lint::{EarlyContext, EarlyLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LintContext}; use syntax::ast; declare_lint! { diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index f75bb9ba32c..a2b7884241f 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,4 +1,4 @@ -use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/src/librustc/lint/passes.rs b/src/librustc_lint/passes.rs similarity index 96% rename from src/librustc/lint/passes.rs rename to src/librustc_lint/passes.rs index 41671ccc6c0..cb54105381f 100644 --- a/src/librustc/lint/passes.rs +++ b/src/librustc_lint/passes.rs @@ -18,23 +18,15 @@ //! example) requires more effort. See `emit_lint` and `GatherNodeLevels` //! in `context.rs`. -pub use self::Level::*; -pub use crate::lint::LintSource::{self, *}; +use crate::context::{EarlyContext, LateContext}; use rustc_data_structures::sync; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; +use rustc_session::lint::LintPass; use rustc_span::Span; use syntax::ast; -pub use crate::lint::context::{ - add_elided_lifetime_in_path_suggestion, CheckLintNameResult, EarlyContext, LateContext, - LintContext, LintStore, -}; - -pub use rustc_session::lint::{builtin, LintArray, LintPass}; -pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; - #[macro_export] macro_rules! late_lint_methods { ($macro:path, $args:tt, [$hir:tt]) => ( @@ -169,6 +161,7 @@ macro_rules! declare_combined_late_lint_pass { expand_combined_late_lint_pass_methods!([$($passes),*], $methods); } + #[allow(rustc::lint_pass_impl_without_macro)] impl LintPass for $name { fn name(&self) -> &'static str { panic!() @@ -296,6 +289,7 @@ macro_rules! declare_combined_early_lint_pass { expand_combined_early_lint_pass_methods!([$($passes),*], $methods); } + #[allow(rustc::lint_pass_impl_without_macro)] impl LintPass for $name { fn name(&self) -> &'static str { panic!() diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index dc18f15fe40..21b244ad75d 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,4 +1,4 @@ -use rustc::lint::{EarlyContext, EarlyLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LintContext}; use rustc_errors::Applicability; use syntax::ast::{ExprKind, Stmt, StmtKind}; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index ab6841c0c09..674a82b6196 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] -use rustc::lint::{LateContext, LateLintPass, LintContext}; +use crate::{LateContext, LateLintPass, LintContext}; use rustc::mir::interpret::{sign_extend, truncate}; use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx}; use rustc::ty::subst::SubstsRef; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index da8a23f041e..26cbda3d978 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,5 +1,4 @@ -use rustc::lint::builtin::UNUSED_ATTRIBUTES; -use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty::adjustment; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashMap; @@ -8,6 +7,7 @@ use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_session::lint::builtin::UNUSED_ATTRIBUTES; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml index d0b7accafd6..41e6c699c34 100644 --- a/src/librustc_plugin_impl/Cargo.toml +++ b/src/librustc_plugin_impl/Cargo.toml @@ -14,6 +14,7 @@ doctest = false rustc = { path = "../librustc" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } +rustc_lint = { path = "../librustc_lint" } rustc_metadata = { path = "../librustc_metadata" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_plugin_impl/lib.rs b/src/librustc_plugin_impl/lib.rs index 682d223f565..10712eb60b9 100644 --- a/src/librustc_plugin_impl/lib.rs +++ b/src/librustc_plugin_impl/lib.rs @@ -9,7 +9,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(nll)] -use rustc::lint::LintStore; +use rustc_lint::LintStore; pub mod build; pub mod load;