Skip to content

Commit 1ca1bc3

Browse files
committed
more tests
1 parent 2e11a89 commit 1ca1bc3

6 files changed

Lines changed: 149 additions & 20 deletions

File tree

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,27 +1479,15 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
14791479
}
14801480

14811481
private module SatisfiesParameterConstraintInput implements
1482-
SatisfiesConstraintWithTypeMatchingInputSig<RelevantAccess, RelevantTarget>
1482+
SatisfiesConstraintInputSig<RelevantAccess, RelevantTarget>
14831483
{
14841484
predicate relevantConstraint(RelevantAccess at, RelevantTarget constraint) {
14851485
constraint = at.getTarget()
14861486
}
1487-
1488-
class TypeMatchingContext = Access;
1489-
1490-
TypeMatchingContext getTypeMatchingContext(RelevantAccess at) {
1491-
at = MkRelevantAccess(result, _, _)
1492-
}
1493-
1494-
pragma[nomagic]
1495-
predicate typeMatch(TypeMatchingContext ctx, TypeParameter tp, TypePath path, Type t) {
1496-
typeMatch(ctx, _, _, path, t, tp)
1497-
}
14981487
}
14991488

15001489
private module SatisfiesParameterConstraint =
1501-
SatisfiesConstraintWithTypeMatching<RelevantAccess, RelevantTarget,
1502-
SatisfiesParameterConstraintInput>;
1490+
SatisfiesConstraint<RelevantAccess, RelevantTarget, SatisfiesParameterConstraintInput>;
15031491

