]> git.lizzy.rs Git - rust.git/commitdiff
extend `is_ty_or_ty_ctxt` to self types
authorBastian Kauschke <bastian_kauschke@hotmail.de>
Sat, 19 Sep 2020 10:34:31 +0000 (12:34 +0200)
committerBastian Kauschke <bastian_kauschke@hotmail.de>
Sat, 19 Sep 2020 10:41:12 +0000 (12:41 +0200)
compiler/rustc_lint/src/internal.rs

index 100e555f299ae691bb9e3e35530dbe02cafb9348..2bac4517409b42e4e2fc5c4fcd6eca9cc6129596 100644 (file)
@@ -5,7 +5,9 @@
 use rustc_ast::{Item, ItemKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
+use rustc_hir::def::Res;
 use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
+use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -177,11 +179,25 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> bool {
 fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
     if let TyKind::Path(qpath) = &ty.kind {
         if let QPath::Resolved(_, path) = qpath {
-            let did = path.res.opt_def_id()?;
-            if cx.tcx.is_diagnostic_item(sym::Ty, did) {
-                return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
-            } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
-                return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
+            match path.res {
+                Res::Def(_, did) => {
+                    if cx.tcx.is_diagnostic_item(sym::Ty, did) {
+                        return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
+                    } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
+                        return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
+                    }
+                }
+                // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
+                Res::SelfTy(None, Some((did, _))) => {
+                    if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
+                        if cx.tcx.is_diagnostic_item(sym::Ty, adt.did) {
+                            return Some(format!("Ty<{}>", substs[0]));
+                        } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, adt.did) {
+                            return Some(format!("TyCtxt<{}>", substs[0]));
+                        }
+                    }
+                }
+                _ => (),
             }
         }
     }