Shared, type inference: Add inference for type parameters with constraints (base type mentions)#19102
Conversation
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
Files not reviewed (1)
- shared/typeinference/codeql/typeinference/internal/TypeInference.qll: Language not supported
Tip: Copilot only keeps its highest confidence comments to reduce noise and keep you focused. Learn more
|
DCA is not looking good. I think maybe the change to |
c6ad485 to
ba9edf8
Compare
|
I can't get DCA to work right now, but when running locally on Edit: DCA is working again and the results are now fine. |
hvitved
left a comment
There was a problem hiding this comment.
Impressive work, very nice! My comments are mostly minor; one thing that I note is that by introducing the pathToSub generalization, we add even more assumptions about covariance, but we already have a follow-up task about handling contravariance properly.
| * of `Mid`, | ||
| * - ``C`1`` is mentioned at `0` for immediate base type mention `Mid<C<T4>>` | ||
| * - ``C`1`` is mentioned at `T3` for immediate base type mention `Mid<C<T4>>` | ||
| * of `Sub`, and |
| * of `Sub`, and | ||
| * - ``C`1`` is mentioned at `0` and implicitly at `0.0` for transitive base type | ||
| * - `T4` is mentioned at `T3.T1` for immediate base type mention `Mid<C<T4>>` | ||
| * of `Sub`, and |
| * - `T4` is mentioned at `T3.T1` for immediate base type mention `Mid<C<T4>>` | ||
| * of `Sub`, and | ||
| * - ``C`1`` is mentioned at `T2` and implicitly at `T2.T1` for transitive base type | ||
| * mention `Base<C<T3>>` of `Sub`. |
| exists(Declaration target | | ||
| /** | ||
| * Holds if inferring types at `a` might depend on the type at `apos` | ||
| * having `baseMention` as a transitive base type mention. |
There was a problem hiding this comment.
Should be
having `base` as a transitive base type.
| not t = immediateBase.getATypeParameter() and | ||
| baseTypeMentionHasTypeAt(immediateBase, baseMention, path, t) |
There was a problem hiding this comment.
This pattern (and the dual) appears twice, so I think it perhaps still makes sense to have the predicates baseTypeMentionHasNonTypeParameterAt and baseTypeMentionHasTypeParameterAt, which then simply call baseTypeMentionHasTypeAt and add appropriate restrictions.
| * For this example | ||
| * ```csharp | ||
| * interface IFoo<A> { } | ||
| * void M<T1, T2>(T2 item) where T2 : IFoo<T1> { } |
There was a problem hiding this comment.
Perhaps change the return type from void to T1, to make it an example where type inference would actually be relevant.
| * - `path1 = ""`, | ||
| * - `tp1 = T2`, | ||
| * - `constraint = IFoo`, | ||
| * - `path2 = "A"`, |
| * - `tp1 = T2`, | ||
| * - `constraint = IFoo`, | ||
| * - `path2 = "A"`, | ||
| * - `tp2 = T1` |
| * type of `a` at position `apos` at path `pathToSub`, and `t` is | ||
| * mentioned (implicitly) at `path` inside `base`. For example, in | ||
| * | ||
| * ```csharp |
There was a problem hiding this comment.
The example should mention that pathToSub = "". Perhaps it would also be worth adding an example where pathToSub != ""?
There was a problem hiding this comment.
For now I've just mentioned pathToSub = "". I think adding another example is a good idea. Now that relevantAccess is added perhaps the existing example needs revamping as well? Now the predicate only finds the supertypes when necessary, and ToString probably doesn't need to do that?
| ) | ||
| } | ||
|
|
||
| /** Similar to `baseTypeMentionHasTypeAt` but FIXME: */ |
There was a problem hiding this comment.
Fine to simply the remove the QL doc.
| /** | ||
| * Holds if inferring types at `a` might depend on the type at `path` of | ||
| * `apos` having `baseMention` as a transitive base type mention. | ||
| * `apos` having `base` as a transitive base type mention. |
The first commit in this PR is a small refactor that tries to:
baseTypeMentionHasTypeParameterAtandbaseTypeMentionHasNonTypeParameterAtinto a single predicate, to cut down some duplication.hasBaseTypeMentionby restrict theTypeMentions that it considers. On the type inference test database this refactor changes the number of tuples from126 + 381 + 66 = 573to0 + 62 + 0 = 62in that predicate, with no change to the results.In addition the PR improves type inference for calls that target functions with type parameters that have trait bounds. For instance, when calling a function like
the new
typeParameterConstraintHasTypeParameterhandles inferringT1. It does this by noticingT1appears inside another type parameterT2,T2occurs inside the declared type ofxat the pathT,Tas a base type mention ofMyTrait<T1>and inferringT1from that.