diff --git a/Cargo.lock b/Cargo.lock index 45a1a169be446..45210cadafd1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3636,6 +3636,7 @@ dependencies = [ "rustc", "rustc_data_structures", "rustc_error_codes", + "rustc_errors", "rustc_feature", "rustc_index", "rustc_session", diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 847c61033daf4..7fa0c770d2a95 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,7 +4,7 @@ //! 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::lint::FutureIncompatibleInfo; use crate::middle::stability; use crate::session::Session; use errors::{pluralize, Applicability, DiagnosticBuilder}; @@ -13,7 +13,6 @@ use rustc_span::edition::Edition; use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; use syntax::ast; -use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; declare_lint! { pub EXCEEDING_BITSHIFTS, @@ -443,70 +442,6 @@ declare_lint! { }; } -declare_lint_pass! { - /// Does nothing as a lint pass, but registers some `Lint`s - /// that are used by other parts of the compiler. - HardwiredLints => [ - ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, - EXCEEDING_BITSHIFTS, - UNUSED_IMPORTS, - UNUSED_EXTERN_CRATES, - UNUSED_QUALIFICATIONS, - UNKNOWN_LINTS, - UNUSED_VARIABLES, - UNUSED_ASSIGNMENTS, - DEAD_CODE, - UNREACHABLE_CODE, - UNREACHABLE_PATTERNS, - OVERLAPPING_PATTERNS, - UNUSED_MACROS, - WARNINGS, - UNUSED_FEATURES, - STABLE_FEATURES, - UNKNOWN_CRATE_TYPES, - TRIVIAL_CASTS, - TRIVIAL_NUMERIC_CASTS, - PRIVATE_IN_PUBLIC, - EXPORTED_PRIVATE_DEPENDENCIES, - PUB_USE_OF_PRIVATE_EXTERN_CRATE, - INVALID_TYPE_PARAM_DEFAULT, - CONST_ERR, - RENAMED_AND_REMOVED_LINTS, - SAFE_PACKED_BORROWS, - PATTERNS_IN_FNS_WITHOUT_BODY, - MISSING_FRAGMENT_SPECIFIER, - LATE_BOUND_LIFETIME_ARGUMENTS, - ORDER_DEPENDENT_TRAIT_OBJECTS, - DEPRECATED, - UNUSED_UNSAFE, - UNUSED_MUT, - UNCONDITIONAL_RECURSION, - SINGLE_USE_LIFETIMES, - UNUSED_LIFETIMES, - UNUSED_LABELS, - TYVAR_BEHIND_RAW_POINTER, - ELIDED_LIFETIMES_IN_PATHS, - BARE_TRAIT_OBJECTS, - ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, - UNSTABLE_NAME_COLLISIONS, - IRREFUTABLE_LET_PATTERNS, - INTRA_DOC_LINK_RESOLUTION_FAILURE, - MISSING_DOC_CODE_EXAMPLES, - PRIVATE_DOC_TESTS, - WHERE_CLAUSES_OBJECT_SAFETY, - PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - MACRO_USE_EXTERN_CRATE, - MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, - ILL_FORMED_ATTRIBUTE_INPUT, - META_VARIABLE_MISUSE, - DEPRECATED_IN_FUTURE, - AMBIGUOUS_ASSOCIATED_ITEMS, - MUTABLE_BORROW_RESERVATION_CONFLICT, - INDIRECT_STRUCTURAL_MATCH, - SOFT_UNSTABLE, - ] -} - // this could be a closure, but then implementing derive traits // becomes hacky (and it gets allocated) #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] @@ -646,5 +581,3 @@ impl BuiltinLintDiagnostics { } } } - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {} diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e1350ad03a10f..7e07c42faf147 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -17,8 +17,6 @@ use self::TargetLint::*; use crate::hir; -use crate::hir::def_id::{CrateNum, DefId}; -use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::lint::{EarlyLintPassObject, LateLintPassObject}; @@ -26,7 +24,7 @@ use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use crate::middle::privacy::AccessLevels; use crate::session::Session; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; -use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt}; use crate::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; @@ -619,150 +617,6 @@ impl LintContext for EarlyContext<'_> { } } -impl<'a, 'tcx> LateContext<'a, 'tcx> { - pub fn current_lint_root(&self) -> hir::HirId { - self.last_node_with_lint_attrs - } - - /// Check if a `DefId`'s path matches the given absolute type path usage. - /// - /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`; - /// inherent `impl` blocks are matched with the name of the type. - /// - /// # Examples - /// - /// ```rust,ignore (no context or def id available) - /// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) { - /// // The given `def_id` is that of an `Option` type - /// } - /// ``` - pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool { - let names = self.get_def_path(def_id); - - names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| a == b) - } - - /// Gets the absolute path of `def_id` as a vector of `Symbol`. - /// - /// # Examples - /// - /// ```rust,ignore (no context or def id available) - /// let def_path = cx.get_def_path(def_id); - /// if let &[sym::core, sym::option, sym::Option] = &def_path[..] { - /// // The given `def_id` is that of an `Option` type - /// } - /// ``` - pub fn get_def_path(&self, def_id: DefId) -> Vec { - pub struct AbsolutePathPrinter<'tcx> { - pub tcx: TyCtxt<'tcx>, - } - - impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { - type Error = !; - - type Path = Vec; - type Region = (); - type Type = (); - type DynExistential = (); - type Const = (); - - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn print_region(self, _region: ty::Region<'_>) -> Result { - Ok(()) - } - - fn print_type(self, _ty: Ty<'tcx>) -> Result { - Ok(()) - } - - fn print_dyn_existential( - self, - _predicates: &'tcx ty::List>, - ) -> Result { - Ok(()) - } - - fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result { - Ok(()) - } - - fn path_crate(self, cnum: CrateNum) -> Result { - Ok(vec![self.tcx.original_crate_name(cnum)]) - } - - fn path_qualified( - self, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - if trait_ref.is_none() { - if let ty::Adt(def, substs) = self_ty.kind { - return self.print_def_path(def.did, substs); - } - } - - // This shouldn't ever be needed, but just in case: - Ok(vec![match trait_ref { - Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)), - None => Symbol::intern(&format!("<{}>", self_ty)), - }]) - } - - fn path_append_impl( - self, - print_prefix: impl FnOnce(Self) -> Result, - _disambiguated_data: &DisambiguatedDefPathData, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - let mut path = print_prefix(self)?; - - // This shouldn't ever be needed, but just in case: - path.push(match trait_ref { - Some(trait_ref) => Symbol::intern(&format!( - "", - trait_ref.print_only_trait_path(), - self_ty - )), - None => Symbol::intern(&format!("", self_ty)), - }); - - Ok(path) - } - - fn path_append( - self, - print_prefix: impl FnOnce(Self) -> Result, - disambiguated_data: &DisambiguatedDefPathData, - ) -> Result { - let mut path = print_prefix(self)?; - - // Skip `::{{constructor}}` on tuple/unit structs. - match disambiguated_data.data { - DefPathData::Ctor => return Ok(path), - _ => {} - } - - path.push(disambiguated_data.data.as_symbol()); - Ok(path) - } - - fn path_generic_args( - self, - print_prefix: impl FnOnce(Self) -> Result, - _args: &[GenericArg<'tcx>], - ) -> Result { - print_prefix(self) - } - } - - AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap() - } -} - impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> { type Ty = Ty<'tcx>; type TyLayout = Result, LayoutError<'tcx>>; diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 680fb497e4014..659be0743cc5a 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -169,56 +169,6 @@ macro_rules! declare_late_lint_pass { late_lint_methods!(declare_late_lint_pass, [], ['tcx]); -#[macro_export] -macro_rules! expand_combined_late_lint_pass_method { - ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ - $($self.$passes.$name $params;)* - }) -} - -#[macro_export] -macro_rules! expand_combined_late_lint_pass_methods { - ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( - $(fn $name(&mut self, context: &LateContext<'a, 'tcx>, $($param: $arg),*) { - expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*)); - })* - ) -} - -#[macro_export] -macro_rules! declare_combined_late_lint_pass { - ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], [$hir:tt], $methods:tt) => ( - #[allow(non_snake_case)] - $v struct $name { - $($passes: $passes,)* - } - - impl $name { - $v fn new() -> Self { - Self { - $($passes: $constructor,)* - } - } - - $v fn get_lints() -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&$passes::get_lints());)* - lints - } - } - - impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name { - expand_combined_late_lint_pass_methods!([$($passes),*], $methods); - } - - impl LintPass for $name { - fn name(&self) -> &'static str { - panic!() - } - } - ) -} - #[macro_export] macro_rules! early_lint_methods { ($macro:path, $args:tt) => ( @@ -296,56 +246,6 @@ macro_rules! declare_early_lint_pass { early_lint_methods!(declare_early_lint_pass, []); -#[macro_export] -macro_rules! expand_combined_early_lint_pass_method { - ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ - $($self.$passes.$name $params;)* - }) -} - -#[macro_export] -macro_rules! expand_combined_early_lint_pass_methods { - ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( - $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { - expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*)); - })* - ) -} - -#[macro_export] -macro_rules! declare_combined_early_lint_pass { - ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => ( - #[allow(non_snake_case)] - $v struct $name { - $($passes: $passes,)* - } - - impl $name { - $v fn new() -> Self { - Self { - $($passes: $constructor,)* - } - } - - $v fn get_lints() -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&$passes::get_lints());)* - lints - } - } - - impl EarlyLintPass for $name { - expand_combined_early_lint_pass_methods!([$($passes),*], $methods); - } - - impl LintPass for $name { - fn name(&self) -> &'static str { - panic!() - } - } - ) -} - /// A lint pass boxed up as a trait object. pub type EarlyLintPassObject = Box; pub type LateLintPassObject = @@ -369,7 +269,6 @@ pub type LevelSource = (Level, LintSource); pub mod builtin; mod context; -pub mod internal; mod levels; pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder}; diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index a40c5d1697c43..9c2c3ee8289ea 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -18,5 +18,6 @@ rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_index = { path = "../librustc_index" } +rustc_errors = { path = "../librustc_errors" } rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 055b1f8b366d8..d82295fdaa333 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -43,6 +43,7 @@ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, Span}; use syntax::ast::{self, Expr}; use syntax::attr::{self, HasAttrs}; +use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::{self, expr_to_string}; use syntax::ptr::P; @@ -51,6 +52,7 @@ use syntax::visit::FnKind; use rustc::hir::{self, GenericParamKind, PatKind}; +use crate::late::LateContextExt; use crate::nonstandard_style::{method_context, MethodLateContext}; use log::debug; @@ -58,6 +60,72 @@ use log::debug; // hardwired lints from librustc pub use lint::builtin::*; +declare_lint_pass! { + /// Does nothing as a lint pass, but registers some `Lint`s + /// that are used by other parts of the compiler. + HardwiredLints => [ + ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, + EXCEEDING_BITSHIFTS, + UNUSED_IMPORTS, + UNUSED_EXTERN_CRATES, + UNUSED_QUALIFICATIONS, + UNKNOWN_LINTS, + UNUSED_VARIABLES, + UNUSED_ASSIGNMENTS, + DEAD_CODE, + UNREACHABLE_CODE, + UNREACHABLE_PATTERNS, + OVERLAPPING_PATTERNS, + UNUSED_MACROS, + WARNINGS, + UNUSED_FEATURES, + STABLE_FEATURES, + UNKNOWN_CRATE_TYPES, + TRIVIAL_CASTS, + TRIVIAL_NUMERIC_CASTS, + PRIVATE_IN_PUBLIC, + EXPORTED_PRIVATE_DEPENDENCIES, + PUB_USE_OF_PRIVATE_EXTERN_CRATE, + INVALID_TYPE_PARAM_DEFAULT, + CONST_ERR, + RENAMED_AND_REMOVED_LINTS, + SAFE_PACKED_BORROWS, + PATTERNS_IN_FNS_WITHOUT_BODY, + MISSING_FRAGMENT_SPECIFIER, + LATE_BOUND_LIFETIME_ARGUMENTS, + ORDER_DEPENDENT_TRAIT_OBJECTS, + DEPRECATED, + UNUSED_UNSAFE, + UNUSED_MUT, + UNCONDITIONAL_RECURSION, + SINGLE_USE_LIFETIMES, + UNUSED_LIFETIMES, + UNUSED_LABELS, + TYVAR_BEHIND_RAW_POINTER, + ELIDED_LIFETIMES_IN_PATHS, + BARE_TRAIT_OBJECTS, + ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, + UNSTABLE_NAME_COLLISIONS, + IRREFUTABLE_LET_PATTERNS, + INTRA_DOC_LINK_RESOLUTION_FAILURE, + MISSING_DOC_CODE_EXAMPLES, + PRIVATE_DOC_TESTS, + WHERE_CLAUSES_OBJECT_SAFETY, + PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, + MACRO_USE_EXTERN_CRATE, + MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, + ILL_FORMED_ATTRIBUTE_INPUT, + META_VARIABLE_MISUSE, + DEPRECATED_IN_FUTURE, + AMBIGUOUS_ASSOCIATED_ITEMS, + MUTABLE_BORROW_RESERVATION_CONFLICT, + INDIRECT_STRUCTURAL_MATCH, + SOFT_UNSTABLE, + ] +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {} + declare_lint! { WHILE_TRUE, Warn, diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 482a7822b7679..ec36863c8fef5 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -381,3 +381,54 @@ pub fn check_ast_crate( } } } + +#[macro_export] +macro_rules! expand_combined_early_lint_pass_method { + ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ + $($self.$passes.$name $params;)* + }) +} + +#[macro_export] +macro_rules! expand_combined_early_lint_pass_methods { + ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { + expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*)); + })* + ) +} + +#[macro_export] +macro_rules! declare_combined_early_lint_pass { + ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => ( + #[allow(non_snake_case)] + $v struct $name { + $($passes: $passes,)* + } + + impl $name { + $v fn new() -> Self { + Self { + $($passes: $constructor,)* + } + } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } + } + + impl EarlyLintPass for $name { + 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/internal.rs b/src/librustc_lint/internal.rs similarity index 98% rename from src/librustc/lint/internal.rs rename to src/librustc_lint/internal.rs index f7dfbab92e613..14019734fe808 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -1,12 +1,12 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use crate::hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; -use crate::lint::{ +use rustc::hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; +use rustc::lint::{ EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass, }; -use errors::Applicability; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Applicability; use rustc_session::declare_tool_lint; use rustc_span::symbol::{sym, Symbol}; use syntax::ast::{Ident, Item, ItemKind}; diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index 1248cfd3bc269..cdb1f27eb9dde 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -15,16 +15,18 @@ //! for all lint attributes. use rustc::hir; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::intravisit as hir_visit; use rustc::hir::intravisit::Visitor; +use rustc::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use rustc::lint::LateContext; use rustc::lint::LintPass; use rustc::lint::{LateLintPass, LateLintPassObject}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use rustc::util::common::time; use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; +use rustc_span::symbol::Symbol; use rustc_span::Span; use std::slice; use syntax::ast; @@ -32,6 +34,180 @@ use syntax::ast; use log::debug; use syntax::walk_list; +pub(crate) trait LateContextExt { + fn current_lint_root(&self) -> hir::HirId; + + /// Check if a `DefId`'s path matches the given absolute type path usage. + /// + /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`; + /// inherent `impl` blocks are matched with the name of the type. + /// + /// # Examples + /// + /// ```rust,ignore (no context or def id available) + /// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) { + /// // The given `def_id` is that of an `Option` type + /// } + /// ``` + fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool; + + /// Gets the absolute path of `def_id` as a vector of `Symbol`. + /// + /// # Examples + /// + /// ```rust,ignore (no context or def id available) + /// let def_path = cx.get_def_path(def_id); + /// if let &[sym::core, sym::option, sym::Option] = &def_path[..] { + /// // The given `def_id` is that of an `Option` type + /// } + /// ``` + fn get_def_path(&self, def_id: DefId) -> Vec; +} + +impl<'a, 'tcx> LateContextExt for LateContext<'a, 'tcx> { + fn current_lint_root(&self) -> hir::HirId { + self.last_node_with_lint_attrs + } + + /// Check if a `DefId`'s path matches the given absolute type path usage. + /// + /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`; + /// inherent `impl` blocks are matched with the name of the type. + /// + /// # Examples + /// + /// ```rust,ignore (no context or def id available) + /// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) { + /// // The given `def_id` is that of an `Option` type + /// } + /// ``` + fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool { + let names = self.get_def_path(def_id); + + names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| a == b) + } + + /// Gets the absolute path of `def_id` as a vector of `Symbol`. + /// + /// # Examples + /// + /// ```rust,ignore (no context or def id available) + /// let def_path = cx.get_def_path(def_id); + /// if let &[sym::core, sym::option, sym::Option] = &def_path[..] { + /// // The given `def_id` is that of an `Option` type + /// } + /// ``` + fn get_def_path(&self, def_id: DefId) -> Vec { + pub struct AbsolutePathPrinter<'tcx> { + pub tcx: TyCtxt<'tcx>, + } + + impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { + type Error = !; + + type Path = Vec; + type Region = (); + type Type = (); + type DynExistential = (); + type Const = (); + + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn print_region(self, _region: ty::Region<'_>) -> Result { + Ok(()) + } + + fn print_type(self, _ty: Ty<'tcx>) -> Result { + Ok(()) + } + + fn print_dyn_existential( + self, + _predicates: &'tcx ty::List>, + ) -> Result { + Ok(()) + } + + fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result { + Ok(()) + } + + fn path_crate(self, cnum: CrateNum) -> Result { + Ok(vec![self.tcx.original_crate_name(cnum)]) + } + + fn path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + if trait_ref.is_none() { + if let ty::Adt(def, substs) = self_ty.kind { + return self.print_def_path(def.did, substs); + } + } + + // This shouldn't ever be needed, but just in case: + Ok(vec![match trait_ref { + Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)), + None => Symbol::intern(&format!("<{}>", self_ty)), + }]) + } + + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + let mut path = print_prefix(self)?; + + // This shouldn't ever be needed, but just in case: + path.push(match trait_ref { + Some(trait_ref) => Symbol::intern(&format!( + "", + trait_ref.print_only_trait_path(), + self_ty + )), + None => Symbol::intern(&format!("", self_ty)), + }); + + Ok(path) + } + + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result { + let mut path = print_prefix(self)?; + + // Skip `::{{constructor}}` on tuple/unit structs. + match disambiguated_data.data { + DefPathData::Ctor => return Ok(path), + _ => {} + } + + path.push(disambiguated_data.data.as_symbol()); + Ok(path) + } + + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, + _args: &[GenericArg<'tcx>], + ) -> Result { + print_prefix(self) + } + } + + AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap() + } +} + macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); }) } @@ -471,3 +647,54 @@ pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( }, ); } + +#[macro_export] +macro_rules! expand_combined_late_lint_pass_method { + ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ + $($self.$passes.$name $params;)* + }) +} + +#[macro_export] +macro_rules! expand_combined_late_lint_pass_methods { + ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(fn $name(&mut self, context: &LateContext<'a, 'tcx>, $($param: $arg),*) { + expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*)); + })* + ) +} + +#[macro_export] +macro_rules! declare_combined_late_lint_pass { + ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], [$hir:tt], $methods:tt) => ( + #[allow(non_snake_case)] + $v struct $name { + $($passes: $passes,)* + } + + impl $name { + $v fn new() -> Self { + Self { + $($passes: $constructor,)* + } + } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } + } + + impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name { + 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!() + } + } + ) +} diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2a3b90f8c93b4..5558493268ebc 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -14,6 +14,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(never_type)] #![feature(nll)] #![recursion_limit = "256"] @@ -25,6 +26,7 @@ extern crate rustc_session; mod array_into_iter; pub mod builtin; mod early; +mod internal; mod late; mod levels; mod non_ascii_idents; @@ -54,7 +56,6 @@ use builtin::*; use non_ascii_idents::*; use nonstandard_style::*; use redundant_semicolon::*; -use rustc::lint::internal::*; use types::*; use unused::*; @@ -390,6 +391,7 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { } fn register_internals(store: &mut lint::LintStore) { + use internal::*; store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index cb22039327e07..72ac0eded2091 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -253,8 +253,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let cpath = Some(input.clone()); let input = Input::File(input); - let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name; - let warnings_lint_name = lint::builtin::WARNINGS.name; + let intra_link_resolution_failure_name = + rustc_lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name; + let warnings_lint_name = rustc_lint::builtin::WARNINGS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; @@ -272,7 +273,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); let lints = || { - lint::builtin::HardwiredLints::get_lints() + rustc_lint::builtin::HardwiredLints::get_lints() .into_iter() .chain(rustc_lint::SoftLints::get_lints().into_iter()) };