Visitar URL original
Type inference: Improve base type matching by hvitved · Pull Request #22761 · github/codeql · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Type inference: Improve base type matching
  • Loading branch information
hvitved committed Oct 7, 2026
commit 468caa3ba37def5992e656b62fa187fc07e61022
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,80 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
hasNotTypeArgument(a, target, tp)
)
}

predicate baseTypeMatchAtTypeParameter(
Access a, AccessEnvironment e, AccessPosition apos, Declaration target, TypeParameter tp,
TypePath prefix, TypePath requiredPrefix
) {
exists(
TypePath pathToTypeParamInConstraint, TypePath pathToTp, TypePath pathToTypeParamInSub
|
argRootTypeSatisfiesTargetTypeCand(_, target, pragma[only_bind_into](apos), tp, pathToTp) and
SatisfiesParameterConstraint::satisfiesConstraintAtTypeParameter(MkRelevantAccess(a,
pragma[only_bind_into](apos), e),
MkRelevantTarget(target, pragma[only_bind_into](apos)), pathToTypeParamInConstraint,
pathToTypeParamInSub) and
hasNotTypeArgument(a, target, tp)
|
/*
* Example:
*
* ```swift
* class Base<B> {
* init(_ value: B) {}
* }
*
* class Derived<D>: Base<[D]> {
* init(_ value: D) { super.init([value]) }
* }
*
* func foo<T>(_ value: T, _ base: Base<T>) { }
*
* foo([2], Derived(<unknown>))
* ```
*
* - tp = T (bound by `foo`)
* - prefix = pathToTypeParamInSub = "D"
* - requiredPrefix = "Element"
* - pathToTypeParamInConstraint = "B.Element"
* - pathToTp = "B"
*/

pathToTypeParamInConstraint = pathToTp.appendInverse(requiredPrefix) and
prefix = pathToTypeParamInSub
or
/*
* Example:
*
* ```swift
* class Base<B> {
* init(_ value: B) {}
* }
*
* class Derived<D>: Base<D> {
* override init(_ value: D) { super.init(value) }
* }
*
* func foo<T>(_ value: T, _ base: Base<T?>) {}
*
* foo(2, Derived(Optional.none))
* ```
*
* - tp = T (bound by `foo`)
* - prefix = "D.Wrapped"
* - pathToTypeParamInSub = "D"
* - requiredPrefix = ""
* - pathToTypeParamInConstraint = "B"
* - pathToTp = "B.Wrapped"
*/

exists(TypePath path0 |
pathToTp = pathToTypeParamInConstraint.appendInverse(path0) and
prefix = pathToTypeParamInSub.append(path0) and
requiredPrefix = TypePath::nil()
)
)
}
}