15041492
/**
15051493
* Holds if the (transitive) base type `t` at `path` of `a` in environment `e`

swift/ql/lib/codeql/swift/typeinference/TypeInference.qll

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ private module Input2 implements InputSig2<TypeMention> {
7777
result.(GenericContextMention).getContext() = tp.(SelfTypeParameter).getProtocol()
7878
or
7979
// todo: type parameter constraints
80-
none()
80+
result.(GenericContextMention).getContext() =
81+
tp.(GenericTypeParamDeclTypeParameter).getDecl().(GenericTypeParamDecl).getABaseTypeDecl()
8182
}
8283

8384
/**
@@ -90,12 +91,16 @@ private module Input2 implements InputSig2<TypeMention> {
9091
predicate conditionSatisfiesConstraint(
9192
TypeAbstraction abs, TypeMention condition, TypeMention constraint, boolean transitive
9293
) {
94+
transitive = true and
9395
condition.(GenericContextMention).getContext() =
9496
any(GenericContext ctx |
9597
abs = ctx and
96-
constraint.(TypeDeclBaseTypeMention).getDecl() = ctx
97-
) and
98-
transitive = true
98+
ctx =
99+
[
100+
constraint.(TypeDeclBaseTypeMention).getDecl().(GenericContext),
101+
constraint.(ExtensionDeclBaseTypeMention).getDecl()
102+
]
103+
)
99104
}
100105

101106
predicate typeParameterIsFunctionallyDetermined(TypeParameter tp) {

swift/ql/lib/codeql/swift/typeinference/TypeMention.qll

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ private Type getTypeAt(Swift::Type t, TypePath path) {
4343
newtype TTypeMention =
4444
TGenericContextMention(GenericContext context) or
4545
TTypeDeclBaseTypeMention(TypeDecl decl, int i) { exists(decl.getInheritedType(i)) } or
46+
TExtensionDeclBaseTypeMention(ExtensionDecl decl, int i) { exists(decl.getProtocol(i)) } or
4647
TParamDeclTypeMention(ParamDecl decl) or
4748
TCallableReturnTypeMention(Callable c)
4849

@@ -79,6 +80,9 @@ class GenericContextMention extends TypeMentionImpl, TGenericContextMention {
7980
result = t.getATypeParameter() and
8081
path = TypePath::singleton(result)
8182
)
83+
or
84+
result =
85+
getTypeAt(context.(ExtensionDecl).getExtendedTypeDecl().getDeclaredInterfaceType(), path)
8286
}
8387

8488
override string toString() { result = context.toString() }
@@ -103,14 +107,38 @@ class TypeDeclBaseTypeMention extends TypeMentionImpl, TTypeDeclBaseTypeMention
103107
override Location getLocation() { result = decl.getLocation() }
104108
}
105109

110+
class ExtensionDeclBaseTypeMention extends TypeMentionImpl, TExtensionDeclBaseTypeMention {
111+
ExtensionDecl decl;
112+
int index;
113+
114+
ExtensionDeclBaseTypeMention() { this = TExtensionDeclBaseTypeMention(decl, index) }
115+
116+
ExtensionDecl getDecl() { result = decl }
117+
118+
int getIndex() { result = index }
119+
120+
override Type getTypeAt(TypePath path) {
121+
result = getTypeAt(decl.getProtocol(index).getDeclaredInterfaceType(), path)
122+
}
123+
124+
override string toString() { result = decl.toString() + " [extended type " + index + "]" }
125+
126+
override Location getLocation() { result = decl.getLocation() }
127+
}
128+
106129
class ParamDeclTypeMention extends TypeMentionImpl, TParamDeclTypeMention {
107130
ParamDecl decl;
108131

109132
ParamDeclTypeMention() { this = TParamDeclTypeMention(decl) }
110133

111134
ParamDecl getDecl() { result = decl }
112135

113-
override Type getTypeAt(TypePath path) { result = getTypeAt(decl.getType(), path) }
136+
override Type getTypeAt(TypePath path) {
137+
result = getTypeAt(decl.getType(), path)
138+
or
139+
result = TSelfTypeParameter(decl.(SelfParamDecl).getEnclosingDecl().getEnclosingDecl()) and
140+
path.isEmpty()
141+
}
114142

115143
override string toString() { result = decl.toString() + " [parameter type]" }
116144

swift/ql/test/library-tests/type-inference/generics.swift

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,55 @@ func testDerived() {
187187
let dd = DerivedDerived("hello") // $ type=dd@DerivedDerived<D>:String target=DerivedDerived.init
188188
let vv1 = dd.getValue1() // $ type=vv1:Bool target=Base.getValue1
189189
let vv2 = dd.getValue2() // $ type=vv2:String target=Base.getValue2
190-
}
190+
}
191+
192+
// --- Generics and protocols ---
193+
194+
protocol MyProtocol2 {
195+
associatedtype MyType
196+
197+
// MyProtocol2.baz
198+
func baz() -> MyType
199+
}
200+
201+
extension MyProtocol2 {
202+
// MyProtocol2.foo
203+
func foo() -> Self {
204+
return self // $ type=self:Self
205+
}
206+
}
207+
208+
class MyClass<T> {
209+
var value : T
210+
211+
// MyClass.init
212+
init(_ value: T) {
213+
self.value = value // $ type=value:T
214+
}
215+
}
216+
217+
extension MyClass : MyProtocol2 {
218+
typealias MyType = T
219+
220+
// MyClass.baz
221+
func baz() -> T {
222+
return value // $ type=.value:T
223+
}
224+
}
225+
226+
// callFoo
227+
func callFoo<T : MyProtocol2>(_ c: T) -> T {
228+
return c.foo() // $ target=MyProtocol2.foo
229+
}
230+
231+
// callBaz
232+
func callBaz<T : MyProtocol2>(_ c: T) -> T.MyType {
233+
return c.baz() // $ target=MyProtocol2.baz
234+
}
235+
236+
func testProtocolExtension() {
237+
let c = MyClass(42) // $ type=c@MyClass<T>:Int target=MyClass.init
238+
let s = c.foo() // $ type=s@MyClass<T>:Int target=MyProtocol2.foo
239+
let v = c.baz() // $ type=v:Int target=MyClass.baz
240+
let v2 = callBaz(c) // $ type=v2:Int target=callBaz
241+
}

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ testFailures
2323
| generics.swift:120:26:121:1 | // $ type=x:MyType target=MyProtocol.bar\n | Missing result: type=x:MyType |
2424
| generics.swift:159:19:160:1 | // $ type=.value1:T1\n | Missing result: type=.value1:T1 |
2525
| generics.swift:164:19:165:1 | // $ type=.value2:T2\n | Missing result: type=.value2:T2 |
26+
| generics.swift:204:17:205:1 | // $ type=self:Self\n | Missing result: type=self:Self |
27+
| generics.swift:222:18:223:1 | // $ type=.value:T\n | Missing result: type=.value:T |
28+
| generics.swift:238:19:239:1 | // $ type=s@MyClass<T>:Int target=MyProtocol2.foo\n | Missing result: type=s@MyClass<T>:Int |
29+
| generics.swift:239:19:240:1 | // $ type=v:Int target=MyClass.baz\n | Missing result: type=v:Int |
30+
| generics.swift:240:23:241:1 | // $ type=v2:Int target=callBaz\n | Missing result: type=v2:Int |
2631
| key_paths.swift:35:30:36:1 | // $ type=xVal:Double\n | Missing result: type=xVal:Double |
2732
| key_paths.swift:36:30:37:1 | // $ type=yVal:Double\n | Missing result: type=yVal:Double |
2833
| key_paths.swift:48:40:49:1 | // $ type=startX:Double\n | Missing result: type=startX:Double |
@@ -485,6 +490,8 @@ inferType
485490
| generics.swift:84:38:84:38 | x | | file://:0:0:0:0 | Int |
486491
| generics.swift:84:43:84:51 | call to String.init(_:) | | file://:0:0:0:0 | String |
487492
| generics.swift:84:50:84:50 | x | | file://:0:0:0:0 | Int |
493+
| generics.swift:93:8:93:8 | self | | generics.swift:89:1:97:1 | Self [MyProtocol] |
494+
| generics.swift:96:8:96:8 | self | | generics.swift:89:1:97:1 | Self [MyProtocol] |
488495
| generics.swift:99:7:99:7 | self | | generics.swift:99:1:123:1 | Wrapper |
489496
| generics.swift:99:7:99:7 | self | T | generics.swift:99:15:99:18 | T |
490497
| generics.swift:100:7:100:7 | self | | generics.swift:99:1:123:1 | Wrapper |
@@ -653,6 +660,44 @@ inferType
653660
| generics.swift:189:13:189:13 | dd | | generics.swift:175:1:180:1 | DerivedDerived |
654661
| generics.swift:189:13:189:13 | dd | D | file://:0:0:0:0 | String |
655662
| generics.swift:189:13:189:26 | call to getValue2() | | file://:0:0:0:0 | String |
663+
| generics.swift:198:8:198:8 | self | | generics.swift:194:1:199:1 | Self [MyProtocol2] |
664+
| generics.swift:208:7:208:7 | self | | generics.swift:208:1:215:1 | MyClass |
665+
| generics.swift:208:7:208:7 | self | T | generics.swift:208:15:208:15 | T |
666+
| generics.swift:209:7:209:7 | self | | generics.swift:208:1:215:1 | MyClass |
667+
| generics.swift:209:7:209:7 | self | | generics.swift:208:1:215:1 | MyClass |
668+
| generics.swift:209:7:209:7 | self | | generics.swift:208:1:215:1 | MyClass |
669+
| generics.swift:209:7:209:7 | self | T | generics.swift:208:15:208:15 | T |
670+
| generics.swift:209:7:209:7 | self | T | generics.swift:208:15:208:15 | T |
671+
| generics.swift:209:7:209:7 | self | T | generics.swift:208:15:208:15 | T |
672+
| generics.swift:209:7:209:7 | value | | generics.swift:208:15:208:15 | T |
673+
| generics.swift:212:3:212:3 | self | | generics.swift:208:1:215:1 | MyClass |
674+
| generics.swift:212:3:212:3 | self | T | generics.swift:208:15:208:15 | T |
675+
| generics.swift:212:8:212:17 | value | | generics.swift:208:15:208:15 | T |
676+
| generics.swift:213:5:213:5 | self | | generics.swift:208:1:215:1 | MyClass |
677+
| generics.swift:213:5:213:5 | self | T | generics.swift:208:15:208:15 | T |
678+
| generics.swift:213:5:213:10 | .value | | generics.swift:208:15:208:15 | T |
679+
| generics.swift:213:18:213:18 | value | | generics.swift:208:15:208:15 | T |
680+
| generics.swift:221:8:221:8 | self | | generics.swift:208:1:215:1 | MyClass |
681+
| generics.swift:221:8:221:8 | self | T | generics.swift:208:15:208:15 | T |
682+
| generics.swift:222:12:222:12 | self | | generics.swift:208:1:215:1 | MyClass |
683+
| generics.swift:222:12:222:12 | self | T | generics.swift:208:15:208:15 | T |
684+
| generics.swift:227:31:227:36 | c | | generics.swift:227:14:227:18 | T |
685+
| generics.swift:228:10:228:10 | c | | generics.swift:227:14:227:18 | T |
686+
| generics.swift:232:31:232:36 | c | | generics.swift:232:14:232:18 | T |
687+
| generics.swift:233:10:233:10 | c | | generics.swift:232:14:232:18 | T |
688+
| generics.swift:237:7:237:7 | c | | generics.swift:208:1:215:1 | MyClass |
689+
| generics.swift:237:7:237:7 | c | | generics.swift:208:1:215:1 | MyClass |
690+
| generics.swift:237:7:237:7 | c | T | file://:0:0:0:0 | Int |
691+
| generics.swift:237:7:237:7 | c | T | file://:0:0:0:0 | Int |
692+
| generics.swift:237:11:237:21 | call to MyClass<T>.init(_:) | | generics.swift:208:1:215:1 | MyClass |
693+
| generics.swift:237:11:237:21 | call to MyClass<T>.init(_:) | T | file://:0:0:0:0 | Int |
694+
| generics.swift:237:19:237:19 | 42 | | file://:0:0:0:0 | Int |
695+
| generics.swift:238:11:238:11 | c | | generics.swift:208:1:215:1 | MyClass |
696+
| generics.swift:238:11:238:11 | c | T | file://:0:0:0:0 | Int |
697+
| generics.swift:239:11:239:11 | c | | generics.swift:208:1:215:1 | MyClass |
698+
| generics.swift:239:11:239:11 | c | T | file://:0:0:0:0 | Int |
699+
| generics.swift:240:20:240:20 | c | | generics.swift:208:1:215:1 | MyClass |
700+
| generics.swift:240:20:240:20 | c | T | file://:0:0:0:0 | Int |
656701
| key_paths.swift:4:7:4:7 | self | | key_paths.swift:3:1:17:1 | Point |
657702
| key_paths.swift:4:7:4:7 | self | | key_paths.swift:3:1:17:1 | Point |
658703
| key_paths.swift:4:7:4:7 | self | | key_paths.swift:3:1:17:1 | Point |
@@ -1152,6 +1197,7 @@ inferType
11521197
| overload_resolution.swift:226:7:226:7 | r2 | | file://:0:0:0:0 | String |
11531198
| overload_resolution.swift:226:7:226:7 | r2 | | file://:0:0:0:0 | String |
11541199
| overload_resolution.swift:226:12:226:36 | call to action() | | file://:0:0:0:0 | String |
1200+
| overload_resolution.swift:233:8:233:8 | self | | overload_resolution.swift:231:1:234:1 | Self [Describable] |
11551201
| overload_resolution.swift:239:12:239:12 | default | | file://:0:0:0:0 | String |
11561202
| overload_resolution.swift:244:12:244:12 | extra | | file://:0:0:0:0 | String |
11571203
| overload_resolution.swift:248:7:248:7 | self | | overload_resolution.swift:248:1:256:1 | DescribableImpl |
@@ -1256,6 +1302,7 @@ inferType
12561302
| overload_resolution.swift:348:12:348:37 | call to send(to:from:) | | file://:0:0:0:0 | String |
12571303
| overload_resolution.swift:348:23:348:23 | x | | file://:0:0:0:0 | String |
12581304
| overload_resolution.swift:348:34:348:34 | y | | file://:0:0:0:0 | String |
1305+
| overload_resolution.swift:355:15:355:15 | self | | overload_resolution.swift:353:1:356:1 | Self [Numeric2] |
12591306
| overload_resolution.swift:360:38:360:38 | 0 | | file://:0:0:0:0 | Int |
12601307
| overload_resolution.swift:369:33:369:38 | x | | overload_resolution.swift:369:20:369:23 | T |
12611308
| overload_resolution.swift:370:10:370:10 | x | | overload_resolution.swift:369:20:369:23 | T |
@@ -1434,6 +1481,7 @@ inferType
14341481
| overload_resolution.swift:494:12:494:12 | ms | | overload_resolution.swift:473:1:489:1 | MultiSubscript |
14351482
| overload_resolution.swift:494:12:494:22 | call to get(_:) | | file://:0:0:0:0 | Int |
14361483
| overload_resolution.swift:494:19:494:19 | a | | file://:0:0:0:0 | String |
1484+
| protocols.swift:5:8:5:8 | self | | protocols.swift:3:1:6:1 | Self [Shape] |
14371485
| protocols.swift:9:7:9:7 | self | | protocols.swift:8:1:20:1 | Circle |
14381486
| protocols.swift:9:7:9:7 | self | | protocols.swift:8:1:20:1 | Circle |
14391487
| protocols.swift:9:7:9:7 | self | | protocols.swift:8:1:20:1 | Circle |
@@ -1480,6 +1528,8 @@ inferType
14801528
| protocols.swift:43:7:43:7 | a2 | | file://:0:0:0:0 | Double |
14811529
| protocols.swift:43:12:43:12 | r | | protocols.swift:22:1:36:1 | Rectangle |
14821530
| protocols.swift:43:12:43:19 | call to area() | | file://:0:0:0:0 | Double |
1531+
| protocols.swift:51:8:51:8 | self | | protocols.swift:48:1:54:1 | Self [Container] |
1532+
| protocols.swift:53:8:53:8 | self | | protocols.swift:48:1:54:1 | Self [Container] |
14831533
| protocols.swift:58:7:58:7 | self | | protocols.swift:56:1:74:1 | IntContainer |
14841534
| protocols.swift:58:7:58:7 | self | | protocols.swift:56:1:74:1 | IntContainer |
14851535
| protocols.swift:58:7:58:7 | self | | protocols.swift:56:1:74:1 | IntContainer |
@@ -1504,6 +1554,8 @@ inferType
15041554
| protocols.swift:79:7:79:7 | cnt | | file://:0:0:0:0 | Int |
15051555
| protocols.swift:79:13:79:13 | ic | | protocols.swift:56:1:74:1 | IntContainer |
15061556
| protocols.swift:79:13:79:22 | call to count() | | file://:0:0:0:0 | Int |
1557+
| protocols.swift:86:8:86:8 | self | | protocols.swift:84:1:87:1 | Self [Printable] |
1558+
| protocols.swift:91:8:91:8 | self | | protocols.swift:89:1:92:1 | Self [Identifiable] |
15071559
| protocols.swift:94:7:94:7 | self | | protocols.swift:94:1:113:1 | Entity |
15081560
| protocols.swift:95:7:95:7 | self | | protocols.swift:94:1:113:1 | Entity |
15091561
| protocols.swift:95:7:95:7 | self | | protocols.swift:94:1:113:1 | Entity |
@@ -1559,6 +1611,8 @@ inferType
15591611
| type_constraints.swift:16:21:16:21 | 7 | | file://:0:0:0:0 | Int |
15601612
| type_constraints.swift:17:18:17:18 | a | | file://:0:0:0:0 | String |
15611613
| type_constraints.swift:17:23:17:23 | z | | file://:0:0:0:0 | String |
1614+
| type_constraints.swift:24:8:24:8 | self | | type_constraints.swift:22:1:25:1 | Self [Displayable2] |
1615+
| type_constraints.swift:29:8:29:8 | self | | type_constraints.swift:27:1:30:1 | Self [Sortable] |
15621616
| type_constraints.swift:33:7:33:7 | self | | type_constraints.swift:32:1:51:1 | TaggedItem |
15631617
| type_constraints.swift:33:7:33:7 | self | | type_constraints.swift:32:1:51:1 | TaggedItem |
15641618
| type_constraints.swift:33:7:33:7 | self | | type_constraints.swift:32:1:51:1 | TaggedItem |
@@ -1674,6 +1728,7 @@ inferType
16741728
| type_constraints.swift:95:12:95:12 | sp | U | file://:0:0:0:0 | String |
16751729
| type_constraints.swift:95:12:95:40 | call to isSecondSmaller(than:) | | file://:0:0:0:0 | Bool |
16761730
| type_constraints.swift:95:37:95:37 | z | | file://:0:0:0:0 | String |
1731+
| type_constraints.swift:103:8:103:8 | self | | type_constraints.swift:100:1:104:1 | Self [ElementContainer] |
16771732
| type_constraints.swift:108:7:108:7 | self | | type_constraints.swift:106:1:119:1 | IntArray |
16781733
| type_constraints.swift:108:7:108:7 | self | | type_constraints.swift:106:1:119:1 | IntArray |
16791734
| type_constraints.swift:108:7:108:7 | self | | type_constraints.swift:106:1:119:1 | IntArray |
@@ -1757,6 +1812,7 @@ inferType
17571812
| type_constraints.swift:214:7:214:7 | hl | | file://:0:0:0:0 | String |
17581813
| type_constraints.swift:214:12:214:12 | truck | | type_constraints.swift:186:1:201:1 | Truck |
17591814
| type_constraints.swift:214:12:214:23 | call to haul() | | file://:0:0:0:0 | String |
1815+
| type_constraints.swift:221:15:221:15 | self | | type_constraints.swift:219:1:222:1 | Self [Summable] |
17601816
| type_constraints.swift:229:7:229:7 | self | | type_constraints.swift:228:1:240:1 | Accumulator |
17611817
| type_constraints.swift:229:7:229:7 | self | | type_constraints.swift:228:1:240:1 | Accumulator |
17621818
| type_constraints.swift:229:7:229:7 | self | | type_constraints.swift:228:1:240:1 | Accumulator |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| generics.swift:240:23:241:1 | // $ type=v2:Int target=callBaz\n | Missing result: type=v2:Int |

0 commit comments

Comments
 (0)