Skip to content

Commit 50d4aeb

Browse files
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
2 parents dcf4d1f + 8fc782a commit 50d4aeb

File tree

5 files changed

+83
-8
lines changed

5 files changed

+83
-8
lines changed

compiler/rustc_lint/src/internal.rs

+27-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
55
use rustc_ast::{Item, ItemKind};
66
use rustc_data_structures::fx::FxHashMap;
77
use rustc_errors::Applicability;
8+
use rustc_hir::def::Res;
89
use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
10+
use rustc_middle::ty;
911
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
1012
use rustc_span::hygiene::{ExpnKind, MacroKind};
1113
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -177,11 +179,31 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> bool {
177179
fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
178180
if let TyKind::Path(qpath) = &ty.kind {
179181
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+
_ => (),
185207
}
186208
}
187209
}

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ impl<'tcx> TyCtxt<'tcx> {
11791179
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
11801180
}
11811181

1182-
pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
1182+
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
11831183
let cname = self.crate_name(LOCAL_CRATE).as_str();
11841184
self.sess.consider_optimizing(&cname, msg)
11851185
}

compiler/rustc_middle/src/ty/error.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ fn foo(&self) -> Self::T { String::new() }
850850
/// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
851851
/// requirement, provide a strucuted suggestion to constrain it to a given type `ty`.
852852
fn constrain_generic_bound_associated_type_structured_suggestion(
853-
&self,
853+
self,
854854
db: &mut DiagnosticBuilder<'_>,
855855
trait_ref: &ty::TraitRef<'tcx>,
856856
bounds: hir::GenericBounds<'_>,
@@ -874,7 +874,7 @@ fn foo(&self) -> Self::T { String::new() }
874874
/// Given a span corresponding to a bound, provide a structured suggestion to set an
875875
/// associated type to a given type `ty`.
876876
fn constrain_associated_type_structured_suggestion(
877-
&self,
877+
self,
878878
db: &mut DiagnosticBuilder<'_>,
879879
span: Span,
880880
assoc: &ty::AssocItem,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// NOTE: This test doesn't actually require `fulldeps`
2+
// so we could instead use it as an `ui` test.
3+
//
4+
// Considering that all other `internal-lints` are tested here
5+
// this seems like the cleaner solution though.
6+
#![feature(rustc_attrs)]
7+
#![deny(rustc::ty_pass_by_reference)]
8+
#![allow(unused)]
9+
10+
#[rustc_diagnostic_item = "TyCtxt"]
11+
struct TyCtxt<'tcx> {
12+
inner: &'tcx (),
13+
}
14+
15+
impl<'tcx> TyCtxt<'tcx> {
16+
fn by_value(self) {} // OK
17+
fn by_ref(&self) {} //~ ERROR passing `TyCtxt<'tcx>` by reference
18+
}
19+
20+
21+
struct TyS<'tcx> {
22+
inner: &'tcx (),
23+
}
24+
25+
#[rustc_diagnostic_item = "Ty"]
26+
type Ty<'tcx> = &'tcx TyS<'tcx>;
27+
28+
impl<'tcx> TyS<'tcx> {
29+
fn by_value(self: Ty<'tcx>) {}
30+
fn by_ref(self: &Ty<'tcx>) {} //~ ERROR passing `Ty<'tcx>` by reference
31+
}
32+
33+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: passing `TyCtxt<'tcx>` by reference
2+
--> $DIR/pass_ty_by_ref_self.rs:17:15
3+
|
4+
LL | fn by_ref(&self) {}
5+
| ^^^^^ help: try passing by value: `TyCtxt<'tcx>`
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/pass_ty_by_ref_self.rs:7:9
9+
|
10+
LL | #![deny(rustc::ty_pass_by_reference)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: passing `Ty<'tcx>` by reference
14+
--> $DIR/pass_ty_by_ref_self.rs:30:21
15+
|
16+
LL | fn by_ref(self: &Ty<'tcx>) {}
17+
| ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)