@@ -5,7 +5,9 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
5
5
use rustc_ast:: { Item , ItemKind } ;
6
6
use rustc_data_structures:: fx:: FxHashMap ;
7
7
use rustc_errors:: Applicability ;
8
+ use rustc_hir:: def:: Res ;
8
9
use rustc_hir:: { GenericArg , HirId , MutTy , Mutability , Path , PathSegment , QPath , Ty , TyKind } ;
10
+ use rustc_middle:: ty;
9
11
use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass} ;
10
12
use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
11
13
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
@@ -177,11 +179,31 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> bool {
177
179
fn is_ty_or_ty_ctxt ( cx : & LateContext < ' _ > , ty : & Ty < ' _ > ) -> Option < String > {
178
180
if let TyKind :: Path ( qpath) = & ty. kind {
179
181
if let QPath :: Resolved ( _, path) = qpath {
180
- let did = path. res . opt_def_id ( ) ?;
181
- if cx. tcx . is_diagnostic_item ( sym:: Ty , did) {
182
- return Some ( format ! ( "Ty{}" , gen_args( path. segments. last( ) . unwrap( ) ) ) ) ;
183
- } else if cx. tcx . is_diagnostic_item ( sym:: TyCtxt , did) {
184
- return Some ( format ! ( "TyCtxt{}" , gen_args( path. segments. last( ) . unwrap( ) ) ) ) ;
182
+ match path. res {
183
+ Res :: Def ( _, did) => {
184
+ if cx. tcx . is_diagnostic_item ( sym:: Ty , did) {
185
+ return Some ( format ! ( "Ty{}" , gen_args( path. segments. last( ) . unwrap( ) ) ) ) ;
186
+ } else if cx. tcx . is_diagnostic_item ( sym:: TyCtxt , did) {
187
+ return Some ( format ! ( "TyCtxt{}" , gen_args( path. segments. last( ) . unwrap( ) ) ) ) ;
188
+ }
189
+ }
190
+ // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
191
+ Res :: SelfTy ( None , Some ( ( did, _) ) ) => {
192
+ if let ty:: Adt ( adt, substs) = cx. tcx . type_of ( did) . kind ( ) {
193
+ if cx. tcx . is_diagnostic_item ( sym:: Ty , adt. did ) {
194
+ // NOTE: This path is currently unreachable as `Ty<'tcx>` is
195
+ // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
196
+ // is not actually allowed.
197
+ //
198
+ // I(@lcnr) still kept this branch in so we don't miss this
199
+ // if we ever change it in the future.
200
+ return Some ( format ! ( "Ty<{}>" , substs[ 0 ] ) ) ;
201
+ } else if cx. tcx . is_diagnostic_item ( sym:: TyCtxt , adt. did ) {
202
+ return Some ( format ! ( "TyCtxt<{}>" , substs[ 0 ] ) ) ;
203
+ }
204
+ }
205
+ }
206
+ _ => ( ) ,
185
207
}
186
208
}
187
209
}
0 commit comments