Address review comments

This commit is contained in:
Tom Hvitved
2026-01-09 11:14:23 +01:00
parent fef00c1668
commit 6028cd6636
4 changed files with 35 additions and 44 deletions

View File

@@ -1538,7 +1538,7 @@ private module MethodResolution {
pragma[nomagic]
Type getACandidateReceiverTypeAtNoBorrow(DerefChain derefChain, TypePath path) {
result = this.getReceiverTypeAt(path) and
derefChain = ""
derefChain.isEmpty()
or
exists(DerefImplItemNode impl, DerefChain suffix |
result = ImplicitDeref::getDereferencedCandidateReceiverType(this, impl, suffix, path) and
@@ -1647,7 +1647,7 @@ private module MethodResolution {
or
// needed for the `hasNoCompatibleTarget` check in
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
derefChain = ""
derefChain.isEmpty()
) and
strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and
n = -1
@@ -1680,7 +1680,7 @@ private module MethodResolution {
or
// needed for the `hasNoCompatibleTarget` check in
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
derefChain = ""
derefChain.isEmpty()
) and
strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and
n = -1
@@ -1830,7 +1830,7 @@ private module MethodResolution {
* as long as the method cannot be resolved in an earlier candidate type, and possibly
* applying a borrow at the end.
*
* The string `derefChain` encodes the sequence of dereferences, and `borrows` indicates
* The parameter `derefChain` encodes the sequence of dereferences, and `borrows` indicates
* whether a borrow has been applied.
*
* [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
@@ -1865,8 +1865,8 @@ private module MethodResolution {
/**
* Gets a method that this call resolves to after having applied a sequence of
* dereferences and possibly a borrow on the receiver type, encoded in the string
* `derefChain` and the enum `borrow`.
* dereferences and possibly a borrow on the receiver type, encoded in `derefChain`
* and `borrow`.
*/
pragma[nomagic]
Method resolveCallTarget(ImplOrTraitItemNode i, DerefChain derefChain, BorrowKind borrow) {
@@ -1881,9 +1881,7 @@ private module MethodResolution {
* and borrowed according to `derefChain` and `borrow`, in order to be able to
* resolve the call target.
*/
predicate argumentHasImplicitDerefChainBorrow(
AstNode arg, DerefChain derefChain, BorrowKind borrow
) {
predicate argumentHasImplicitDerefChainBorrow(Expr arg, DerefChain derefChain, BorrowKind borrow) {
exists(this.resolveCallTarget(_, derefChain, borrow)) and
arg = this.getArg(any(ArgumentPosition pos | pos.isSelf())) and
not (derefChain.isEmpty() and borrow.isNoBorrow())
@@ -2025,7 +2023,7 @@ private module MethodResolution {
}
override predicate argumentHasImplicitDerefChainBorrow(
AstNode arg, DerefChain derefChain, BorrowKind borrow
Expr arg, DerefChain derefChain, BorrowKind borrow
) {
exists(ArgumentPosition pos, boolean isMutable |
this.implicitBorrowAt(pos, isMutable) and
@@ -2161,7 +2159,7 @@ private module MethodResolution {
MkMethodCallDerefCand(MethodCall mc, DerefChain derefChain) {
mc.supportsAutoDerefAndBorrow() and
mc.hasNoCompatibleTargetMutBorrow(derefChain) and
exists(mc.getACandidateReceiverTypeAtNoBorrow(derefChain, _))
exists(mc.getACandidateReceiverTypeAtNoBorrow(derefChain, TypePath::nil()))
}
/** A method call with a dereference chain. */
@@ -2579,6 +2577,13 @@ private Type inferMethodCallTypeNonSelf(AstNode n, boolean isReturn, TypePath pa
)
}
/**
* Gets the type of `n` at `path` after applying `derefChain` and `borrow`,
* where `n` is the `self` argument of a method call.
*
* The predicate recursively pops the head of `derefChain` until it becomes
* empty, at which point the inferred type can be applied back to `n`.
*/
pragma[nomagic]
private Type inferMethodCallTypeSelf(
AstNode n, DerefChain derefChain, BorrowKind borrow, TypePath path
@@ -2604,14 +2609,14 @@ private Type inferMethodCallTypeSelf(
t0 = inferMethodCallTypeSelf(n, derefChain0, borrow, path0) and
derefChain0.isCons(impl, derefChain) and
borrow.isNoBorrow() and
selfParamType = impl.resolveSelfParamTypeStrippedAt(selfPath)
selfParamType = impl.resolveSelfTypeAt(selfPath)
|
result = selfParamType and
path = selfPath and
not result instanceof TypeParameter
or
exists(TypeParameter tp, TypePath pathToTypeParam, TypePath suffix |
impl.returnTypeStrippedMentionsTypeParameterAt(tp, pathToTypeParam) and
impl.targetTypeParameterAt(tp, pathToTypeParam) and
path0 = pathToTypeParam.appendInverse(suffix) and
result = t0 and
path = selfPath.append(suffix)
@@ -3911,13 +3916,13 @@ cached
private module Cached {
/** Holds if `n` is implicitly dereferenced and/or borrowed. */
cached
predicate implicitDerefChainBorrow(AstNode n, DerefChain derefChain, boolean borrow) {
predicate implicitDerefChainBorrow(Expr e, DerefChain derefChain, boolean borrow) {
exists(BorrowKind bk |
any(MethodResolution::MethodCall mc).argumentHasImplicitDerefChainBorrow(n, derefChain, bk) and
any(MethodResolution::MethodCall mc).argumentHasImplicitDerefChainBorrow(e, derefChain, bk) and
if bk.isNoBorrow() then borrow = false else borrow = true
)
or
n =
e =
any(FieldExpr fe |
exists(resolveStructFieldExpr(fe, derefChain))
or

View File

@@ -309,7 +309,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
}
pragma[nomagic]
private Type resolveImplSelfTypeAt(Impl i, TypePath path) {
Type resolveImplSelfTypeAt(Impl i, TypePath path) {
result = i.getSelfTy().(TypeMention).resolveTypeAt(path)
}

View File

@@ -16,30 +16,16 @@ class DerefImplItemNode extends ImplItemNode {
/** Gets the `deref` function in this `Deref` impl block. */
Function getDerefFunction() { result = this.getAssocItem("deref") }
private SelfParam getSelfParam() { result = this.getDerefFunction().getSelfParam() }
/** Gets the type of the implementing type at `path`. */
Type resolveSelfTypeAt(TypePath path) { result = resolveImplSelfTypeAt(this, path) }
/**
* Resolves the type at `path` of the `self` parameter inside the `deref` function,
* stripped of the leading `&`.
* Holds if the target type of the dereference implemention mentions type
* parameter `tp` at `path`.
*/
pragma[nomagic]
Type resolveSelfParamTypeStrippedAt(TypePath path) {
exists(TypePath path0 |
result = getSelfParamTypeMention(this.getSelfParam()).resolveTypeAt(path0) and
path0.isCons(getRefTypeParameter(false), path)
)
}
/**
* Holds if the return type at `path` of the `deref` function, stripped of the
* leading `&`, mentions type parameter `tp` at `path`.
*/
pragma[nomagic]
predicate returnTypeStrippedMentionsTypeParameterAt(TypeParameter tp, TypePath path) {
exists(TypePath path0 |
tp = getReturnTypeMention(this.getDerefFunction()).resolveTypeAt(path0) and
path0.isCons(getRefTypeParameter(false), path)
)
predicate targetTypeParameterAt(TypeParameter tp, TypePath path) {
tp = this.getAssocItem("Target").(TypeAlias).getTypeRepr().(TypeMention).resolveTypeAt(path)
}
/** Gets the first type parameter of the type being implemented, if any. */

View File

@@ -974,7 +974,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
}
pragma[inline]
private predicate satisfiesConstraintTypeMention1Inline(
private predicate satisfiesConstraintTypeMentionInline(
HasTypeTree tt, TypeAbstraction abs, Type constraint, TypePath path,
TypePath pathToTypeParamInSub
) {
@@ -986,18 +986,18 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
}
pragma[nomagic]
private predicate satisfiesConstraintTypeMention1(
private predicate satisfiesConstraintTypeMention(
HasTypeTree tt, Type constraint, TypePath path, TypePath pathToTypeParamInSub
) {
satisfiesConstraintTypeMention1Inline(tt, _, constraint, path, pathToTypeParamInSub)
satisfiesConstraintTypeMentionInline(tt, _, constraint, path, pathToTypeParamInSub)
}
pragma[nomagic]
private predicate satisfiesConstraintTypeMention1Through(
private predicate satisfiesConstraintTypeMentionThrough(
HasTypeTree tt, TypeAbstraction abs, Type constraint, TypePath path,
TypePath pathToTypeParamInSub
) {
satisfiesConstraintTypeMention1Inline(tt, abs, constraint, path, pathToTypeParamInSub)
satisfiesConstraintTypeMentionInline(tt, abs, constraint, path, pathToTypeParamInSub)
}
pragma[inline]
@@ -1017,7 +1017,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
satisfiesConstraintTypeNonTypeParamInline(tt, _, constraint, path, t)
or
exists(TypePath prefix0, TypePath pathToTypeParamInSub, TypePath suffix |
satisfiesConstraintTypeMention1(tt, constraint, prefix0, pathToTypeParamInSub) and
satisfiesConstraintTypeMention(tt, constraint, prefix0, pathToTypeParamInSub) and
getTypeAt(tt, pathToTypeParamInSub.appendInverse(suffix)) = t and
path = prefix0.append(suffix)
)
@@ -1037,7 +1037,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
satisfiesConstraintTypeNonTypeParamInline(tt, abs, constraint, path, t)
or
exists(TypePath prefix0, TypePath pathToTypeParamInSub, TypePath suffix |
satisfiesConstraintTypeMention1Through(tt, abs, constraint, prefix0, pathToTypeParamInSub) and
satisfiesConstraintTypeMentionThrough(tt, abs, constraint, prefix0, pathToTypeParamInSub) and
getTypeAt(tt, pathToTypeParamInSub.appendInverse(suffix)) = t and
path = prefix0.append(suffix)
)