Skip to content

Kotlin: fix cases where type variables were used out of scope #9123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

smowton
Copy link
Contributor

@smowton smowton commented May 11, 2022

  • Substitute type parameters when creating a SAM class instance that satisfies a generic instance
  • In the process, fix source-locations of SAM class instances to indicate the instantiation site, not the interface being satisfied
  • Fix generic arg extraction when Function23+ get rewritten to FunctionN in the JVM lowering
  • Fix the type-parameter-out-of-scope test to detect these situations in future

This is temporarily based on #9122 -- the real diff is smowton/codeql@smowton/admin/update-kotlin...smowton:smowton/fix/type-variable-in-scope-consistency

@smowton smowton requested review from a team as code owners May 11, 2022 20:13
@github-actions github-actions bot added the Java label May 11, 2022
@smowton smowton added the no-change-note-required This PR does not need a change note label May 11, 2022
// References to SomeGeneric<T1, T2, ...> where SomeGeneric is declared SomeGeneric<T1, T2, ...> are extracted
// as if they were references to the unbound type SomeGeneric.
val extractedTypeArgs = when {
c.symbol.isKFunction() && typeArgs != null && typeArgs.isNotEmpty() -> listOf(typeArgs.last())
extractClass.symbol.isKFunction() && typeArgs != null && typeArgs.isNotEmpty() -> listOf(typeArgs.last())
extractClass.fqNameWhenAvailable == FqName("kotlin.jvm.functions.FunctionN") && typeArgs != null && typeArgs.isNotEmpty() -> listOf(typeArgs.last())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test case for this? How come we didn't see this issue before? We have tests that cover big-arity functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add one -- I think we simply didn't notice or care that the type extracted was FunctionN<FirstArgumentType> not FunctionN<ReturnType>. It's probably not a critical bug but rather a weird surprise waiting for someone down the line.

@tamasvajk
Copy link
Contributor

tamasvajk commented May 12, 2022

Are the kotlin CI tests running on this PR? If not, I think it would make sense to open the PR still in the private repo.

@smowton
Copy link
Contributor Author

smowton commented May 13, 2022

@tamasvajk it appears yes they are-- in recent runs of the semmle-code job Java Language Tests Linux we see lines like

[2/8] [991/1179 comp 4.3s eval 206ms] PASSED /home/runner/work/semmle-code/semmle-code/ql/java/ql/test/kotlin/library-tests/type_equivalences/type_equivalences.ql

I believe our integration tests are not running however: I'll make a PR to fix this later today.

@smowton
Copy link
Contributor Author

smowton commented May 13, 2022

Ah no I take it back, we do run the Kotlin integration tests. To check: do we have the right file filters selecting when the integration tests run, and do we need a single-language tests job for Kotlin?

@smowton smowton force-pushed the smowton/fix/type-variable-in-scope-consistency branch from 6024ec6 to 2f55999 Compare May 13, 2022 15:10
@smowton
Copy link
Contributor Author

smowton commented May 13, 2022

@tamasvajk added a test -- if you revert the commit "Fix extracted type arguments of kotlin.jvm.functions.FunctionN" then you'll see the FunctionN type arguments change improperly (note their pretty-printed names work but the actual argument disagrees):

-| test.kt:4:5:4:138 | f1 | FunctionN<String> | String |
-| test.kt:5:5:5:134 | f2 | FunctionN<T1> | T1 |
-| test.kt:6:5:6:110 | f3 | FunctionN<T3> | T3 |
+| test.kt:4:5:4:138 | f1 | FunctionN<String> | Integer |
+| test.kt:5:5:5:134 | f2 | FunctionN<T1> | Integer |
+| test.kt:6:5:6:110 | f3 | FunctionN<T3> | T2 |

@smowton smowton force-pushed the smowton/fix/type-variable-in-scope-consistency branch from 2f55999 to 189b555 Compare May 13, 2022 17:23
@smowton
Copy link
Contributor Author

smowton commented May 13, 2022

Requires semmle-code PR https://github.com/github/semmle-code/pull/42569

smowton added 11 commits May 19, 2022 11:55
The selection of type variables mentioned in a particular class previously didn't work as intended, so the consistency query would always pass.
Otherwise references to type variables declared on kotlin.Xyz.someFunction can refer to its Java equivalent java.Xyz.someFunction if it has one.
…rameters

I had forgotten that the Java QL lib regards a ParameterizedType as either an instantiation Generic<String>, or the unbound declaration Generic<T>.
…nterface implementations

For example, in implementing Producer<T> by an actual lambda of type () -> Int, the return type should be Int, not T. This produced type-variable-out-of-scope consistency check failures.
Previously we accidentally extracted an argument type instead of the result type.
This makes debugging a little easier.
These are mainly moving the source locations and type specialisations in SAM-converted methods.
The Java extractor assigns a type with unbound type variables to the result of ImmutableSortedMap.of calls.
@smowton smowton force-pushed the smowton/fix/type-variable-in-scope-consistency branch from 6180996 to e722c99 Compare May 19, 2022 10:55
@smowton
Copy link
Contributor Author

smowton commented May 19, 2022

One test failure is expected (taken care of by the corresponding internal PR); one is an unrelated failure also affecting main.

@smowton smowton merged commit 01aaa6c into github:main May 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Java no-change-note-required This PR does not need a change note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants