Skip to content

Commit 272000c

Browse files
committed
Auto merge of #60317 - flip1995:internal_lints, r=oli-obk
Internal lints: usage_of_qualified_ty & ty_pass_by_reference Closes #59952 Implements internal lints: - `USAGE_OF_QUALIFIED_TY` - `TY_PASS_BY_REFERENCE` r? @oli-obk
2 parents bdfdbcd + 2e5f0b3 commit 272000c

Some content is hidden

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

52 files changed

+480
-170
lines changed

src/librustc/infer/error_reporting/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
690690
name: String,
691691
sub: ty::subst::SubstsRef<'tcx>,
692692
pos: usize,
693-
other_ty: &Ty<'tcx>,
693+
other_ty: Ty<'tcx>,
694694
) {
695695
// `value` and `other_value` hold two incomplete type representation for display.
696696
// `name` is the path of both types being compared. `sub`
@@ -768,10 +768,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
768768
path: String,
769769
sub: ty::subst::SubstsRef<'tcx>,
770770
other_path: String,
771-
other_ty: &Ty<'tcx>,
771+
other_ty: Ty<'tcx>,
772772
) -> Option<()> {
773773
for (i, ta) in sub.types().enumerate() {
774-
if &ta == other_ty {
774+
if ta == other_ty {
775775
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
776776
return Some(());
777777
}
@@ -839,7 +839,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
839839
/// Compares two given types, eliding parts that are the same between them and highlighting
840840
/// relevant differences, and return two representation of those types for highlighted printing.
841841
fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) {
842-
fn equals<'tcx>(a: &Ty<'tcx>, b: &Ty<'tcx>) -> bool {
842+
fn equals<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
843843
match (&a.sty, &b.sty) {
844844
(a, b) if *a == *b => true,
845845
(&ty::Int(_), &ty::Infer(ty::InferTy::IntVar(_)))
@@ -1099,7 +1099,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10991099
}
11001100
};
11011101

1102-
let span = cause.span(&self.tcx);
1102+
let span = cause.span(self.tcx);
11031103

11041104
diag.span_label(span, terr.to_string());
11051105
if let Some((sp, msg)) = secondary_span {
@@ -1233,7 +1233,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12331233
trace, terr
12341234
);
12351235

1236-
let span = trace.cause.span(&self.tcx);
1236+
let span = trace.cause.span(self.tcx);
12371237
let failure_code = trace.cause.as_failure_code(terr);
12381238
let mut diag = match failure_code {
12391239
FailureCode::Error0317(failure_str) => {

src/librustc/infer/error_reporting/need_type_info.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use errors::DiagnosticBuilder;
1111

1212
struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
1313
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
14-
target_ty: &'a Ty<'tcx>,
14+
target_ty: Ty<'tcx>,
1515
hir_map: &'a hir::map::Map<'gcx>,
1616
found_local_pattern: Option<&'gcx Pat>,
1717
found_arg_pattern: Option<&'gcx Pat>,
@@ -26,7 +26,7 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
2626
Some(ty) => {
2727
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
2828
ty.walk().any(|inner_ty| {
29-
inner_ty == *self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
29+
inner_ty == self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
3030
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
3131
self.infcx
3232
.type_variables
@@ -68,10 +68,10 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
6868
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
6969
pub fn extract_type_name(
7070
&self,
71-
ty: &'a Ty<'tcx>,
71+
ty: Ty<'tcx>,
7272
highlight: Option<ty::print::RegionHighlightMode>,
7373
) -> String {
74-
if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty {
74+
if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
7575
let ty_vars = self.type_variables.borrow();
7676
if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
7777
*ty_vars.var_origin(ty_vid) {
@@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
102102

103103
let mut local_visitor = FindLocalByTypeVisitor {
104104
infcx: &self,
105-
target_ty: &ty,
105+
target_ty: ty,
106106
hir_map: &self.tcx.hir(),
107107
found_local_pattern: None,
108108
found_arg_pattern: None,

src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
193193
);
194194

195195
let mut err = self.tcx().sess.struct_span_err(
196-
cause.span(&self.tcx()),
196+
cause.span(self.tcx()),
197197
&format!(
198198
"implementation of `{}` is not general enough",
199199
self.tcx().def_path_str(trait_def_id),

src/librustc/infer/nll_relate/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ where
267267
fn relate_projection_ty(
268268
&mut self,
269269
projection_ty: ty::ProjectionTy<'tcx>,
270-
value_ty: ty::Ty<'tcx>,
270+
value_ty: Ty<'tcx>,
271271
) -> Ty<'tcx> {
272272
use crate::infer::type_variable::TypeVariableOrigin;
273273
use crate::traits::WhereClause;

src/librustc/lint/internal.rs

+122-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
22
//! Clippy.
33
4-
use crate::hir::{HirId, Path, PathSegment, QPath, Ty, TyKind};
4+
use crate::hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
55
use crate::lint::{
66
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
77
};
@@ -57,12 +57,28 @@ impl EarlyLintPass for DefaultHashTypes {
5757
declare_lint! {
5858
pub USAGE_OF_TY_TYKIND,
5959
Allow,
60-
"Usage of `ty::TyKind` outside of the `ty::sty` module"
60+
"usage of `ty::TyKind` outside of the `ty::sty` module"
6161
}
6262

63-
declare_lint_pass!(TyKindUsage => [USAGE_OF_TY_TYKIND]);
63+
declare_lint! {
64+
pub TY_PASS_BY_REFERENCE,
65+
Allow,
66+
"passing `Ty` or `TyCtxt` by reference"
67+
}
68+
69+
declare_lint! {
70+
pub USAGE_OF_QUALIFIED_TY,
71+
Allow,
72+
"using `ty::{Ty,TyCtxt}` instead of importing it"
73+
}
74+
75+
declare_lint_pass!(TyTyKind => [
76+
USAGE_OF_TY_TYKIND,
77+
TY_PASS_BY_REFERENCE,
78+
USAGE_OF_QUALIFIED_TY,
79+
]);
6480

65-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
81+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
6682
fn check_path(&mut self, cx: &LateContext<'_, '_>, path: &'tcx Path, _: HirId) {
6783
let segments = path.segments.iter().rev().skip(1).rev();
6884

@@ -82,16 +98,72 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
8298
}
8399

84100
fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
85-
if let TyKind::Path(qpath) = &ty.node {
86-
if let QPath::Resolved(_, path) = qpath {
87-
if let Some(last) = path.segments.iter().last() {
88-
if lint_ty_kind_usage(cx, last) {
89-
cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, "usage of `ty::TyKind`")
90-
.help("try using `ty::Ty` instead")
101+
match &ty.node {
102+
TyKind::Path(qpath) => {
103+
if let QPath::Resolved(_, path) = qpath {
104+
if let Some(last) = path.segments.iter().last() {
105+
if lint_ty_kind_usage(cx, last) {
106+
cx.struct_span_lint(
107+
USAGE_OF_TY_TYKIND,
108+
path.span,
109+
"usage of `ty::TyKind`",
110+
)
111+
.help("try using `Ty` instead")
91112
.emit();
113+
} else {
114+
if ty.span.ctxt().outer().expn_info().is_some() {
115+
return;
116+
}
117+
if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
118+
if path.segments.len() > 1 {
119+
cx.struct_span_lint(
120+
USAGE_OF_QUALIFIED_TY,
121+
path.span,
122+
&format!("usage of qualified `ty::{}`", t),
123+
)
124+
.span_suggestion(
125+
path.span,
126+
"try using it unqualified",
127+
t,
128+
// The import probably needs to be changed
129+
Applicability::MaybeIncorrect,
130+
)
131+
.emit();
132+
}
133+
}
134+
}
135+
}
136+
}
137+
}
138+
TyKind::Rptr(
139+
_,
140+
MutTy {
141+
ty: inner_ty,
142+
mutbl: Mutability::MutImmutable,
143+
},
144+
) => {
145+
if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner_def_id()) {
146+
if cx.tcx.impl_trait_ref(impl_did).is_some() {
147+
return;
92148
}
93149
}
150+
if let Some(t) = is_ty_or_ty_ctxt(cx, &inner_ty) {
151+
cx.struct_span_lint(
152+
TY_PASS_BY_REFERENCE,
153+
ty.span,
154+
&format!("passing `{}` by reference", t),
155+
)
156+
.span_suggestion(
157+
ty.span,
158+
"try passing by value",
159+
t,
160+
// Changing type of function argument
161+
Applicability::MaybeIncorrect,
162+
)
163+
.emit();
164+
}
94165
}
166+
_ => {}
95167
}
96168
}
97169
}
@@ -107,3 +179,43 @@ fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
107179

108180
false
109181
}
182+
183+
fn is_ty_or_ty_ctxt(cx: &LateContext<'_, '_>, ty: &Ty) -> Option<String> {
184+
match &ty.node {
185+
TyKind::Path(qpath) => {
186+
if let QPath::Resolved(_, path) = qpath {
187+
let did = path.def.opt_def_id()?;
188+
if cx.match_def_path(did, &["rustc", "ty", "Ty"]) {
189+
return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
190+
} else if cx.match_def_path(did, &["rustc", "ty", "context", "TyCtxt"]) {
191+
return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
192+
}
193+
}
194+
}
195+
_ => {}
196+
}
197+
198+
None
199+
}
200+
201+
fn gen_args(segment: &PathSegment) -> String {
202+
if let Some(args) = &segment.args {
203+
let lifetimes = args
204+
.args
205+
.iter()
206+
.filter_map(|arg| {
207+
if let GenericArg::Lifetime(lt) = arg {
208+
Some(lt.name.ident().to_string())
209+
} else {
210+
None
211+
}
212+
})
213+
.collect::<Vec<_>>();
214+
215+
if !lifetimes.is_empty() {
216+
return format!("<{}>", lifetimes.join(", "));
217+
}
218+
}
219+
220+
String::new()
221+
}

src/librustc/middle/exported_symbols.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
44
StableHasherResult};
55
use std::cmp;
66
use std::mem;
7-
use crate::ty;
7+
use crate::ty::{self, TyCtxt};
88
use crate::ty::subst::SubstsRef;
99

1010
/// The SymbolExportLevel of a symbols specifies from which kinds of crates
@@ -39,7 +39,7 @@ pub enum ExportedSymbol<'tcx> {
3939

4040
impl<'tcx> ExportedSymbol<'tcx> {
4141
pub fn symbol_name(&self,
42-
tcx: ty::TyCtxt<'_, 'tcx, '_>)
42+
tcx: TyCtxt<'_, 'tcx, '_>)
4343
-> ty::SymbolName {
4444
match *self {
4545
ExportedSymbol::NonGeneric(def_id) => {
@@ -55,7 +55,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
5555
}
5656

5757
pub fn compare_stable(&self,
58-
tcx: ty::TyCtxt<'_, 'tcx, '_>,
58+
tcx: TyCtxt<'_, 'tcx, '_>,
5959
other: &ExportedSymbol<'tcx>)
6060
-> cmp::Ordering {
6161
match *self {
@@ -92,7 +92,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
9292
}
9393
}
9494

95-
pub fn metadata_symbol_name(tcx: ty::TyCtxt<'_, '_, '_>) -> String {
95+
pub fn metadata_symbol_name(tcx: TyCtxt<'_, '_, '_>) -> String {
9696
format!("rust_metadata_{}_{}",
9797
tcx.original_crate_name(LOCAL_CRATE),
9898
tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())

src/librustc/mir/mono.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub enum MonoItem<'tcx> {
1818
}
1919

2020
impl<'tcx> MonoItem<'tcx> {
21-
pub fn size_estimate<'a>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> usize {
21+
pub fn size_estimate<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> usize {
2222
match *self {
2323
MonoItem::Fn(instance) => {
2424
// Estimate the size of a function based on how many statements
@@ -144,7 +144,7 @@ impl<'tcx> CodegenUnit<'tcx> {
144144
base_n::encode(hash, base_n::CASE_INSENSITIVE)
145145
}
146146

147-
pub fn estimate_size<'a>(&mut self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) {
147+
pub fn estimate_size<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
148148
// Estimate the size of a codegen unit as (approximately) the number of MIR
149149
// statements it corresponds to.
150150
self.size_estimate = Some(self.items.keys().map(|mi| mi.size_estimate(tcx)).sum());

src/librustc/mir/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ macro_rules! make_mir_visitor {
198198
}
199199

200200
fn visit_ty(&mut self,
201-
ty: & $($mutability)? Ty<'tcx>,
201+
ty: $(& $mutability)? Ty<'tcx>,
202202
_: TyContext) {
203203
self.super_ty(ty);
204204
}
@@ -864,7 +864,7 @@ macro_rules! make_mir_visitor {
864864
self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
865865
}
866866

867-
fn super_ty(&mut self, _ty: & $($mutability)? Ty<'tcx>) {
867+
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
868868
}
869869

870870
fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {

src/librustc/traits/auto_trait.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ pub struct AutoTraitInfo<'cx> {
4949
}
5050

5151
pub struct AutoTraitFinder<'a, 'tcx: 'a> {
52-
tcx: &'a TyCtxt<'a, 'tcx, 'tcx>,
52+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
5353
}
5454

5555
impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
56-
pub fn new(tcx: &'a TyCtxt<'a, 'tcx, 'tcx>) -> Self {
56+
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
5757
AutoTraitFinder { tcx }
5858
}
5959

@@ -291,7 +291,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
291291
infcx: &InferCtxt<'b, 'tcx, 'c>,
292292
ty_did: DefId,
293293
trait_did: DefId,
294-
ty: ty::Ty<'c>,
294+
ty: Ty<'c>,
295295
param_env: ty::ParamEnv<'c>,
296296
user_env: ty::ParamEnv<'c>,
297297
fresh_preds: &mut FxHashSet<ty::Predicate<'c>>,
@@ -661,7 +661,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
661661
T: Iterator<Item = Obligation<'cx, ty::Predicate<'cx>>>,
662662
>(
663663
&self,
664-
ty: ty::Ty<'_>,
664+
ty: Ty<'_>,
665665
nested: T,
666666
computed_preds: &'b mut FxHashSet<ty::Predicate<'cx>>,
667667
fresh_preds: &'b mut FxHashSet<ty::Predicate<'cx>>,

src/librustc/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12421242
found: ty::PolyTraitRef<'tcx>)
12431243
-> DiagnosticBuilder<'tcx>
12441244
{
1245-
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
1245+
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
12461246
trait_ref: &ty::TraitRef<'tcx>) -> String {
12471247
let inputs = trait_ref.substs.type_at(1);
12481248
let sig = if let ty::Tuple(inputs) = inputs.sty {

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub struct ObligationCause<'tcx> {
138138
}
139139

140140
impl<'tcx> ObligationCause<'tcx> {
141-
pub fn span<'a, 'gcx>(&self, tcx: &TyCtxt<'a, 'gcx, 'tcx>) -> Span {
141+
pub fn span<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Span {
142142
match self.code {
143143
ObligationCauseCode::CompareImplMethodObligation { .. } |
144144
ObligationCauseCode::MainFunctionType |

0 commit comments

Comments
 (0)