about summary refs log tree commit diff
diff options
context:
space:
mode:
authorecstatic-morse <ecstaticmorse@gmail.com>2020-09-21 20:40:57 -0700
committerGitHub <noreply@github.com>2020-09-21 20:40:57 -0700
commit50d4aebc7a85c3e0285bcdd622ccdbef33929638 (patch)
tree771a848c5e03a76d7c20741abefc1ba7eeec5a67
parentdcf4d1f2beefa7bebdbfb31e4774cefa901928b7 (diff)
parent8fc782afc204adf1d2d6c1e0f13b1242aef396d4 (diff)
downloadrust-50d4aebc7a85c3e0285bcdd622ccdbef33929638.tar.gz
rust-50d4aebc7a85c3e0285bcdd622ccdbef33929638.zip
Rollup merge of #76914 - lcnr:path-no-more, r=ecstatic-morse
extend `Ty` and `TyCtxt` lints to self types

blocked on #76891

r? @ecstatic-morse cc @Aaron1011
-rw-r--r--compiler/rustc_lint/src/internal.rs32
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/error.rs4
-rw-r--r--src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs33
-rw-r--r--src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr20
5 files changed, 83 insertions, 8 deletions
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 100e555f299..c2d98b8e4ad 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -5,7 +5,9 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
 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,31 @@ 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) {
+                            // NOTE: This path is currently unreachable as `Ty<'tcx>` is
+                            // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
+                            // is not actually allowed.
+                            //
+                            // I(@lcnr) still kept this branch in so we don't miss this
+                            // if we ever change it in the future.
+                            return Some(format!("Ty<{}>", substs[0]));
+                        } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, adt.did) {
+                            return Some(format!("TyCtxt<{}>", substs[0]));
+                        }
+                    }
+                }
+                _ => (),
             }
         }
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index cd8f12a4f35..ccc8ffd9a9c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1179,7 +1179,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
     }
 
-    pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
+    pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
         let cname = self.crate_name(LOCAL_CRATE).as_str();
         self.sess.consider_optimizing(&cname, msg)
     }
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 8a9d9830cc4..342a37cadba 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -850,7 +850,7 @@ fn foo(&self) -> Self::T { String::new() }
     /// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
     /// requirement, provide a strucuted suggestion to constrain it to a given type `ty`.
     fn constrain_generic_bound_associated_type_structured_suggestion(
-        &self,
+        self,
         db: &mut DiagnosticBuilder<'_>,
         trait_ref: &ty::TraitRef<'tcx>,
         bounds: hir::GenericBounds<'_>,
@@ -874,7 +874,7 @@ fn foo(&self) -> Self::T { String::new() }
     /// Given a span corresponding to a bound, provide a structured suggestion to set an
     /// associated type to a given type `ty`.
     fn constrain_associated_type_structured_suggestion(
-        &self,
+        self,
         db: &mut DiagnosticBuilder<'_>,
         span: Span,
         assoc: &ty::AssocItem,
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
new file mode 100644
index 00000000000..f58446d5592
--- /dev/null
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
@@ -0,0 +1,33 @@
+// NOTE: This test doesn't actually require `fulldeps`
+// so we could instead use it as an `ui` test.
+//
+// Considering that all other `internal-lints` are tested here
+// this seems like the cleaner solution though.
+#![feature(rustc_attrs)]
+#![deny(rustc::ty_pass_by_reference)]
+#![allow(unused)]
+
+#[rustc_diagnostic_item = "TyCtxt"]
+struct TyCtxt<'tcx> {
+    inner: &'tcx (),
+}
+
+impl<'tcx> TyCtxt<'tcx> {
+    fn by_value(self) {} // OK
+    fn by_ref(&self) {} //~ ERROR passing `TyCtxt<'tcx>` by reference
+}
+
+
+struct TyS<'tcx> {
+    inner: &'tcx (),
+}
+
+#[rustc_diagnostic_item = "Ty"]
+type Ty<'tcx> = &'tcx TyS<'tcx>;
+
+impl<'tcx> TyS<'tcx> {
+    fn by_value(self: Ty<'tcx>) {}
+    fn by_ref(self: &Ty<'tcx>) {} //~ ERROR passing `Ty<'tcx>` by reference
+}
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
new file mode 100644
index 00000000000..b846b30f4ed
--- /dev/null
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
@@ -0,0 +1,20 @@
+error: passing `TyCtxt<'tcx>` by reference
+  --> $DIR/pass_ty_by_ref_self.rs:17:15
+   |
+LL |     fn by_ref(&self) {}
+   |               ^^^^^ help: try passing by value: `TyCtxt<'tcx>`
+   |
+note: the lint level is defined here
+  --> $DIR/pass_ty_by_ref_self.rs:7:9
+   |
+LL | #![deny(rustc::ty_pass_by_reference)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: passing `Ty<'tcx>` by reference
+  --> $DIR/pass_ty_by_ref_self.rs:30:21
+   |
+LL |     fn by_ref(self: &Ty<'tcx>) {}
+   |                     ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
+
+error: aborting due to 2 previous errors
+