2018-12-06 06:50:04 -06:00
|
|
|
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
|
|
|
|
//! Clippy.
|
|
|
|
|
2019-03-21 11:03:45 -05:00
|
|
|
use crate::hir::{HirId, Path, PathSegment, QPath, Ty, TyKind};
|
2019-02-24 10:54:53 -06:00
|
|
|
use crate::lint::{
|
2018-12-06 06:50:04 -06:00
|
|
|
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
|
|
|
|
};
|
2019-02-24 10:54:53 -06:00
|
|
|
use errors::Applicability;
|
2018-12-06 06:50:04 -06:00
|
|
|
use rustc_data_structures::fx::FxHashMap;
|
|
|
|
use syntax::ast::Ident;
|
|
|
|
|
|
|
|
declare_lint! {
|
|
|
|
pub DEFAULT_HASH_TYPES,
|
2019-03-16 08:59:34 -05:00
|
|
|
Allow,
|
2018-12-06 06:50:04 -06:00
|
|
|
"forbid HashMap and HashSet and suggest the FxHash* variants"
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct DefaultHashTypes {
|
|
|
|
map: FxHashMap<String, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DefaultHashTypes {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
let mut map = FxHashMap::default();
|
|
|
|
map.insert("HashMap".to_string(), "FxHashMap".to_string());
|
|
|
|
map.insert("HashSet".to_string(), "FxHashSet".to_string());
|
|
|
|
Self { map }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-04 12:23:11 -05:00
|
|
|
impl_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
|
2018-12-06 06:50:04 -06:00
|
|
|
|
|
|
|
impl EarlyLintPass for DefaultHashTypes {
|
|
|
|
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
|
|
|
|
let ident_string = ident.to_string();
|
|
|
|
if let Some(replace) = self.map.get(&ident_string) {
|
|
|
|
let msg = format!(
|
|
|
|
"Prefer {} over {}, it has better performance",
|
|
|
|
replace, ident_string
|
|
|
|
);
|
|
|
|
let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg);
|
2019-02-24 10:54:53 -06:00
|
|
|
db.span_suggestion(
|
2018-12-06 06:50:04 -06:00
|
|
|
ident.span,
|
|
|
|
"use",
|
|
|
|
replace.to_string(),
|
|
|
|
Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
|
|
|
|
);
|
|
|
|
db.note(&format!(
|
|
|
|
"a `use rustc_data_structures::fx::{}` may be necessary",
|
|
|
|
replace
|
|
|
|
))
|
|
|
|
.emit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
declare_lint! {
|
|
|
|
pub USAGE_OF_TY_TYKIND,
|
2019-03-16 08:59:34 -05:00
|
|
|
Allow,
|
2018-12-06 06:50:04 -06:00
|
|
|
"Usage of `ty::TyKind` outside of the `ty::sty` module"
|
|
|
|
}
|
|
|
|
|
2019-04-04 12:23:11 -05:00
|
|
|
declare_lint_pass!(TyKindUsage => [USAGE_OF_TY_TYKIND]);
|
2018-12-06 06:50:04 -06:00
|
|
|
|
|
|
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
|
2019-02-28 10:34:01 -06:00
|
|
|
fn check_path(&mut self, cx: &LateContext<'_, '_>, path: &'tcx Path, _: HirId) {
|
2019-03-21 11:03:45 -05:00
|
|
|
let segments = path.segments.iter().rev().skip(1).rev();
|
|
|
|
|
|
|
|
if let Some(last) = segments.last() {
|
|
|
|
let span = path.span.with_hi(last.ident.span.hi());
|
|
|
|
if lint_ty_kind_usage(cx, last) {
|
|
|
|
cx.struct_span_lint(USAGE_OF_TY_TYKIND, span, "usage of `ty::TyKind::<kind>`")
|
|
|
|
.span_suggestion(
|
|
|
|
span,
|
|
|
|
"try using ty::<kind> directly",
|
|
|
|
"ty".to_string(),
|
|
|
|
Applicability::MaybeIncorrect, // ty maybe needs an import
|
|
|
|
)
|
|
|
|
.emit();
|
2018-12-06 06:50:04 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
|
|
|
|
if let TyKind::Path(qpath) = &ty.node {
|
|
|
|
if let QPath::Resolved(_, path) = qpath {
|
|
|
|
if let Some(last) = path.segments.iter().last() {
|
2019-03-21 11:03:45 -05:00
|
|
|
if lint_ty_kind_usage(cx, last) {
|
|
|
|
cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, "usage of `ty::TyKind`")
|
|
|
|
.help("try using `ty::Ty` instead")
|
|
|
|
.emit();
|
2018-12-06 06:50:04 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-21 11:03:45 -05:00
|
|
|
|
|
|
|
fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
|
|
|
|
if segment.ident.as_str() == "TyKind" {
|
|
|
|
if let Some(def) = segment.def {
|
|
|
|
if let Some(did) = def.opt_def_id() {
|
2019-04-07 12:47:54 -05:00
|
|
|
return cx.match_def_path(did, &["rustc", "ty", "sty", "TyKind"]);
|
2019-03-21 11:03:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
false
|
|
|
|
}
|