refactor: add an enum DerefAdjustKind in favor of Option<OverloadedDeref>

This commit is contained in:
Frank King 2026-01-30 11:06:27 +08:00
parent 01eba5596e
commit cdee2fbff5
13 changed files with 35 additions and 37 deletions

View file

@ -10,7 +10,7 @@ use rustc_hir::attrs::AttributeKind;
use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind, find_attr};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_middle::ty::{
self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt, TypeckResults,
};
@ -236,7 +236,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
.iter()
.rev()
.fold(0, |acc, adjustment| match adjustment.kind {
Adjust::Deref(Some(_)) => acc + 1,
Adjust::Deref(DerefAdjustKind::Overloaded(_)) => acc + 1,
Adjust::Deref(_) if acc > 0 => acc + 1,
_ => acc,
})

View file

@ -24,7 +24,7 @@ use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::{Expr, ExprKind, LangItem, RustcVersion, find_attr};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};
use rustc_middle::ty::{self, GenericArg, List, TraitRef, Ty, TyCtxt, Upcast};
use rustc_session::impl_lint_pass;
use rustc_span::edition::Edition::Edition2021;
@ -704,12 +704,12 @@ where
let mut n_needed = 0;
loop {
if let Some(Adjustment {
kind: Adjust::Deref(overloaded_deref),
kind: Adjust::Deref(deref),
target,
}) = iter.next()
{
n_total += 1;
if overloaded_deref.is_some() {
if let DerefAdjustKind::Overloaded(..) = deref {
n_needed = n_total;
}
ty = *target;

View file

@ -12,7 +12,7 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
use rustc_hir::{Closure, Expr, ExprKind, HirId, LetStmt, Mutability, UnOp};
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_span::Symbol;
use rustc_span::symbol::sym;
@ -88,7 +88,7 @@ fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExp
.typeck_results()
.expr_adjustments(e)
.iter()
.any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
.any(|a| matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(..))))
{
// Custom deref impls need to borrow the whole value as it's captured by reference
can_move = false;

View file

@ -10,7 +10,7 @@ use rustc_hir::{self as hir, LangItem};
use rustc_lint::LateContext;
use rustc_middle::mir::{Mutability, Pinnedness};
use rustc_middle::ty;
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_span::symbol::Ident;
use rustc_span::{Span, sym};
@ -73,7 +73,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_
&& cx.tcx.lang_items().clone_trait() == Some(trait_id)
// no autoderefs
&& !cx.typeck_results().expr_adjustments(obj).iter()
.any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
.any(|a| matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(..))))
{
let obj_ty = cx.typeck_results().expr_ty(obj);
if let ty::Ref(_, ty, mutability) = obj_ty.kind() {

View file

@ -58,7 +58,7 @@ pub(super) fn check(
.iter()
.map(|x| &x.kind)
.collect::<Box<[_]>>()
&& let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj
&& let [ty::adjustment::Adjust::Deref(ty::adjustment::DerefAdjustKind::Builtin), ty::adjustment::Adjust::Borrow(_)] = *adj
&& let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap()
&& let Some(method_name) = cx.tcx.get_diagnostic_name(method_did)
{

View file

@ -4,7 +4,7 @@ use rustc_ast::BorrowKind;
use rustc_errors::{Applicability, Diag};
use rustc_hir::{Expr, ExprKind, Node, QPath};
use rustc_lint::LateContext;
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_span::sym;
use super::SWAP_WITH_TEMPORARY;
@ -47,7 +47,7 @@ impl<'tcx> ArgKind<'tcx> {
&& let adjustments = cx.typeck_results().expr_adjustments(arg)
&& adjustments
.first()
.is_some_and(|adj| matches!(adj.kind, Adjust::Deref(None)))
.is_some_and(|adj| matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Builtin)))
&& adjustments
.last()
.is_some_and(|adj| matches!(adj.kind, Adjust::Borrow(_)))

View file

@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::{self, ExistentialPredicate, Ty};
use rustc_span::{Span, sym};
@ -58,7 +58,7 @@ pub(super) fn check(cx: &LateContext<'_>, receiver: &Expr<'_>, call_span: Span)
|diag| {
let derefs = recv_adjusts
.iter()
.filter(|adj| matches!(adj.kind, Adjust::Deref(None)))
.filter(|adj| matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Builtin)))
.count();
diag.note(

View file

@ -14,7 +14,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind, OverloadedDeref};
use rustc_middle::ty::{
self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
};
@ -78,7 +78,7 @@ fn check_addr_of_expr(
// For matching uses of `Cow::from`
[
Adjustment {
kind: Adjust::Deref(None),
kind: Adjust::Deref(DerefAdjustKind::Builtin),
target: referent_ty,
},
Adjustment {
@ -89,7 +89,7 @@ fn check_addr_of_expr(
// For matching uses of arrays
| [
Adjustment {
kind: Adjust::Deref(None),
kind: Adjust::Deref(DerefAdjustKind::Builtin),
target: referent_ty,
},
Adjustment {
@ -104,11 +104,11 @@ fn check_addr_of_expr(
// For matching everything else
| [
Adjustment {
kind: Adjust::Deref(None),
kind: Adjust::Deref(DerefAdjustKind::Builtin),
target: referent_ty,
},
Adjustment {
kind: Adjust::Deref(Some(OverloadedDeref { .. })),
kind: Adjust::Deref(DerefAdjustKind::Overloaded(OverloadedDeref { .. })),
..
},
Adjustment {

View file

@ -7,7 +7,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{self as hir, LangItem, Node};
use rustc_lint::LateContext;
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_middle::ty::{Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::{Span, Symbol, sym};
@ -161,7 +161,7 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
&& cx.tcx.lang_items().clone_trait().is_some_and(|id| id == trait_id)
// no autoderefs
&& !cx.typeck_results().expr_adjustments(obj).iter()
.any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
.any(|a| matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(..))))
&& obj.res_local_id() == Some(local_id)
{
true

View file

@ -33,7 +33,7 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::mir::{ConstValue, UnevaluatedConst};
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};
use rustc_middle::ty::{
self, AliasTyKind, EarlyBinder, GenericArgs, GenericArgsRef, Instance, Ty, TyCtxt, TypeFolder, TypeSuperFoldable,
TypeckResults, TypingEnv,
@ -907,7 +907,7 @@ fn does_adjust_borrow(adjust: &Adjustment<'_>) -> Option<BorrowCause> {
match adjust.kind {
Adjust::Borrow(_) => Some(BorrowCause::AutoBorrow),
// Custom deref calls `<T as Deref>::deref(&x)` resulting in a borrow.
Adjust::Deref(Some(_)) => Some(BorrowCause::AutoDeref),
Adjust::Deref(DerefAdjustKind::Overloaded(_)) => Some(BorrowCause::AutoDeref),
// All other adjustments read the value.
_ => None,
}

View file

@ -19,7 +19,7 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, QPath, UnOp};
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_span::Symbol;
use std::{cmp, ops};
@ -132,7 +132,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
.typeck_results()
.expr_adjustments(e)
.iter()
.any(|adj| matches!(adj.kind, Adjust::Deref(Some(_))))
.any(|adj| matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Overloaded(_))))
{
self.eagerness |= NoChange;
return;
@ -211,12 +211,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
// Custom `Deref` impl might have side effects
ExprKind::Unary(UnOp::Deref, e)
if self
.cx
.typeck_results()
.expr_ty(e)
.builtin_deref(true)
.is_none() =>
if self.cx.typeck_results().expr_ty(e).builtin_deref(true).is_none() =>
{
self.eagerness |= NoChange;
},

View file

@ -108,7 +108,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::lint::LevelAndSource;
use rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, PointerCoercion};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, DerefAdjustKind, PointerCoercion};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt,
@ -477,8 +477,8 @@ pub fn expr_custom_deref_adjustment(cx: &LateContext<'_>, e: &Expr<'_>) -> Optio
.expr_adjustments(e)
.iter()
.find_map(|a| match a.kind {
Adjust::Deref(Some(d)) => Some(Some(d.mutbl)),
Adjust::Deref(None) => None,
Adjust::Deref(DerefAdjustKind::Overloaded(d)) => Some(Some(d.mutbl)),
Adjust::Deref(DerefAdjustKind::Builtin) => None,
_ => Some(None),
})
.and_then(|x| x)
@ -3537,7 +3537,9 @@ pub fn expr_adjustment_requires_coercion(cx: &LateContext<'_>, expr: &Expr<'_>)
cx.typeck_results().expr_adjustments(expr).iter().any(|adj| {
matches!(
adj.kind,
Adjust::Deref(Some(_)) | Adjust::Pointer(PointerCoercion::Unsize) | Adjust::NeverToAny
Adjust::Deref(DerefAdjustKind::Overloaded(_))
| Adjust::Pointer(PointerCoercion::Unsize)
| Adjust::NeverToAny
)
})
}

View file

@ -17,7 +17,7 @@ use rustc_lint::LateContext;
use rustc_middle::mir::ConstValue;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::traits::EvaluationResult;
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};
use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::{
self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg,
@ -1345,6 +1345,7 @@ pub fn get_field_idx_by_name(ty: Ty<'_>, name: Symbol) -> Option<usize> {
pub fn adjust_derefs_manually_drop<'tcx>(adjustments: &'tcx [Adjustment<'tcx>], mut ty: Ty<'tcx>) -> bool {
adjustments.iter().any(|a| {
let ty = mem::replace(&mut ty, a.target);
matches!(a.kind, Adjust::Deref(Some(op)) if op.mutbl == Mutability::Mut) && is_manually_drop(ty)
matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(op)) if op.mutbl == Mutability::Mut)
&& is_manually_drop(ty)
})
}