Merge branch 'main' into redsun82/update-kotlin-2.3.20

This commit is contained in:
Paolo Tranquilli
2026-03-26 14:59:59 +01:00
8 changed files with 271 additions and 45 deletions

View File

@@ -32,7 +32,8 @@ module Impl {
* Gets the `index`th type bound of this type parameter, if any.
*
* This includes type bounds directly on this type parameter and bounds from
* any `where` clauses for this type parameter.
* any `where` clauses for this type parameter, but restricted to `where`
* clauses from the item that declares this type parameter.
*/
TypeBound getTypeBound(int index) {
result =
@@ -43,13 +44,36 @@ module Impl {
* Gets a type bound of this type parameter.
*
* This includes type bounds directly on this type parameter and bounds from
* any `where` clauses for this type parameter.
* any `where` clauses for this type parameter, but restricted to `where`
* clauses from the item that declares this type parameter.
*/
TypeBound getATypeBound() { result = this.getTypeBound(_) }
/** Holds if this type parameter has at least one type bound. */
predicate hasTypeBound() { exists(this.getATypeBound()) }
/**
* Gets the `index`th additional type bound of this type parameter,
* which applies to `constrainingItem`, if any.
*
* For example, in
*
* ```rust
* impl<T> SomeType<T> where T: Clone {
* fn foo() where T: Debug { }
* }
* ```
*
* The constraint `Debug` additionally applies to `T` in `foo`.
*/
TypeBound getAdditionalTypeBound(Item constrainingItem, int index) {
result =
rank[index + 1](int i, int j |
|
this.(TypeParamItemNode).getAdditionalTypeBoundAt(constrainingItem, i, j) order by i, j
)
}
override string toAbbreviatedString() { result = this.getName().getText() }
override string toStringImpl() { result = this.getName().getText() }

View File

@@ -1162,21 +1162,39 @@ private Path getWherePredPath(WherePred wp) { result = wp.getTypeRepr().(PathTyp
final class TypeParamItemNode extends NamedItemNode, TypeItemNode instanceof TypeParam {
/** Gets a where predicate for this type parameter, if any */
pragma[nomagic]
private WherePred getAWherePred() {
private WherePred getAWherePred(ItemNode constrainingItem, boolean isAdditional) {
exists(ItemNode declaringItem |
this = declaringItem.getTypeParam(_) and
this = resolvePath(getWherePredPath(result)) and
result = declaringItem.getADescendant() and
this = declaringItem.getADescendant()
result = constrainingItem.getADescendant()
|
constrainingItem = declaringItem and
isAdditional = false
or
constrainingItem = declaringItem.getADescendant() and
isAdditional = true
)
}
pragma[nomagic]
TypeBound getTypeBoundAt(int i, int j) {
exists(TypeBoundList tbl | result = tbl.getBound(j) |
tbl = super.getTypeBoundList() and i = 0
tbl = super.getTypeBoundList() and
i = 0
or
exists(WherePred wp |
wp = this.getAWherePred() and
wp = this.getAWherePred(_, false) and
tbl = wp.getTypeBoundList() and
wp = any(WhereClause wc).getPredicate(i)
)
)
}
pragma[nomagic]
TypeBound getAdditionalTypeBoundAt(Item constrainingItem, int i, int j) {
exists(TypeBoundList tbl | result = tbl.getBound(j) |
exists(WherePred wp |
wp = this.getAWherePred(constrainingItem, true) and
tbl = wp.getTypeBoundList() and
wp = any(WhereClause wc).getPredicate(i)
)
@@ -1197,6 +1215,15 @@ final class TypeParamItemNode extends NamedItemNode, TypeItemNode instanceof Typ
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
pragma[nomagic]
ItemNode resolveAdditionalBound(ItemNode constrainingItem) {
result =
resolvePath(this.getAdditionalTypeBoundAt(constrainingItem, _, _)
.getTypeRepr()
.(PathTypeRepr)
.getPath())
}
override string getName() { result = TypeParam.super.getName().getText() }
override Namespace getNamespace() { result.isType() }

View File

@@ -87,6 +87,7 @@ private newtype TAssocFunctionType =
}
bindingset[abs, constraint, tp]
pragma[inline_late]
private Type getTraitConstraintTypeAt(
TypeAbstraction abs, TypeMention constraint, TypeParameter tp, TypePath path
) {
@@ -203,7 +204,7 @@ class AssocFunctionType extends MkAssocFunctionType {
}
pragma[nomagic]
Trait getALookupTrait(Type t) {
private Trait getALookupTrait(Type t) {
result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound()
or
result = t.(SelfTypeParameter).getTrait()
@@ -213,23 +214,47 @@ Trait getALookupTrait(Type t) {
result = t.(DynTraitType).getTrait()
}
/**
* Gets the type obtained by substituting in relevant traits in which to do function
* lookup, or `t` itself when no such trait exist.
*/
pragma[nomagic]
Type substituteLookupTraits(Type t) {
private Trait getAdditionalLookupTrait(ItemNode i, Type t) {
result =
t.(TypeParamTypeParameter)
.getTypeParam()
.(TypeParamItemNode)
.resolveAdditionalBound(i.getImmediateParent*())
}
bindingset[n, t]
pragma[inline_late]
Trait getALookupTrait(AstNode n, Type t) {
result = getALookupTrait(t)
or
result = getAdditionalLookupTrait(any(ItemNode i | n = i.getADescendant()), t)
}
bindingset[i, t]
pragma[inline_late]
private Type substituteLookupTraits0(ItemNode i, Type t) {
not exists(getALookupTrait(t)) and
not exists(getAdditionalLookupTrait(i, t)) and
result = t
or
result = TTrait(getALookupTrait(t))
or
result = TTrait(getAdditionalLookupTrait(i, t))
}
/**
* Gets the `n`th `substituteLookupTraits` type for `t`, per some arbitrary order.
* Gets the type obtained by substituting in relevant traits in which to do function
* lookup, or `t` itself when no such trait exists, in the context of AST node `n`.
*/
bindingset[n, t]
pragma[inline_late]
Type substituteLookupTraits(AstNode n, Type t) {
result = substituteLookupTraits0(any(ItemNode i | n = i.getADescendant()), t)
}
pragma[nomagic]
Type getNthLookupType(Type t, int n) {
private Type getNthLookupType(Type t, int n) {
not exists(getALookupTrait(t)) and
result = t and
n = 0
@@ -244,24 +269,66 @@ Type getNthLookupType(Type t, int n) {
}
/**
* Gets the index of the last `substituteLookupTraits` type for `t`.
* Gets the `n`th `substituteLookupTraits` type for `t`, per some arbitrary order,
* in the context of AST node `node`.
*/
bindingset[node, t]
pragma[inline_late]
Type getNthLookupType(AstNode node, Type t, int n) {
exists(ItemNode i | node = i.getADescendant() |
if exists(getAdditionalLookupTrait(i, t))
then
result =
TTrait(rank[n + 1](Trait trait, int j |
trait = [getALookupTrait(t), getAdditionalLookupTrait(i, t)] and
j = idOfTypeParameterAstNode(trait)
|
trait order by j
))
else result = getNthLookupType(t, n)
)
}
pragma[nomagic]
int getLastLookupTypeIndex(Type t) { result = max(int n | exists(getNthLookupType(t, n))) }
private int getLastLookupTypeIndex(Type t) { result = max(int n | exists(getNthLookupType(t, n))) }
/**
* Gets the index of the last `substituteLookupTraits` type for `t`,
* in the context of AST node `node`.
*/
bindingset[node, t]
pragma[inline_late]
int getLastLookupTypeIndex(AstNode node, Type t) {
if exists(getAdditionalLookupTrait(node, t))
then result = max(int n | exists(getNthLookupType(node, t, n)))
else result = getLastLookupTypeIndex(t)
}
signature class ArgSig {
/** Gets the type of this argument at `path`. */
Type getTypeAt(TypePath path);
/** Gets the enclosing item node of this argument. */
ItemNode getEnclosingItemNode();
/** Gets a textual representation of this argument. */
string toString();
/** Gets the location of this argument. */
Location getLocation();
}
/**
* A wrapper around `IsInstantiationOf` which ensures to substitute in lookup
* traits when checking whether argument types are instantiations of function
* types.
*/
module ArgIsInstantiationOf<
HasTypeTreeSig Arg, IsInstantiationOfInputSig<Arg, AssocFunctionType> Input>
{
module ArgIsInstantiationOf<ArgSig Arg, IsInstantiationOfInputSig<Arg, AssocFunctionType> Input> {
final private class ArgFinal = Arg;
private class ArgSubst extends ArgFinal {
Type getTypeAt(TypePath path) {
result = substituteLookupTraits(super.getTypeAt(path)) and
result = substituteLookupTraits0(this.getEnclosingItemNode(), super.getTypeAt(path)) and
not result = TNeverType() and
not result = TUnknownType()
}
@@ -318,6 +385,8 @@ signature module ArgsAreInstantiationsOfInputSig {
Location getLocation();
ItemNode getEnclosingItemNode();
Type getArgType(FunctionPosition pos, TypePath path);
predicate hasTargetCand(ImplOrTraitItemNode i, Function f);
@@ -366,6 +435,8 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
FunctionPosition getPos() { result = pos }
ItemNode getEnclosingItemNode() { result = call.getEnclosingItemNode() }
Location getLocation() { result = call.getLocation() }
Type getTypeAt(TypePath path) { result = call.getArgType(pos, path) }

View File

@@ -1589,7 +1589,7 @@ private module AssocFunctionResolution {
Trait getATrait() {
result = this.getTrait()
or
result = getALookupTrait(getCallExprTypeQualifier(this, TypePath::nil(), _))
result = getALookupTrait(this, getCallExprTypeQualifier(this, TypePath::nil(), _))
}
predicate hasATrait() { exists(this.getATrait()) }
@@ -1639,7 +1639,7 @@ private module AssocFunctionResolution {
private predicate isRelevantSelfPos(FunctionPosition selfPos) {
not this.hasReceiver() and
exists(TypePath strippedTypePath, Type strippedType |
strippedType = substituteLookupTraits(this.getTypeAt(selfPos, strippedTypePath)) and
strippedType = substituteLookupTraits(this, this.getTypeAt(selfPos, strippedTypePath)) and
strippedType != TNeverType() and
strippedType != TUnknownType()
|
@@ -1803,7 +1803,7 @@ private module AssocFunctionResolution {
this.hasNoCompatibleTargetNoBorrowToIndex(selfPos, derefChain, strippedTypePath, strippedType,
n - 1) and
exists(Type t |
t = getNthLookupType(strippedType, n) and
t = getNthLookupType(this, strippedType, n) and
this.hasNoCompatibleTargetCheck(selfPos, derefChain, TNoBorrowKind(), strippedTypePath, t)
)
}
@@ -1816,7 +1816,7 @@ private module AssocFunctionResolution {
predicate hasNoCompatibleTargetNoBorrow(FunctionPosition selfPos, DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleTargetNoBorrowToIndex(selfPos, derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
getLastLookupTypeIndex(this, strippedType))
)
}
@@ -1845,7 +1845,7 @@ private module AssocFunctionResolution {
this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(selfPos, derefChain, strippedTypePath,
strippedType, n - 1) and
exists(Type t |
t = getNthLookupType(strippedType, n) and
t = getNthLookupType(this, strippedType, n) and
this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(),
strippedTypePath, t)
)
@@ -1861,7 +1861,7 @@ private module AssocFunctionResolution {
) {
exists(Type strippedType |
this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(selfPos, derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
getLastLookupTypeIndex(this, strippedType))
)
}
@@ -1880,7 +1880,7 @@ private module AssocFunctionResolution {
this.hasNoCompatibleTargetSharedBorrowToIndex(selfPos, derefChain, strippedTypePath,
strippedType, n - 1) and
exists(Type t |
t = getNthLookupType(strippedType, n) and
t = getNthLookupType(this, strippedType, n) and
this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
strippedTypePath, t)
)
@@ -1895,7 +1895,7 @@ private module AssocFunctionResolution {
predicate hasNoCompatibleTargetSharedBorrow(FunctionPosition selfPos, DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleTargetSharedBorrowToIndex(selfPos, derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
getLastLookupTypeIndex(this, strippedType))
)
}
@@ -1913,7 +1913,7 @@ private module AssocFunctionResolution {
this.hasNoCompatibleTargetMutBorrowToIndex(selfPos, derefChain, strippedTypePath,
strippedType, n - 1) and
exists(Type t |
t = getNthLookupType(strippedType, n) and
t = getNthLookupType(this, strippedType, n) and
this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(true),
strippedTypePath, t)
)
@@ -1928,7 +1928,7 @@ private module AssocFunctionResolution {
predicate hasNoCompatibleTargetMutBorrow(FunctionPosition selfPos, DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleTargetMutBorrowToIndex(selfPos, derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
getLastLookupTypeIndex(this, strippedType))
)
}
@@ -1947,7 +1947,7 @@ private module AssocFunctionResolution {
this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(selfPos, derefChain, strippedTypePath,
strippedType, n - 1) and
exists(Type t |
t = getNthLookupType(strippedType, n) and
t = getNthLookupType(this, strippedType, n) and
this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
strippedTypePath, t)
)
@@ -1964,7 +1964,7 @@ private module AssocFunctionResolution {
) {
exists(Type strippedType |
this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(selfPos, derefChain, _,
strippedType, getLastLookupTypeIndex(strippedType))
strippedType, getLastLookupTypeIndex(this, strippedType))
)
}
@@ -1982,7 +1982,7 @@ private module AssocFunctionResolution {
this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(selfPos, derefChain, strippedTypePath,
strippedType, n - 1) and
exists(Type t |
t = getNthLookupType(strippedType, n) and
t = getNthLookupType(this, strippedType, n) and
this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TSomeBorrowKind(true),
strippedTypePath, t)
)
@@ -1999,7 +1999,7 @@ private module AssocFunctionResolution {
) {
exists(Type strippedType |
this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(selfPos, derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
getLastLookupTypeIndex(this, strippedType))
)
}
@@ -2268,9 +2268,12 @@ private module AssocFunctionResolution {
AssocFunctionCall getAssocFunctionCall() { result = afc_ }
ItemNode getEnclosingItemNode() { result.getADescendant() = afc_ }
Type getTypeAt(TypePath path) {
result =
substituteLookupTraits(afc_.getANonPseudoSelfTypeAt(selfPos_, derefChain, borrow, path))
substituteLookupTraits(afc_,
afc_.getANonPseudoSelfTypeAt(selfPos_, derefChain, borrow, path))
}
pragma[nomagic]
@@ -2404,7 +2407,7 @@ private module AssocFunctionResolution {
CallDerefCand() { this = MkCallDerefCand(afc, selfPos, derefChain) }
Type getTypeAt(TypePath path) {
result = substituteLookupTraits(afc.getSelfTypeAtNoBorrow(selfPos, derefChain, path)) and
result = substituteLookupTraits(afc, afc.getSelfTypeAtNoBorrow(selfPos, derefChain, path)) and
result != TNeverType() and
result != TUnknownType()
}
@@ -2641,6 +2644,8 @@ private module FunctionCallMatchingInput implements MatchingWithEnvironmentInput
Declaration() { this = TFunctionDeclaration(i, f) }
FunctionDeclaration getFunction() { result = f }
predicate isAssocFunction(ImplOrTraitItemNode i_, Function f_) {
i_ = i.asSome() and
f_ = f
@@ -2666,6 +2671,23 @@ private module FunctionCallMatchingInput implements MatchingWithEnvironmentInput
Location getLocation() { result = f.getLocation() }
}
pragma[nomagic]
private TypeMention getAdditionalTypeParameterConstraint(TypeParameter tp, Declaration decl) {
result =
tp.(TypeParamTypeParameter)
.getTypeParam()
.getAdditionalTypeBound(decl.getFunction(), _)
.getTypeRepr()
}
bindingset[decl]
TypeMention getATypeParameterConstraint(TypeParameter tp, Declaration decl) {
result = Input2::getATypeParameterConstraint(tp) and
exists(decl)
or
result = getAdditionalTypeParameterConstraint(tp, decl)
}
class AccessEnvironment = string;
bindingset[derefChain, borrow]

View File

@@ -106,3 +106,27 @@ mod regression3 {
z
}
}
mod regression4 {
trait MyTrait {
// MyTrait::m
fn m(self);
}
impl<T> MyTrait for &T {
// RefAsMyTrait::m
fn m(self) {}
}
struct S<T>(T);
impl<T> S<T> {
fn call_m(self)
where
T: MyTrait,
{
let S(s) = self;
s.m(); // $ target=MyTrait::m
}
}
}

View File

@@ -5083,6 +5083,15 @@ inferCertainType
| regressions.rs:99:22:99:22 | x | | regressions.rs:99:18:99:19 | T2 |
| regressions.rs:103:5:107:5 | { ... } | | regressions.rs:99:18:99:19 | T2 |
| regressions.rs:104:33:104:33 | x | | regressions.rs:99:18:99:19 | T2 |
| regressions.rs:113:14:113:17 | SelfParam | | regressions.rs:111:5:114:5 | Self [trait MyTrait] |
| regressions.rs:118:14:118:17 | SelfParam | | {EXTERNAL LOCATION} | & |
| regressions.rs:118:14:118:17 | SelfParam | TRef | regressions.rs:116:10:116:10 | T |
| regressions.rs:118:20:118:21 | { ... } | | {EXTERNAL LOCATION} | () |
| regressions.rs:124:19:124:22 | SelfParam | | regressions.rs:121:5:121:19 | S |
| regressions.rs:124:19:124:22 | SelfParam | T | regressions.rs:123:10:123:10 | T |
| regressions.rs:127:9:130:9 | { ... } | | {EXTERNAL LOCATION} | () |
| regressions.rs:128:24:128:27 | self | | regressions.rs:121:5:121:19 | S |
| regressions.rs:128:24:128:27 | self | T | regressions.rs:123:10:123:10 | T |
inferType
| associated_types.rs:5:15:5:18 | SelfParam | | associated_types.rs:1:1:2:21 | Wrapper |
| associated_types.rs:5:15:5:18 | SelfParam | A | associated_types.rs:4:6:4:6 | A |
@@ -15135,4 +15144,18 @@ inferType
| regressions.rs:105:33:105:33 | y | T | regressions.rs:99:14:99:15 | T1 |
| regressions.rs:105:33:105:33 | y | T | regressions.rs:99:18:99:19 | T2 |
| regressions.rs:106:9:106:9 | z | | regressions.rs:99:18:99:19 | T2 |
| regressions.rs:113:14:113:17 | SelfParam | | regressions.rs:111:5:114:5 | Self [trait MyTrait] |
| regressions.rs:118:14:118:17 | SelfParam | | {EXTERNAL LOCATION} | & |
| regressions.rs:118:14:118:17 | SelfParam | TRef | regressions.rs:116:10:116:10 | T |
| regressions.rs:118:20:118:21 | { ... } | | {EXTERNAL LOCATION} | () |
| regressions.rs:124:19:124:22 | SelfParam | | regressions.rs:121:5:121:19 | S |
| regressions.rs:124:19:124:22 | SelfParam | T | regressions.rs:123:10:123:10 | T |
| regressions.rs:127:9:130:9 | { ... } | | {EXTERNAL LOCATION} | () |
| regressions.rs:128:17:128:20 | S(...) | | regressions.rs:121:5:121:19 | S |
| regressions.rs:128:17:128:20 | S(...) | T | regressions.rs:123:10:123:10 | T |
| regressions.rs:128:19:128:19 | s | | regressions.rs:123:10:123:10 | T |
| regressions.rs:128:24:128:27 | self | | regressions.rs:121:5:121:19 | S |
| regressions.rs:128:24:128:27 | self | T | regressions.rs:123:10:123:10 | T |
| regressions.rs:129:13:129:13 | s | | regressions.rs:123:10:123:10 | T |
| regressions.rs:129:13:129:17 | s.m() | | {EXTERNAL LOCATION} | () |
testFailures

View File

@@ -416,7 +416,7 @@ impl<T> MyOption<&T> {
}
}
// MISSING: summary=<test::option::MyOption>::cloned;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated
// summary=<test::option::MyOption>::cloned;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated
pub fn cloned(self) -> MyOption<T>
where
T: Clone,
@@ -440,7 +440,7 @@ impl<T> MyOption<&mut T> {
}
}
// MISSING: summary=<test::option::MyOption>::cloned;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated
// summary=<test::option::MyOption>::cloned;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated
pub fn cloned(self) -> MyOption<T>
where
T: Clone,

View File

@@ -1296,6 +1296,15 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
Type getDeclaredType(DeclarationPosition dpos, TypePath path);
}
/**
* Gets a type constraint on the type parameter `tp` that applies to `decl`,
* if any.
*/
bindingset[decl]
default TypeMention getATypeParameterConstraint(TypeParameter tp, Declaration decl) {
result = getATypeParameterConstraint(tp)
}
/**
* A position inside an access. For example, the integer position of an
* argument inside a method call.
@@ -1643,6 +1652,24 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
t = getTypeArgument(a, target, tp, path)
}
/**
* Holds if the type parameter `constrainedTp` occurs in the declared type of
* `target` at `apos` and `pathToConstrained`, and there is a constraint
* `constraint` on `constrainedTp`.
*/
pragma[nomagic]
private predicate typeParameterHasConstraint(
Declaration target, AccessPosition apos, TypeParameter constrainedTp,
TypePath pathToConstrained, TypeMention constraint
) {
exists(DeclarationPosition dpos |
accessDeclarationPositionMatch(apos, dpos) and
constrainedTp = target.getTypeParameter(_) and
constrainedTp = target.getDeclaredType(dpos, pathToConstrained) and
constraint = getATypeParameterConstraint(constrainedTp, target)
)
}
/**
* Holds if the declared type of `target` contains a type parameter at
* `apos` and `pathToConstrained` that must satisfy `constraint` and `tp`
@@ -1665,14 +1692,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
Declaration target, AccessPosition apos, TypePath pathToConstrained, TypeMention constraint,
TypePath pathToTp, TypeParameter tp
) {
exists(DeclarationPosition dpos, TypeParameter constrainedTp |
accessDeclarationPositionMatch(apos, dpos) and
constrainedTp = target.getTypeParameter(_) and
constraint = getATypeParameterConstraint(constrainedTp) and
exists(TypeParameter constrainedTp |
typeParameterHasConstraint(target, apos, constrainedTp, pathToConstrained, constraint) and
tp = target.getTypeParameter(_) and
tp = constraint.getTypeAt(pathToTp) and
constrainedTp != tp and
constrainedTp = target.getDeclaredType(dpos, pathToConstrained)
constrainedTp != tp
)
}
@@ -1799,6 +1823,15 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
Type getDeclaredType(DeclarationPosition dpos, TypePath path);
}
/**
* Gets a type constraint on the type parameter `tp` that applies to `decl`,
* if any.
*/
bindingset[decl]
default TypeMention getATypeParameterConstraint(TypeParameter tp, Declaration decl) {
result = getATypeParameterConstraint(tp)
}
/**
* A position inside an access. For example, the integer position of an
* argument inside a method call.
@@ -1856,6 +1889,8 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
private import codeql.util.Unit
import Input
predicate getATypeParameterConstraint = Input::getATypeParameterConstraint/2;
class AccessEnvironment = Unit;
final private class AccessFinal = Input::Access;