Skip to content

Commit 8093c96

Browse files
committed
wip
1 parent ff2fe20 commit 8093c96

13 files changed

Lines changed: 209 additions & 1403 deletions

File tree

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ module SatisfiesBlanketConstraint<
9696

9797
Type getTypeAt(TypePath path) {
9898
result = at.getTypeAt(blanketPath.appendInverse(path)) and
99-
not result = TNeverType() and
10099
not result = TUnknownType()
101100
}
102101

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ module ArgIsInstantiationOf<ArgSig Arg, IsInstantiationOfInputSig<Arg, AssocFunc
329329
private class ArgSubst extends ArgFinal {
330330
Type getTypeAt(TypePath path) {
331331
result = substituteLookupTraits0(this.getEnclosingItemNode(), super.getTypeAt(path)) and
332-
not result = TNeverType() and
333332
not result = TUnknownType()
334333
}
335334
}

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ newtype TType =
3636
TTrait(Trait t) or
3737
TImplTraitType(ImplTraitTypeRepr impl) or
3838
TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or
39-
TNeverType() or
4039
TUnknownType() or
4140
TTypeParamTypeParameter(TypeParam t) or
4241
TAssociatedTypeTypeParameter(Trait trait, AssocType typeAlias) {
@@ -326,14 +325,6 @@ TypeParamTypeParameter getSliceTypeParameter() {
326325
result = any(SliceType t).getPositionalTypeParameter(0)
327326
}
328327

329-
class NeverType extends Type, TNeverType {
330-
override TypeParameter getPositionalTypeParameter(int i) { none() }
331-
332-
override string toString() { result = "!" }
333-
334-
override Location getLocation() { result instanceof EmptyLocation }
335-
}
336-
337328
abstract class PtrType extends StructType { }
338329

339330
pragma[nomagic]

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

Lines changed: 76 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ import M2
272272
private module Input3 implements InputSig3 {
273273
private import rust as Rust
274274

275-
predicate cachedStageRevRef() {
275+
predicate cacheRevRef() {
276276
Stages::TypeInferenceStage::ref()
277277
or
278278
(implicitDerefChainBorrow(_, _, _) implies any())
@@ -306,6 +306,16 @@ private module Input3 implements InputSig3 {
306306
)
307307
or
308308
result = n.(ShorthandSelfParameterMention)
309+
or
310+
exists(Static static |
311+
n = static and
312+
result = static.getTypeRepr()
313+
)
314+
or
315+
exists(Const c |
316+
n = c and
317+
result = c.getTypeRepr()
318+
)
309319
}
310320

311321
class Expr = Rust::Expr;
@@ -342,32 +352,61 @@ private module Input3 implements InputSig3 {
342352

343353
class ParenExpr = Rust::ParenExpr;
344354

345-
class Variable extends Rust::Variable {
355+
private newtype TLocalVariable =
356+
TVariableVariable(Rust::Variable v) or
357+
TConstVariable(Const c) or
358+
TStaticVariable(Static s)
359+
360+
class LocalVariable extends TLocalVariable {
361+
Rust::Variable asVariable() { this = TVariableVariable(result) }
362+
363+
Const asConst() { this = TConstVariable(result) }
364+
365+
Static asStatic() { this = TStaticVariable(result) }
366+
346367
AstNode getDefiningNode() {
347-
result = this.getPat().getName() or
348-
result = this.getParameter().(SelfParam)
368+
result = this.asVariable().getPat().getName() or
369+
result = this.asVariable().getParameter().(SelfParam) or
370+
result = this.asConst() or
371+
result = this.asStatic()
372+
}
373+
374+
Expr getAnAccess() {
375+
result = this.asVariable().getAnAccess()
376+
or
377+
result = this.asConst().getAnAccess()
378+
or
379+
result = this.asStatic().getAnAccess()
380+
}
381+
382+
string toString() {
383+
result = this.asVariable().toString()
384+
or
385+
result = this.asConst().toString()
386+
or
387+
result = this.asStatic().toString()
349388
}
350389

351-
Expr getAnAccess() { result = super.getAnAccess() }
390+
Location getLocation() { result = this.getDefiningNode().getLocation() }
352391
}
353392

354-
abstract class LetDeclaration extends AstNode {
393+
abstract class LocalVariableDeclaration extends AstNode {
355394
abstract predicate isCoercionSite();
356395

357396
abstract AstNode getLeftOperand();
358397

359398
abstract AstNode getRightOperand();
360399
}
361400

362-
private class LetExprLetDeclaration extends LetDeclaration, LetExpr {
401+
private class LetExprDeclaration extends LocalVariableDeclaration, LetExpr {
363402
override predicate isCoercionSite() { not this.getPat() instanceof IdentPat }
364403

365404
override AstNode getLeftOperand() { result = this.getPat() }
366405

367406
override AstNode getRightOperand() { result = this.getScrutinee() }
368407
}
369408

370-
private class LetStmtLetDeclaration extends LetDeclaration, LetStmt {
409+
private class LetStmtDeclaration extends LocalVariableDeclaration, LetStmt {
371410
override predicate isCoercionSite() {
372411
this.hasTypeRepr() or
373412
not identLetStmt(this, _, _)
@@ -393,16 +432,6 @@ private module Input3 implements InputSig3 {
393432
}
394433

395434
class Call extends FunctionCallMatchingInput::Access {
396-
/** Gets the target of this call. */
397-
Callable getTargetCertain() {
398-
exists(ImplOrTraitItemNodeOption i, FunctionDeclaration f, Path p |
399-
result.isFunction(i, f) and
400-
p = CallExprImpl::getFunctionPath(this) and
401-
f = resolvePath(p) and
402-
f.isDirectlyFor(i)
403-
)
404-
}
405-
406435
Callable getTarget(string derefChainBorrow) { result = super.getTarget(derefChainBorrow) }
407436
}
408437

@@ -467,8 +496,6 @@ private module Input3 implements InputSig3 {
467496
}
468497

469498
Type inferTypeCertainSpecific(AstNode n, TypePath path) {
470-
result = inferFunctionBodyType(n, path)
471-
or
472499
result = inferLiteralType(n, path, true)
473500
or
474501
result = inferRefPatType(n) and
@@ -498,16 +525,14 @@ private module Input3 implements InputSig3 {
498525
path.isEmpty() and
499526
result instanceof UnitType
500527
or
501-
isPanicMacroCall(n) and
502-
path.isEmpty() and
503-
result instanceof NeverType
504-
or
505528
n instanceof ClosureExpr and
506529
path.isEmpty() and
507530
result = closureRootType()
508531
}
509532

510533
predicate inferStepSymmetric(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
534+
// inferStepSymmetricCertain0(n1, prefix1, n2, prefix2)
535+
// or
511536
prefix1.isEmpty() and
512537
prefix2.isEmpty() and
513538
(
@@ -619,9 +644,17 @@ private module Input3 implements InputSig3 {
619644
or
620645
result = inferOperationType(n, pos, path)
621646
)
647+
or
648+
result = inferFieldExprType(n, path, true)
622649
}
623650

624651
Type inferTypeSpecific(AstNode n, TypePath path) {
652+
// result = inferTypeCertainSpecific0(n, path)
653+
// or
654+
isPanicMacroCall(n) and
655+
path.isEmpty() and
656+
result instanceof UnknownType
657+
or
625658
result = inferAssignmentOperationType(n, path)
626659
or
627660
exists(FunctionPosition pos | pos.isReturn() |
@@ -630,7 +663,7 @@ private module Input3 implements InputSig3 {
630663
result = inferOperationType(n, pos, path)
631664
)
632665
or
633-
result = inferFieldExprType(n, path)
666+
result = inferFieldExprType(n, path, false)
634667
or
635668
result = inferTryExprType(n, path)
636669
or
@@ -666,7 +699,7 @@ module Consistency {
666699

667700
private Type inferTypeCertainAdj(AstNode n, TypePath path) {
668701
result = inferTypeCertain(n, path) and
669-
not result = TNeverType()
702+
not result = TUnknownType()
670703
}
671704

672705
predicate nonUniqueCertainType(AstNode n, TypePath path, Type t) {
@@ -834,17 +867,6 @@ private Type getCallExprTypeArgument(CallExpr ce, TypeArgumentPosition apos, Typ
834867
)
835868
}
836869

837-
pragma[nomagic]
838-
private Type inferFunctionBodyType(AstNode n, TypePath path) {
839-
exists(Function f |
840-
n = f.getFunctionBody() and
841-
result = getReturnTypeMention(f).getTypeAt(path) and
842-
not exists(ImplTraitReturnType i | i.getFunction() = f |
843-
result = i or result = i.getATypeParameter()
844-
)
845-
)
846-
}
847-
848870
/**
849871
* Holds if `me` is a call to the `panic!` macro.
850872
*
@@ -1127,17 +1149,14 @@ private module ContextTyping {
11271149
*/
11281150
bindingset[path, type]
11291151
private predicate isComplexRootStripped(TypePath path, Type type) {
1130-
(
1131-
path.isEmpty() and
1132-
not validSelfType(type)
1133-
or
1134-
exists(TypeParameter tp |
1135-
complexSelfRoot(_, tp) and
1136-
path = TypePath::singleton(tp) and
1137-
exists(type)
1138-
)
1139-
) and
1140-
type != TNeverType()
1152+
path.isEmpty() and
1153+
not validSelfType(type)
1154+
or
1155+
exists(TypeParameter tp |
1156+
complexSelfRoot(_, tp) and
1157+
path = TypePath::singleton(tp) and
1158+
exists(type)
1159+
)
11411160
}
11421161

11431162
private newtype TBorrowKind =
@@ -1606,7 +1625,6 @@ private module AssocFunctionResolution {
16061625
not this.hasReceiver() and
16071626
exists(TypePath strippedTypePath, Type strippedType |
16081627
strippedType = substituteLookupTraits(this, this.getTypeAt(selfPos, strippedTypePath)) and
1609-
strippedType != TNeverType() and
16101628
strippedType != TUnknownType()
16111629
|
16121630
nonBlanketLikeCandidate(this, _, selfPos, _, _, strippedTypePath, strippedType)
@@ -1703,7 +1721,6 @@ private module AssocFunctionResolution {
17031721
FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath path
17041722
) {
17051723
result = this.getSelfTypeAt(selfPos, derefChain, borrow, path) and
1706-
result != TNeverType() and
17071724
result != TUnknownType()
17081725
}
17091726

@@ -2343,7 +2360,6 @@ private module AssocFunctionResolution {
23432360

23442361
Type getTypeAt(TypePath path) {
23452362
result = substituteLookupTraits(afc, afc.getSelfTypeAtNoBorrow(selfPos, derefChain, path)) and
2346-
result != TNeverType() and
23472363
result != TUnknownType()
23482364
}
23492365

@@ -3313,7 +3329,7 @@ private module FieldExprMatching = Matching<FieldExprMatchingInput>;
33133329
* the receiver of field expression call.
33143330
*/
33153331
pragma[nomagic]
3316-
private Type inferFieldExprType(AstNode n, TypePath path) {
3332+
private Type inferFieldExprType(AstNode n, TypePath path, boolean topDown) {
33173333
exists(
33183334
FieldExprMatchingInput::Access a, FieldExprMatchingInput::AccessPosition apos, TypePath path0
33193335
|
@@ -3322,6 +3338,7 @@ private Type inferFieldExprType(AstNode n, TypePath path) {
33223338
|
33233339
if apos.isSelf()
33243340
then
3341+
topDown = true and
33253342
exists(Type receiverType | receiverType = inferType(n) |
33263343
if receiverType instanceof RefType
33273344
then
@@ -3331,7 +3348,9 @@ private Type inferFieldExprType(AstNode n, TypePath path) {
33313348
path = TypePath::cons(getRefTypeParameter(_), path0)
33323349
else path = path0
33333350
)
3334-
else path = path0
3351+
else (
3352+
topDown = false and path = path0
3353+
)
33353354
)
33363355
}
33373356

@@ -3437,7 +3456,10 @@ private DynTraitTypeParameter getDynFutureOutputTypeParameter() {
34373456
pragma[nomagic]
34383457
predicate isUnitBlockExpr(BlockExpr be) {
34393458
not be.getStmtList().hasTailExpr() and
3440-
not be = any(Callable c).getBody() and
3459+
not exists(Callable c |
3460+
be = c.getBody() and
3461+
c = any(ReturnExpr re).getEnclosingCallable()
3462+
) and
34413463
not be.hasLabel()
34423464
}
34433465

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ private module MkTypeMention<getAdditionalPathTypeAtSig/2 getAdditionalPathTypeA
676676
}
677677

678678
class NeverTypeReprMention extends TypeMentionImpl, NeverTypeRepr {
679-
override Type getTypeAt(TypePath path) { result = TNeverType() and path.isEmpty() }
679+
override Type getTypeAt(TypePath path) { result = TUnknownType() and path.isEmpty() }
680680
}
681681

682682
class PtrTypeReprMention extends TypeMentionImpl instanceof PtrTypeRepr {

rust/ql/test/library-tests/dataflow/sources/web_frameworks/CONSISTENCY/TypeInferenceConsistency.expected

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
multipleResolvedTargets
22
| main.rs:2223:9:2223:31 | ... .my_add(...) |
33
| main.rs:2225:9:2225:29 | ... .my_add(...) |
4-
| main.rs:2740:13:2740:17 | x.f() |
54
| regressions.rs:179:17:179:27 | ... + ... |

rust/ql/test/library-tests/type-inference/closure.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mod fn_once_trait {
6464
let _r = apply(f, true); // $ target=apply type=_r:i64
6565

6666
let f = |x| x + 1; // $ type=x:i64 $ MISSING: target=add
67-
let _r2 = apply_two(f); // $ target=apply_two certainType=_r2:i64
67+
let _r2 = apply_two(f); // $ target=apply_two type=_r2:i64
6868
}
6969
}
7070

@@ -101,7 +101,7 @@ mod fn_mut_trait {
101101
let _r = apply(f, true); // $ target=apply type=_r:i64
102102

103103
let f = |x| x + 1; // $ type=x:i64 $ MISSING: target=add
104-
let _r2 = apply_two(f); // $ target=apply_two certainType=_r2:i64
104+
let _r2 = apply_two(f); // $ target=apply_two type=_r2:i64
105105
}
106106
}
107107

@@ -138,7 +138,7 @@ mod fn_trait {
138138
let _r = apply(f, true); // $ target=apply type=_r:i64
139139

140140
let f = |x| x + 1; // $ type=x:i64 $ MISSING: target=add
141-
let _r2 = apply_two(f); // $ target=apply_two certainType=_r2:i64
141+
let _r2 = apply_two(f); // $ target=apply_two type=_r2:i64
142142
}
143143
}
144144

rust/ql/test/library-tests/type-inference/dereference.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ mod implicit_deref_coercion_cycle {
141141

142142
#[rustfmt::skip]
143143
pub fn test() {
144-
let mut key_to_key = HashMap::<&Key, &Key>::new(); // $ target=new
144+
let mut key_to_key = HashMap::<_, &Key>::new(); // $ target=new
145145
let mut key = &Key {}; // Initialize key2 to a reference
146146
if let Some(ref_key) = key_to_key.get(key) { // $ target=get
147147
// Below `ref_key` is implicitly dereferenced from `&&Key` to `&Key`

0 commit comments

Comments
 (0)