Skip to content

Commit 786d5bd

Browse files
committed
wip7
1 parent 5c8ab5f commit 786d5bd

File tree

4 files changed

+182
-5
lines changed

4 files changed

+182
-5
lines changed

rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class AssocFunctionType extends MkAssocFunctionType {
197197
exists(Function f, ImplOrTraitItemNode i, FunctionPosition pos | this.appliesTo(f, i, pos) |
198198
result = pos.getTypeMention(f)
199199
or
200-
pos.isSelf() and
200+
pos.isSelfOrTypeQualifier() and
201201
not f.hasSelfParam() and
202202
result = [i.(Impl).getSelfTy().(AstNode), i.(Trait).getName()]
203203
)

rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll

Lines changed: 161 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,38 @@ private module MethodResolution {
13851385
)
13861386
}
13871387

1388+
/**
1389+
* Holds if resolving the function `implFunction` in `impl` requires inspecting
1390+
* the type of applied _arguments_ or possibly knowing the return type.
1391+
*
1392+
* `traitTp` is a type parameter of the trait being implemented by `impl`, and
1393+
* we need to check that the type of `f` corresponding to `traitTp` is satisfied
1394+
* at any one of the positions `pos` in which that type occurs in `f` (at `path`).
1395+
*
1396+
* As for method resolution, we always check the type being implemented (corresponding
1397+
* to `traitTp` being the special `Self` type parameter).
1398+
*/
1399+
pragma[nomagic]
1400+
private predicate traitFunctionResolutionDependsOnArgument(
1401+
TraitItemNode trait, NonMethodFunction traitFunction, FunctionPosition pos, ImplItemNode impl,
1402+
NonMethodFunction implFunction, TypePath path, TypeParameter traitTp
1403+
) {
1404+
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, pos, impl, implFunction, path,
1405+
traitTp) and
1406+
// Exclude functions where we cannot resolve all relevant type mentions; this allows
1407+
// for blanket implementations to be applied in those cases
1408+
forall(TypeParameter traitTp0 |
1409+
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, _, impl, implFunction, _,
1410+
traitTp0)
1411+
|
1412+
exists(FunctionPosition pos0, TypePath path0 |
1413+
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, pos0, impl, implFunction,
1414+
path0, traitTp0) and
1415+
exists(getAssocFunctionTypeAt(implFunction, impl, pos0, path0))
1416+
)
1417+
)
1418+
}
1419+
13881420
/**
13891421
* Holds if function `f` with the name `name` and the arity `arity` exists in
13901422
* `i`, and the type of the `self` parameter is `selfType`.
@@ -1415,9 +1447,45 @@ private module MethodResolution {
14151447
or
14161448
traitFunctionResolutionDependsOnArgument0(_, _, selfPos, _, f, _, TSelfTypeParameter(trait))
14171449
)
1450+
) and
1451+
// Exclude functions where we cannot resolve all relevant type mentions; this allows
1452+
// for blanket implementations to be applied in those cases
1453+
forall(TraitItemNode trait, NonMethodFunction traitFunction, TypeParameter traitTp0 |
1454+
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, _, i, f, _, traitTp0)
1455+
|
1456+
exists(FunctionPosition pos0, TypePath path0 |
1457+
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, pos0, i, f, path0, traitTp0) and
1458+
exists(getAssocFunctionTypeAt(f, i, pos0, path0))
1459+
)
14181460
)
14191461
}
14201462

1463+
pragma[nomagic]
1464+
private predicate testassocFunctionInfo(
1465+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1466+
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
1467+
) {
1468+
assocFunctionInfo(f, name, arity, i, selfPos, selfType) and
1469+
strippedType = selfType.getTypeAt(strippedTypePath) and
1470+
(
1471+
isComplexRootStripped(strippedTypePath, strippedType)
1472+
or
1473+
selfPos.isTypeQualifier() and strippedTypePath.isEmpty()
1474+
) and
1475+
posAdj = selfPos.getFunctionCallAdjusted(f) and
1476+
(
1477+
selfPos.isSelfOrTypeQualifier()
1478+
or
1479+
exists(TraitItemNode trait |
1480+
traitFunctionResolutionDependsOnArgument0(_, f, selfPos, _, _, _, TSelfTypeParameter(trait))
1481+
or
1482+
traitFunctionResolutionDependsOnArgument0(_, _, selfPos, _, f, _, TSelfTypeParameter(trait))
1483+
)
1484+
) and
1485+
not assocFunctionInfo(f, name, arity, selfPos, posAdj, i, selfType, strippedTypePath,
1486+
strippedType)
1487+
}
1488+
14211489
pragma[nomagic]
14221490
private predicate assocFunctionInfoTypeParam(
14231491
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
@@ -1756,6 +1824,24 @@ private module MethodResolution {
17561824
)
17571825
}
17581826

1827+
private predicate foo2(
1828+
FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType
1829+
) {
1830+
//ImplOrTraitItemNode i
1831+
this = Debug::getRelevantLocatable() and
1832+
derefChain.isEmpty() and
1833+
strippedType =
1834+
this.getComplexStrippedType(selfPos, derefChain, TNoBorrowKind(), strippedTypePath) and
1835+
this.hasNoCompatibleTargetCheck(selfPos, derefChain, TNoBorrowKind(), strippedTypePath,
1836+
getNthLookupType(strippedType, _))
1837+
// exists(Type t | t = getNthLookupType(strippedType, n) |
1838+
// this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1839+
// strippedTypePath, t)
1840+
// ) and
1841+
// methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1842+
// not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1843+
}
1844+
17591845
/**
17601846
* Holds if the candidate receiver type represented by `derefChain` does not
17611847
* have a matching method target.
@@ -1768,6 +1854,16 @@ private module MethodResolution {
17681854
)
17691855
}
17701856

1857+
private predicate testhasNoCompatibleTargetNoBorrow(
1858+
FunctionPosition selfPos, DerefChain derefChain
1859+
) {
1860+
exists(Type strippedType |
1861+
this.hasNoCompatibleTargetNoBorrowToIndex(selfPos, derefChain, _, strippedType,
1862+
getLastLookupTypeIndex(strippedType))
1863+
) and
1864+
this = Debug::getRelevantLocatable()
1865+
}
1866+
17711867
// forex using recursion
17721868
pragma[nomagic]
17731869
private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex(
@@ -1794,6 +1890,29 @@ private module MethodResolution {
17941890
)
17951891
}
17961892

1893+
private predicate sdf(
1894+
FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType,
1895+
int n, ImplOrTraitItemNode i
1896+
) {
1897+
(
1898+
this.supportsAutoDerefAndBorrow() and
1899+
selfPos.isSelf()
1900+
or
1901+
// needed for the `hasNoCompatibleTarget` check in
1902+
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1903+
derefChain.isEmpty()
1904+
) and
1905+
strippedType =
1906+
this.getComplexStrippedType(selfPos, derefChain, TNoBorrowKind(), strippedTypePath) and
1907+
this = Debug::getRelevantLocatable() and
1908+
exists(Type t | t = getNthLookupType(strippedType, n) |
1909+
// this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(),
1910+
// strippedTypePath, t)
1911+
methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) and
1912+
not this.hasIncompatibleTarget(i, selfPos, derefChain, TNoBorrowKind(), strippedType)
1913+
)
1914+
}
1915+
17971916
/**
17981917
* Holds if the candidate receiver type represented by `derefChain` does not have
17991918
* a matching non-blanket method target.
@@ -1827,6 +1946,22 @@ private module MethodResolution {
18271946
)
18281947
}
18291948

1949+
private predicate foo(
1950+
FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType
1951+
) {
1952+
//ImplOrTraitItemNode i
1953+
this = Debug::getRelevantLocatable() and
1954+
this.hasNoCompatibleTargetNoBorrow(selfPos, derefChain) and
1955+
strippedType =
1956+
this.getComplexStrippedType(selfPos, derefChain, TSomeBorrowKind(false), strippedTypePath) //and
1957+
// exists(Type t | t = getNthLookupType(strippedType, n) |
1958+
// this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1959+
// strippedTypePath, t)
1960+
// ) and
1961+
// methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1962+
// not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1963+
}
1964+
18301965
/**
18311966
* Holds if the candidate receiver type represented by `derefChain`, followed
18321967
* by a shared borrow, does not have a matching method target.
@@ -2194,13 +2329,13 @@ private module MethodResolution {
21942329

21952330
pragma[nomagic]
21962331
predicate hasNoCompatibleNonBlanketTarget() {
2197-
mc_.hasNoCompatibleNonBlanketTargetSharedBorrow(selfPos, derefChain) and
2332+
mc_.hasNoCompatibleNonBlanketTargetSharedBorrow(_, derefChain) and
21982333
borrow.isSharedBorrow()
21992334
or
2200-
mc_.hasNoCompatibleNonBlanketTargetMutBorrow(selfPos, derefChain) and
2335+
mc_.hasNoCompatibleNonBlanketTargetMutBorrow(_, derefChain) and
22012336
borrow.isMutableBorrow()
22022337
or
2203-
mc_.hasNoCompatibleNonBlanketTargetNoBorrow(selfPos, derefChain) and
2338+
mc_.hasNoCompatibleNonBlanketTargetNoBorrow(_, derefChain) and
22042339
borrow.isNoBorrow()
22052340
}
22062341

@@ -2367,6 +2502,28 @@ private module MethodResolution {
23672502
blanketPath.getHead() = borrow.getRefType().getPositionalTypeParameter(0)
23682503
)
23692504
}
2505+
2506+
pragma[nomagic]
2507+
predicate testhasBlanketCandidate(
2508+
MethodCallCand mcc, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam
2509+
) {
2510+
exists(MethodCall mc, FunctionPosition pos, BorrowKind borrow |
2511+
mcc = MkMethodCallCand(mc, _, pos, _, borrow) and
2512+
blanketPath.isEmpty() and
2513+
mc = Debug::getRelevantLocatable() and
2514+
methodCallBlanketLikeCandidate(mc, _, _, pos, impl, _, blanketPath, blanketTypeParam) and
2515+
impl.isBlanketImplementation() and
2516+
// Only apply blanket implementations when no other implementations are possible;
2517+
// this is to account for codebases that use the (unstable) specialization feature
2518+
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2519+
// cases where our blanket implementation filtering is not precise enough.
2520+
mcc.hasNoCompatibleNonBlanketTarget()
2521+
|
2522+
borrow.isNoBorrow()
2523+
or
2524+
blanketPath.getHead() = borrow.getRefType().getPositionalTypeParameter(0)
2525+
)
2526+
}
23702527
}
23712528

23722529
private module ReceiverSatisfiesBlanketLikeConstraint =
@@ -3937,7 +4094,7 @@ private module Debug {
39374094
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
39384095
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
39394096
filepath.matches("%/main.rs") and
3940-
startline = 661
4097+
startline = 570
39414098
)
39424099
}
39434100

rust/ql/test/library-tests/dataflow/local/inline-flow.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ edges
307307
| main.rs:575:10:575:10 | b | main.rs:575:10:575:17 | b.into() | provenance | MaD:3 |
308308
| main.rs:575:10:575:10 | b | main.rs:575:10:575:17 | b.into() | provenance | MaD:4 |
309309
| main.rs:576:20:576:20 | b | main.rs:576:10:576:21 | ...::from(...) | provenance | MaD:9 |
310+
| main.rs:576:20:576:20 | b | main.rs:576:10:576:21 | ...::from(...) | provenance | ReflexiveFrom |
310311
nodes
311312
| main.rs:19:10:19:18 | source(...) | semmle.label | source(...) |
312313
| main.rs:23:9:23:9 | s | semmle.label | s |

rust/ql/test/library-tests/type-inference/type-inference.expected

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9885,12 +9885,16 @@ inferType
98859885
| main.rs:1613:13:1616:13 | Vec2 {...} | | main.rs:1493:5:1498:5 | Vec2 |
98869886
| main.rs:1614:20:1614:23 | self | | main.rs:1493:5:1498:5 | Vec2 |
98879887
| main.rs:1614:20:1614:25 | self.x | | {EXTERNAL LOCATION} | i64 |
9888+
| main.rs:1614:20:1614:33 | ... \| ... | | {EXTERNAL LOCATION} | NonZero |
98889889
| main.rs:1614:20:1614:33 | ... \| ... | | {EXTERNAL LOCATION} | i64 |
9890+
| main.rs:1614:20:1614:33 | ... \| ... | T | {EXTERNAL LOCATION} | i64 |
98899891
| main.rs:1614:29:1614:31 | rhs | | main.rs:1493:5:1498:5 | Vec2 |
98909892
| main.rs:1614:29:1614:33 | rhs.x | | {EXTERNAL LOCATION} | i64 |
98919893
| main.rs:1615:20:1615:23 | self | | main.rs:1493:5:1498:5 | Vec2 |
98929894
| main.rs:1615:20:1615:25 | self.y | | {EXTERNAL LOCATION} | i64 |
9895+
| main.rs:1615:20:1615:33 | ... \| ... | | {EXTERNAL LOCATION} | NonZero |
98939896
| main.rs:1615:20:1615:33 | ... \| ... | | {EXTERNAL LOCATION} | i64 |
9897+
| main.rs:1615:20:1615:33 | ... \| ... | T | {EXTERNAL LOCATION} | i64 |
98949898
| main.rs:1615:29:1615:31 | rhs | | main.rs:1493:5:1498:5 | Vec2 |
98959899
| main.rs:1615:29:1615:33 | rhs.y | | {EXTERNAL LOCATION} | i64 |
98969900
| main.rs:1621:25:1621:33 | SelfParam | | {EXTERNAL LOCATION} | &mut |
@@ -10245,9 +10249,13 @@ inferType
1024510249
| main.rs:1770:26:1770:30 | 33i64 | | {EXTERNAL LOCATION} | i64 |
1024610250
| main.rs:1770:26:1770:38 | ... & ... | | {EXTERNAL LOCATION} | i64 |
1024710251
| main.rs:1770:34:1770:38 | 34i64 | | {EXTERNAL LOCATION} | i64 |
10252+
| main.rs:1771:13:1771:21 | i64_bitor | | {EXTERNAL LOCATION} | NonZero |
1024810253
| main.rs:1771:13:1771:21 | i64_bitor | | {EXTERNAL LOCATION} | i64 |
10254+
| main.rs:1771:13:1771:21 | i64_bitor | T | {EXTERNAL LOCATION} | i64 |
1024910255
| main.rs:1771:25:1771:29 | 35i64 | | {EXTERNAL LOCATION} | i64 |
10256+
| main.rs:1771:25:1771:37 | ... \| ... | | {EXTERNAL LOCATION} | NonZero |
1025010257
| main.rs:1771:25:1771:37 | ... \| ... | | {EXTERNAL LOCATION} | i64 |
10258+
| main.rs:1771:25:1771:37 | ... \| ... | T | {EXTERNAL LOCATION} | i64 |
1025110259
| main.rs:1771:33:1771:37 | 36i64 | | {EXTERNAL LOCATION} | i64 |
1025210260
| main.rs:1772:13:1772:22 | i64_bitxor | | {EXTERNAL LOCATION} | i64 |
1025310261
| main.rs:1772:26:1772:30 | 37i64 | | {EXTERNAL LOCATION} | i64 |
@@ -12655,15 +12663,25 @@ inferType
1265512663
| overloading.rs:397:10:397:10 | b | | {EXTERNAL LOCATION} | bool |
1265612664
| overloading.rs:397:25:401:5 | { ... } | | overloading.rs:372:5:372:14 | S1 |
1265712665
| overloading.rs:398:13:398:13 | s | | overloading.rs:364:5:365:13 | S |
12666+
| overloading.rs:398:13:398:13 | s | | overloading.rs:372:5:372:14 | S1 |
1265812667
| overloading.rs:398:17:398:54 | if b {...} else {...} | | overloading.rs:364:5:365:13 | S |
12668+
| overloading.rs:398:17:398:54 | if b {...} else {...} | | overloading.rs:372:5:372:14 | S1 |
1265912669
| overloading.rs:398:20:398:20 | b | | {EXTERNAL LOCATION} | bool |
1266012670
| overloading.rs:398:22:398:26 | { ... } | | overloading.rs:364:5:365:13 | S |
12671+
| overloading.rs:398:22:398:26 | { ... } | | overloading.rs:372:5:372:14 | S1 |
1266112672
| overloading.rs:398:24:398:24 | S | | overloading.rs:364:5:365:13 | S |
12673+
| overloading.rs:398:24:398:24 | S | | overloading.rs:372:5:372:14 | S1 |
1266212674
| overloading.rs:398:33:398:54 | { ... } | | overloading.rs:364:5:365:13 | S |
12675+
| overloading.rs:398:33:398:54 | { ... } | | overloading.rs:372:5:372:14 | S1 |
1266312676
| overloading.rs:398:35:398:52 | ...::default(...) | | overloading.rs:364:5:365:13 | S |
12677+
| overloading.rs:398:35:398:52 | ...::default(...) | | overloading.rs:372:5:372:14 | S1 |
12678+
| overloading.rs:399:13:399:13 | x | | overloading.rs:364:5:365:13 | S |
1266412679
| overloading.rs:399:13:399:13 | x | | overloading.rs:372:5:372:14 | S1 |
12680+
| overloading.rs:399:17:399:29 | ...::from(...) | | overloading.rs:364:5:365:13 | S |
1266512681
| overloading.rs:399:17:399:29 | ...::from(...) | | overloading.rs:372:5:372:14 | S1 |
1266612682
| overloading.rs:399:28:399:28 | s | | overloading.rs:364:5:365:13 | S |
12683+
| overloading.rs:399:28:399:28 | s | | overloading.rs:372:5:372:14 | S1 |
12684+
| overloading.rs:400:9:400:9 | x | | overloading.rs:364:5:365:13 | S |
1266712685
| overloading.rs:400:9:400:9 | x | | overloading.rs:372:5:372:14 | S1 |
1266812686
| pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option |
1266912687
| pattern_matching.rs:13:26:133:1 | { ... } | T | {EXTERNAL LOCATION} | () |
@@ -14781,3 +14799,4 @@ inferType
1478114799
| regressions.rs:32:9:32:13 | opt_e | T | regressions.rs:5:5:7:5 | E |
1478214800
| regressions.rs:32:9:32:22 | opt_e.unwrap() | | regressions.rs:5:5:7:5 | E |
1478314801
testFailures
14802+
| overloading.rs:399:17:399:29 | ...::from(...) | Unexpected result: target=from |

0 commit comments

Comments
 (0)