Skip to content

Commit 714f282

Browse files
authored
Rollup merge of rust-lang#59316 - flip1995:internal_lints_take_2, r=oli-obk
Internal lints take 2 cc rust-lang#58701 cc rust-lang#49509 TODO: Add `#![warn(internal)]` to crates (and fix violations) Crates depending on `rustc_data_structures` - [x] librustc_resolve - [x] librustc_driver - [x] librustc_passes - [x] librustc_metadata - [x] librustc_interface - [x] librustc_save_analysis - [x] librustc_lint - [x] librustc - [x] librustc_incremental - [x] librustc_codegen_utils - [x] libarena - [x] librustc_target - [x] librustc_allocator - [x] librustc_privacy - [x] librustc_traits - [x] librustc_borrowck - [x] libsyntax - [x] librustc_codegen_ssa - [x] libsyntax_ext - [x] librustc_errors - [x] librustc_mir - [x] libsyntax_pos - [x] librustc_typeck Crates with `feature(rustc_private)` Excluding crates, which are already in the list above. Also excluding tools and tests. - [ ] ~~libstd~~ - [x] libfmt_macros - [x] librustdoc r? @oli-obk
2 parents f8673e0 + c81ce06 commit 714f282

File tree

58 files changed

+684
-103
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+684
-103
lines changed

src/bootstrap/bin/rustc.rs

+5
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ fn main() {
316316
}
317317
}
318318

319+
// This is required for internal lints.
320+
if stage != "0" {
321+
cmd.arg("-Zunstable-options");
322+
}
323+
319324
// Force all crates compiled by this compiler to (a) be unstable and (b)
320325
// allow the `rustc_private` feature to link to other unstable crates
321326
// also in the sysroot. We also do this for host crates, since those

src/libarena/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
test(no_crate_inject, attr(deny(warnings))))]
1313

1414
#![deny(rust_2018_idioms)]
15+
#![cfg_attr(not(stage0), deny(internal))]
1516

1617
#![feature(alloc)]
1718
#![feature(core_intrinsics)]

src/libfmt_macros/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
test(attr(deny(warnings))))]
1010

1111
#![deny(rust_2018_idioms)]
12+
#![cfg_attr(not(stage0), deny(internal))]
1213

1314
#![feature(nll)]
1415
#![feature(rustc_private)]

src/librustc/hir/def_id.rs

+104-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use crate::ty;
2-
use crate::ty::TyCtxt;
3-
use crate::hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX;
1+
use crate::ty::{self, print::Printer, subst::Kind, Ty, TyCtxt};
2+
use crate::hir::map::definitions::{DisambiguatedDefPathData, FIRST_FREE_HIGH_DEF_INDEX};
43
use rustc_data_structures::indexed_vec::Idx;
54
use serialize;
65
use std::fmt;
76
use std::u32;
7+
use syntax::symbol::{LocalInternedString, Symbol};
88

99
newtype_index! {
1010
pub struct CrateId {
@@ -252,6 +252,107 @@ impl DefId {
252252
format!("module `{}`", tcx.def_path_str(*self))
253253
}
254254
}
255+
256+
/// Check if a `DefId`'s path matches the given absolute type path usage.
257+
// Uplifted from rust-lang/rust-clippy
258+
pub fn match_path<'a, 'tcx>(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, path: &[&str]) -> bool {
259+
pub struct AbsolutePathPrinter<'a, 'tcx> {
260+
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
261+
}
262+
263+
impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> {
264+
type Error = !;
265+
266+
type Path = Vec<LocalInternedString>;
267+
type Region = ();
268+
type Type = ();
269+
type DynExistential = ();
270+
271+
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
272+
self.tcx
273+
}
274+
275+
fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
276+
Ok(())
277+
}
278+
279+
fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
280+
Ok(())
281+
}
282+
283+
fn print_dyn_existential(
284+
self,
285+
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
286+
) -> Result<Self::DynExistential, Self::Error> {
287+
Ok(())
288+
}
289+
290+
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
291+
Ok(vec![self.tcx.original_crate_name(cnum).as_str()])
292+
}
293+
294+
fn path_qualified(
295+
self,
296+
self_ty: Ty<'tcx>,
297+
trait_ref: Option<ty::TraitRef<'tcx>>,
298+
) -> Result<Self::Path, Self::Error> {
299+
if trait_ref.is_none() {
300+
if let ty::Adt(def, substs) = self_ty.sty {
301+
return self.print_def_path(def.did, substs);
302+
}
303+
}
304+
305+
// This shouldn't ever be needed, but just in case:
306+
Ok(vec![match trait_ref {
307+
Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)).as_str(),
308+
None => Symbol::intern(&format!("<{}>", self_ty)).as_str(),
309+
}])
310+
}
311+
312+
fn path_append_impl(
313+
self,
314+
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
315+
_disambiguated_data: &DisambiguatedDefPathData,
316+
self_ty: Ty<'tcx>,
317+
trait_ref: Option<ty::TraitRef<'tcx>>,
318+
) -> Result<Self::Path, Self::Error> {
319+
let mut path = print_prefix(self)?;
320+
321+
// This shouldn't ever be needed, but just in case:
322+
path.push(match trait_ref {
323+
Some(trait_ref) => {
324+
Symbol::intern(&format!("<impl {} for {}>", trait_ref, self_ty)).as_str()
325+
},
326+
None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(),
327+
});
328+
329+
Ok(path)
330+
}
331+
332+
fn path_append(
333+
self,
334+
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
335+
disambiguated_data: &DisambiguatedDefPathData,
336+
) -> Result<Self::Path, Self::Error> {
337+
let mut path = print_prefix(self)?;
338+
path.push(disambiguated_data.data.as_interned_str().as_str());
339+
Ok(path)
340+
}
341+
342+
fn path_generic_args(
343+
self,
344+
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
345+
_args: &[Kind<'tcx>],
346+
) -> Result<Self::Path, Self::Error> {
347+
print_prefix(self)
348+
}
349+
}
350+
351+
let names = AbsolutePathPrinter { tcx }.print_def_path(self, &[]).unwrap();
352+
353+
names.len() == path.len()
354+
&& names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
355+
}
255356
}
256357

