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
This commit is contained in:
commit
50d4aebc7a
@ -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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
33
src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
Normal file
33
src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
Normal file
@ -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() {}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user