private module AccessConstraint {
Expand Down Expand Up @@ -1745,6 +1819,16 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
)
)
or
exists(
Declaration target, TypePath prefix, TypePath requiredPrefix, TypePath suffix,
TypeParameter tp
|
AccessBaseType::baseTypeMatchAtTypeParameter(a, e, apos, target, tp, prefix,
requiredPrefix) and
typeMatch(a, e, target, requiredPrefix.appendInverse(suffix), result, tp) and
path = prefix.append(suffix)
)
or
exists(
Declaration target, TypePath prefix, TypeMention constraint,
TypePath pathToTypeParamInConstraint, TypePath pathToTypeParamInSub
Expand Down
6 changes: 3 additions & 3 deletions unified/ql/test/library-tests/type-inference/generics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,15 @@ func testDerived() {

let x = foo(false, [2], DerivedDerived([])) // $ target=foo target=DerivedDerived.init type=x@DerivedDerived<D>:Int

foo2(false, [2], DerivedDerived([])) // $ target=foo2 target=DerivedDerived.init $ MISSING: type=DerivedDerived(...)@DerivedDerived<D>:Int
foo2(false, [2], DerivedDerived([])) // $ target=foo2 target=DerivedDerived.init type=DerivedDerived(...)@DerivedDerived<D>:Int

let y = bar(false, 2, DerivedDerived([])) // $ type=y@DerivedDerived<D>:Int target=bar target=DerivedDerived.init

bar2(false, 2, DerivedDerived([])) // $ target=bar2 target=DerivedDerived.init $ MISSING: type=DerivedDerived(...)@DerivedDerived<D>:Int
bar2(false, 2, DerivedDerived([])) // $ target=bar2 target=DerivedDerived.init type=DerivedDerived(...)@DerivedDerived<D>:Int

let w = baz(false, 2, Derived(Optional.none)) // $ type=w@Derived<T1>.Optional<Wrapped>:Int target=baz target=Derived.init field=Optional.none

baz2(false, 2, Derived(Optional.none)) // $ target=baz2 target=Derived.init field=Optional.none $ MISSING: type=Derived(...)@Derived<T1>.Optional<Wrapped>:Int
baz2(false, 2, Derived(Optional.none)) // $ target=baz2 target=Derived.init field=Optional.none type=Derived(...)@Derived<T1>.Optional<Wrapped>:Int
}

// --- Generics and protocols ---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,9 @@ inferType
| generics.swift:207:15:207:17 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int |
| generics.swift:207:16:207:16 | 2 | | {EXTERNAL LOCATION} | Int |
| generics.swift:207:20:207:37 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived |
| generics.swift:207:20:207:37 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int |
| generics.swift:207:35:207:36 | ArrayLiteral | | {EXTERNAL LOCATION} | Array |
| generics.swift:207:35:207:36 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int |
| generics.swift:209:7:209:7 | y | | generics.swift:164:1:172:1 | DerivedDerived |
| generics.swift:209:7:209:7 | y | D | {EXTERNAL LOCATION} | Int |
| generics.swift:209:11:209:43 | bar(...) | | generics.swift:164:1:172:1 | DerivedDerived |
Expand All @@ -1443,7 +1445,9 @@ inferType
| generics.swift:211:8:211:12 | false | | {EXTERNAL LOCATION} | Bool |
| generics.swift:211:15:211:15 | 2 | | {EXTERNAL LOCATION} | Int |
| generics.swift:211:18:211:35 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived |
| generics.swift:211:18:211:35 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int |
| generics.swift:211:33:211:34 | ArrayLiteral | | {EXTERNAL LOCATION} | Array |
| generics.swift:211:33:211:34 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int |
| generics.swift:213:7:213:7 | w | | generics.swift:154:1:162:1 | Derived |
| generics.swift:213:7:213:7 | w | T1 | {EXTERNAL LOCATION} | Optional |
| generics.swift:213:7:213:7 | w | T1.Wrapped | {EXTERNAL LOCATION} | Int |
Expand All @@ -1463,7 +1467,9 @@ inferType
| generics.swift:215:15:215:15 | 2 | | {EXTERNAL LOCATION} | Int |
| generics.swift:215:18:215:39 | Derived(...) | | generics.swift:154:1:162:1 | Derived |
| generics.swift:215:18:215:39 | Derived(...) | T1 | {EXTERNAL LOCATION} | Optional |
| generics.swift:215:18:215:39 | Derived(...) | T1.Wrapped | {EXTERNAL LOCATION} | Int |
| generics.swift:215:26:215:38 | ... .none | | {EXTERNAL LOCATION} | Optional |
| generics.swift:215:26:215:38 | ... .none | Wrapped | {EXTERNAL LOCATION} | Int |
| generics.swift:227:22:229:3 | Block | | generics.swift:220:1:224:1 | MyProtocol2 |
| generics.swift:228:12:228:15 | self | | generics.swift:220:1:224:1 | MyProtocol2 |
| generics.swift:233:7:233:11 | value | | generics.swift:232:15:232:15 | T |
Expand Down
Loading