257358
impl serialize::UseSpecializedEncodable for DefId {}

src/librustc/ich/hcx.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::session::Session;
99

1010
use std::cmp::Ord;
1111
use std::hash as std_hash;
12-
use std::collections::HashMap;
1312
use std::cell::RefCell;
1413

1514
use syntax::ast;
@@ -394,13 +393,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for DelimSpan {
394393
}
395394
}
396395

397-
pub fn hash_stable_trait_impls<'a, 'gcx, W, R>(
396+
pub fn hash_stable_trait_impls<'a, 'gcx, W>(
398397
hcx: &mut StableHashingContext<'a>,
399398
hasher: &mut StableHasher<W>,
400399
blanket_impls: &[DefId],
401-
non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>)
402-
where W: StableHasherResult,
403-
R: std_hash::BuildHasher,
400+
non_blanket_impls: &FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>)
401+
where W: StableHasherResult
404402
{
405403
{
406404
let mut blanket_impls: SmallVec<[_; 8]> = blanket_impls

src/librustc/infer/error_reporting/mod.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use crate::hir::Node;
5656
use crate::middle::region;
5757
use crate::traits::{ObligationCause, ObligationCauseCode};
5858
use crate::ty::error::TypeError;
59-
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TyKind, TypeFoldable};
59+
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
6060
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
6161
use std::{cmp, fmt};
6262
use syntax_pos::{Pos, Span};
@@ -1094,14 +1094,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10941094
(_, false, _) => {
10951095
if let Some(exp_found) = exp_found {
10961096
let (def_id, ret_ty) = match exp_found.found.sty {
1097-
TyKind::FnDef(def, _) => {
1097+
ty::FnDef(def, _) => {
10981098
(Some(def), Some(self.tcx.fn_sig(def).output()))
10991099
}
11001100
_ => (None, None),
11011101
};
11021102

11031103
let exp_is_struct = match exp_found.expected.sty {
1104-
TyKind::Adt(def, _) => def.is_struct(),
1104+
ty::Adt(def, _) => def.is_struct(),
11051105
_ => false,
11061106
};
11071107

@@ -1140,8 +1140,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11401140
diag: &mut DiagnosticBuilder<'tcx>,
11411141
) {
11421142
match (&exp_found.expected.sty, &exp_found.found.sty) {
1143-
(TyKind::Adt(exp_def, exp_substs), TyKind::Ref(_, found_ty, _)) => {
1144-
if let TyKind::Adt(found_def, found_substs) = found_ty.sty {
1143+
(ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) => {
1144+
if let ty::Adt(found_def, found_substs) = found_ty.sty {
11451145
let path_str = format!("{:?}", exp_def);
11461146
if exp_def == &found_def {
11471147
let opt_msg = "you can convert from `&Option<T>` to `Option<&T>` using \
@@ -1164,17 +1164,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11641164
let mut show_suggestion = true;
11651165
for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) {
11661166
match exp_ty.sty {
1167-
TyKind::Ref(_, exp_ty, _) => {
1167+
ty::Ref(_, exp_ty, _) => {
11681168
match (&exp_ty.sty, &found_ty.sty) {
1169-
(_, TyKind::Param(_)) |
1170-
(_, TyKind::Infer(_)) |
1171-
(TyKind::Param(_), _) |
1172-
(TyKind::Infer(_), _) => {}
1169+
(_, ty::Param(_)) |
1170+
(_, ty::Infer(_)) |
1171+
(ty::Param(_), _) |
1172+
(ty::Infer(_), _) => {}
11731173
_ if ty::TyS::same_type(exp_ty, found_ty) => {}
11741174
_ => show_suggestion = false,
11751175
};
11761176
}
1177-
TyKind::Param(_) | TyKind::Infer(_) => {}
1177+
ty::Param(_) | ty::Infer(_) => {}
11781178
_ => show_suggestion = false,
11791179
}
11801180
}

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
3030

3131
#![deny(rust_2018_idioms)]
32+
#![cfg_attr(not(stage0), deny(internal))]
3233
#![allow(explicit_outlives_requirements)]
3334

3435
#![feature(arbitrary_self_types)]

src/librustc/lint/internal.rs

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
2+
//! Clippy.
3+
4+
use crate::hir::{HirId, Path, PathSegment, QPath, Ty, TyKind};
5+
use crate::lint::{
6+
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
7+
};
8+
use errors::Applicability;
9+
use rustc_data_structures::fx::FxHashMap;
10+
use syntax::ast::Ident;
11+
12+
declare_lint! {
13+
pub DEFAULT_HASH_TYPES,
14+
Allow,
15+
"forbid HashMap and HashSet and suggest the FxHash* variants"
16+
}
17+
18+
pub struct DefaultHashTypes {
19+
map: FxHashMap<String, String>,
20+
}
21+
22+
impl DefaultHashTypes {
23+
pub fn new() -> Self {
24+
let mut map = FxHashMap::default();
25+
map.insert("HashMap".to_string(), "FxHashMap".to_string());
26+
map.insert("HashSet".to_string(), "FxHashSet".to_string());
27+
Self { map }
28+
}
29+
}
30+
31+
impl LintPass for DefaultHashTypes {
32+
fn get_lints(&self) -> LintArray {
33+
lint_array!(DEFAULT_HASH_TYPES)
34+
}
35+
36+
fn name(&self) -> &'static str {
37+
"DefaultHashTypes"
38+
}
39+
}
40+
41+
impl EarlyLintPass for DefaultHashTypes {
42+
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
43+
let ident_string = ident.to_string();
44+
if let Some(replace) = self.map.get(&ident_string) {
45+
let msg = format!(
46+
"Prefer {} over {}, it has better performance",
47+
replace, ident_string
48+
);
49+
let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg);
50+
db.span_suggestion(
51+
ident.span,
52+
"use",
53+
replace.to_string(),
54+
Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
55+
);
56+
db.note(&format!(
57+
"a `use rustc_data_structures::fx::{}` may be necessary",
58+
replace
59+
))
60+
.emit();
61+
}
62+
}
63+
}
64+
65+
declare_lint! {
66+
pub USAGE_OF_TY_TYKIND,
67+
Allow,
68+
"Usage of `ty::TyKind` outside of the `ty::sty` module"
69+
}
70+
71+
pub struct TyKindUsage;
72+
73+
impl LintPass for TyKindUsage {
74+
fn get_lints(&self) -> LintArray {
75+
lint_array!(USAGE_OF_TY_TYKIND)
76+
}
77+
78+
fn name(&self) -> &'static str {
79+
"TyKindUsage"
80+
}
81+
}
82+
83+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
84+
fn check_path(&mut self, cx: &LateContext<'_, '_>, path: &'tcx Path, _: HirId) {
85+
let segments = path.segments.iter().rev().skip(1).rev();
86+
87+
if let Some(last) = segments.last() {
88+
let span = path.span.with_hi(last.ident.span.hi());
89+
if lint_ty_kind_usage(cx, last) {
90+
cx.struct_span_lint(USAGE_OF_TY_TYKIND, span, "usage of `ty::TyKind::<kind>`")
91+
.span_suggestion(
92+
span,
93+
"try using ty::<kind> directly",
94+
"ty".to_string(),
95+
Applicability::MaybeIncorrect, // ty maybe needs an import
96+
)
97+
.emit();
98+
}
99+
}
100+
}
101+
102+
fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
103+
if let TyKind::Path(qpath) = &ty.node {
104+
if let QPath::Resolved(_, path) = qpath {
105+
if let Some(last) = path.segments.iter().last() {
106+
if lint_ty_kind_usage(cx, last) {
107+
cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, "usage of `ty::TyKind`")
108+
.help("try using `ty::Ty` instead")
109+
.emit();
110+
}
111+
}
112+
}
113+
}
114+
}
115+
}
116+
117+
fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
118+
if segment.ident.as_str() == "TyKind" {
119+
if let Some(def) = segment.def {
120+
if let Some(did) = def.opt_def_id() {
121+
return did.match_path(cx.tcx, &["rustc", "ty", "sty", "TyKind"]);
122+
}
123+
}
124+
}
125+
126+
false
127+
}

src/librustc/lint/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ impl_stable_hash_for!(enum self::LintSource {
574574
pub type LevelSource = (Level, LintSource);
575575

576576
pub mod builtin;
577+
pub mod internal;
577578
mod context;
578579
mod levels;
579580

src/librustc/mir/tcx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
3636
pub fn field_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, f: &Field) -> Ty<'tcx>
3737
{
3838
let answer = match self.ty.sty {
39-
ty::TyKind::Adt(adt_def, substs) => {
39+
ty::Adt(adt_def, substs) => {
4040
let variant_def = match self.variant_index {
4141
None => adt_def.non_enum_variant(),
4242
Some(variant_index) => {

0 commit comments

Comments
 (0)