Static scope is checked first during resolution
(scopes are in reverse order).
This fixes a difference between how K1 and K2 resolve annotations.
#KT-63249 Fixed
This commit solves a stub type inconsistency problem.
As a part of KT-59369 fix we decided (see commit 299d2799),
that ConeStubTypeForChainInference has a scope of Any,
so we can safely resolve only to equals/hashCode/toString.
However, later we can replace a stub type with some inferred type,
which can have its own equals/hashCode/toString implementation,
while the call still refers Any member.
In this situation FIR2IR decides that we are calling a fake override,
which is not true, in fact we are calling an overriding method.
This leads to a crash in Native backend.
To solve this situation, we provide an explicit cast of a dispatch
receiver with a stub type (ConeStubTypeForChainInference) to Any,
thus confirming directly we are calling Any method and nothing else.
#KT-63932 Fixed
- Previously, only callable package name sets were implemented, because
the compiler cannot economically compute classifier package sets for
libraries. This has not changed. However, the K2 IntelliJ plugin and
standalone Analysis API can very easily compute classifier package
sets. Hence, this commit adds support to `FirSymbolNamesProvider` for
such sets.
- Similar to callable package sets, classifier package sets (1) improve
the memory usage of symbol names providers and (2) improve the
performance of `mayHaveTopLevelClassifier`, which is a significant
bottleneck in the IDE.
- In many cases, the package sets for callables and classifiers are the
same. For example, the IDE Kotlin declaration provider computes the
set of packages that contain any classifier and/or callable, for the
following reasons: (1) indexing package names without filtering for
declarations is much faster, (2) computing separate sets is not free
both in time and memory, and (3) the performance impact of having a
more narrow set for callables is expected to be negligible. For this
reason, `FirSymbolNamesProvider.getPackageNames` exists to provide a
shared package set.
- The `hasSpecific*PackageNamesComputation` properties are required to
avoid caching the same package set in cached symbol names providers
twice. Because these properties are constant, they can be checked very
quickly, and no time has to be wasted trying a specific package set
computation to find out whether it's supported.
### IDE Performance Results
Package set construction performance improved in the IDE in multiple
benchmarks. This improves the performance of symbol providers overall,
which has a direct impact on completion, code analysis, and Find Usages.
In a local manual run of the `intellij_commit/setUp` Find Usages
performance test, the total time spent in `getClassLikeSymbolByClassId`
improved from ~18.7s to ~11.2s. Due to parallel resolve, this does not
translate to a wall clock improvement of 7 seconds, but rather of a few
seconds.
Some performance tests improved markedly in warmup, with for example
`toolbox_enterprise/genUuid` Find Usages having an improvement in
`StubBasedFirDeserializedSymbolProvider.getClassLikeSymbolByClassId`
from 2.4s to 0.2s. This has a direct impact on the first-run performance
of the tested Find Usages command.
So far, classifier package sets in the IDE are only implemented for
libraries, and library sessions are cached after the first warmup.
Because the biggest impact of classifier package sets is avoiding
computation of "class names in package" sets, the impact of this
optimization is not accurately reflected in the timings reported by our
performance tests. `toolbox_enterprise/genUuid` above is a good example,
as the warmup timings are great, but after warmup,
`StubBasedFirDeserializedSymbolProvider.getClassLikeSymbolByClassId`
improved only from 150ms to 70ms.
`toolbox_enterprise/genUuid` is another example, as we can confidently
say that the first-run Find Usages performance has improved (which makes
a difference for the user), but it is unclear by how much, as warmup is
not measured in performance tests.
The same optimization for source sessions will be easier to measure, as
source sessions are invalidated after each performance test run. This
commit lays the groundwork for that as well, because source session
support only requires the requisite package set computation in the
IDE declaration provider to be implemented.
^KT-62553 fixed
'ContextCollector' is used for computing context of 'FirCodeFragment's.
Code fragments themselves might contain additional smart cast operations
that modify the context receiver stack.
^KT-63056 Fixed
Before this commit, K2 always applied coercion-to-unit for
callable references if expected type was Unit, and actual non-Unit.
However, this may not work in case when actual return type is
a type parameter and it must be inferred into Unit.
In this commit we started to disallow coercion-to-unit
for references with synthetic outer call (~ top-level in K1)
AND a type parameter as a return type (both should be true to disallow).
This provides better K1 consistency,
while still keeping some broken K1 cases working in K2.
See also added comment in CallableReferenceResolution.kt.
#KT-62565 Fixed
Previously, there was a contract that each callable symbol in the chain
of `processDirectOverriddenWithBaseScope` will be unique. And if some
symbol is accessible from multiple scopes, then only last of them will
be returned as a component of `MemberWithScope`. So there actually was
no such thing as "pair of two different MemberWithScope with the same
symbol and different scopes"
After the change of `processDirectOverriddenWithBaseScope` contract (see
previous commits) each scope returns `MemberWithScope` for some symbol
with the previous scope in the hierarchy even if it contains the same
symbol as the current scope
So now scope is actually a part of `MemberWithScope`, which should be
considered as part of equality. Otherwise, we can skip some part of
the overridden hierarchy, because we will start to consider symbol as
visited after its first occurrence (in opposite to the previous behavior,
when only the last scope was returned)
This commit is Low Level FIR part of changes around propagated
annotations (aka foreign annotations).
It includes such changes as:
* implicit type phase postpones foreign annotations resolution
* annotation arguments are requests resolution for postponed
annotations from implicit type phase as a pre-resolve step
* body resolve phase just calls lazy resolution for foreign annotations
on demand
* isResolved check for type annotations to be sure that all annotations
are resolved after annotation arguments phase
^KT-63042 Fixed
^KT-63681 Fixed
We shouldn't transform annotations not from declaration side due to
a possible different context and to avoid unexpected transformation of
unrelated declarations
Example:
```kotlin
fun implicitType1() = TopLevelObject.expectedType()
object TopLevelObject {
private const val privateConstVal = "privateConstVal"
fun expectedType(): @Anno(privateConstVal) Int = 4
}
```
Here we will try to transform the annotation from `expectedType`
during `implicitType1` and as the result, we will see unresolved
reference on the declaration side. This commit fixes this issue.
This solution is based on the fact that the compiler anyway will
resolve the propagated annotation on the declaration side.
And it doesn't matter if it is resolved before or after the call site
declaration transformation, because as a global result, we will observe
that all declarations are resolved correctly in the right context.
Hence, this commit fixes the issue in the case of "full resolution"
which is true for the compiler, but it is not correct for Low Level
FIR where we resolve declarations on demand. It will be solved in
the next commits
^KT-63042
Such annotations will be transformed as usual in `FirDeclarationsResolveTransformer.transformRegularClass`.
Also, this transformation doesn't have a corresponding class as a container
^KT-63042
Now annotations have the container symbol itself, so this property
is no longer needed.
This migration fixes issues with a missed container symbol, so now
all cases of lazy resolution from KtType are supported
^KT-63042
We should share the original instance to be able to later resolve it in
the original context. This commit returns the KT-60387 problem, but the
root cause (concurrent modification) will be fixed in the context of
KT-63042
^KT-63042
There were a number of locals where components of InitialConstraint were
named lower and upper in the FirBuilderInferenceSession.
That is not true for equality constraints, so such naming should be
avoided to avoid misconception about the nature of type relation encoded
in constraint.
^KT-64031 Fixed
The condition was added to the substitute function, when it was also
re-used in delegate inference.
However, delegate inference no longer uses this function.
It is not very possible to both have variable fixed and being present in
nonFixedToVariablesSubstitutor in builder inference.
^KT-64028 Fixed
There are two overloads of substitute function
in the FirBuilderInferenceSession.
In fact, it has very different usage and semantics.
Relates to KT-64028
Error arises from the fact that type substitution operation isn't
consistent when applied to captured types.
E.g.:
```
substitution = { A => B }
substituteOrSelf(C<CapturedType(out A)_0>) -> C<CapturedType(out B)_1>
substituteOrSelf(C<CapturedType(out A)_0>) -> C<CapturedType(out B)_2>
C<CapturedType(out B)_1> <!:> C<CapturedType(out B)_2>
```
Relates to KT-53749
Before, we were wrapping the original constraint position into
ConeBuilderInferenceSubstitutionConstraintPosition twice during the
constraint substitution in builder inference.
It was causing problems with diagnostic reporting.
Remove TODOs about diagnostic reporting from FirBuilderInferenceSession.
Propagation of errors from the common system is now implemented
Diagnostic reporting in updateCalls isn't needed, since we
report errors after the system completion unlike K1
Relates to KT-53749
Pass constraint errors from the integration system into a candidate to
make sure it is reported later.
Related to KT-59426, KT-59437, KT-53749
#KT-55168 Submitted
- Pass containingClass (helps to avoid calculations of the
containingClass in allRecursivelyOverriddenDeclarationsIncludingSelf
implementation)
- Reuse allRecursivelyOverriddenDeclarationsIncludingSelf by
DefaultArgumentsInExpectActualizedByFakeOverride &
ActualFunctionWithDefaultParameters
Review: https://jetbrains.team/p/kt/reviews/13244
Review: https://jetbrains.team/p/kt/reviews/13244
Motivation:
```
// Module :lib
class Foo {
val member: Int = 2
}
// Module :app
// dependencies { implementation(project(":lib")) }
class Foo {
val member: Int = 2
}
```
Before the commit:
app_Foo.expectForActual is `null`
app_Foo.member.expectForActual = lib_foo.member
After the commit:
app_Foo.expectForActual is `null`
app_Foo.member.expectForActual is `null`
If I don't fix this problem then
`CommonizerHierarchicalIT.testCommonizeHierarchicallyMultiModule`
becomes red after I fix KT-59887 in the following commits
`app_Foo.member.expectForActual = lib_foo.member` happens because we
also need to match fake-overrides (KT-63550)
I didn't measure it, but theoretically, this commit should be a
performance improvement, becuase we reuse `expectForActual` cache
Additionally, The commit breaks some other tests (e.g.
compiler/testData/diagnostics/tests/multiplatform/headerClass/actualMissing.fir.kt).
The tests will become green again, once I fix KT-59887
integrateConstraintToSystem and substitute functions are only used in
the FirBuilderInferenceSession
Move is needed to specialize implementation for builder inference and
avoid an introduction of accidental usages from other inference sessions
This commit actually does two things:
- Adds Any scope to stub type
- Makes CheckDispatchReceiver treat stub types
as non-null for the unsafe call check to make such candidates viable
Related to KT-59369
Previously, because we didn't handle flexible types properly in
prepareCapturedType, projections inside flexible types would only be
captured during subtyping with captureStatus=FOR_SUBTYPING
which would lead to the constraint type being wrongly approximated
(see ConstraintInjector.TypeCheckerStateForConstraintInjector
.addNewIncorporatedConstraint).
Fixing the capturing produced two kinds of false positive diagnostics:
1. In ConstraintInjector.TypeCheckerStateForConstraintInjector
.addNewIncorporatedConstraint we would get two instances of cone types
that are structurally equal and containing the same captured type.
However, because we only skipped subtyping if the types were
referentially equal, we would get a contradiction here.
The fix was to use structural equality instead, which should be okay
as the captured type instances are the same.
2. Reified type variables were inferred to captured types because
flexible arrays with captured upper bounds
(Array<Foo>..Array<Captured(out Foo)>?) were not properly approximated.
#KT-62609 Fixed
We should pass container for correct logic around CLASS_HEADER_ANNOTATIONS.
Also, such correct containers will be used in the context of KT-63042 to
correctly detect an annotation ownership
^KT-63042
^KT-63842 Fixed