It's necessary because even for stable a.b.c.d we can't guarantee that
this reference will always point to the same symbol because
different capture type instantiations generate different scopes
with different resulting symbol instances.
This is mostly a revert of 2f61a2f56f
There, we erroneously assumed that we may take captured types as equal
if they are based on the same-typed projections.
Each instance of capturing defines its own captured type,
that should not be equal to any other type captured in other place.
Initial motivation was brought by FP Ultimate, where a piece of code
from the new test was found that started working differently after
recent changes.
The most obvious consequence is the change in addAllProjection.fir.kt:
one cannot use an instance as an argument when expected type
is captured type based on the same instance.
Otherwise, it would lead to CCE if we allowed to put arbitrary charsequences
to the list that initially was a MutableList<String>
All other test data changes (but addAllProjection.fir.kt and differentCapturedTypes.kt)
are irrelevant and will be fixed in the subsequent commits
When constraint system has forks in it usually we solve all of them before
starting full completion of corresponding call. But if some call with
forks was a last statement of postponed lambda, we will never call
completion for it with FULL mode. Instead of it we complete it in PARTIAL
mode and then just merge its constraint storage into storage of outer
call. So all forks from this inner call just remain unresolved inside
outer system without this fix
^KT-55966 Fixed
Instead, rely on the variable assignment analyzer to properly restrict
smart casts. This makes error messages more consistent, but otherwise
should have no effect.
If a certain type statement is true on loop entry and all continue
paths, then it is also true on exit if the condition did not reassign
the variable.
^KT-7676 tag fixed-in-k2
It's also not a backwards jump in do-while, unless it's in the loop's
condition, which is a stupid "feature" IMO. As you can probably tell
from the comments added in this commit.
`x?.y != null` does not imply that `x != null` if e.g. an argument to
`y` has reassigned `x` in the meantime.
The same is true for `x == y` and `functionWithContract(x, y)`, but
those are somewhat harder to implement since there is no easy way to
find the last node of a certain argument.
^KT-55096
In theory, forking persistent flows should be cheap because of object
reuse, so the proposal here is to start from scratch and prove
redundancy of forks on a case-by-case basis. Something something better
safe than sorry.
^KT-28333 tag fixed-in-k2
^KT-28489 tag fixed-in-k2
val c = C("...")
val d = c
if (c.x == null) return
c.x.length // c.x has type String
d.x.length // d.x -> c.x through d -> c
c = C(null) // remove alias d -> c
d.x.length // info from c.x moved to d.x
^KT-54824 Fixed
For example:
val c = C("...")
val x = c.x // alias to variable for c.x, which depends on c
if (x == null) return
// now c.x has type Any
c = C(null)
// c has been reassigned => info for c.x is no longer valid;
// c itself has never had any statements made about it, but
// we must still call removeAllAboutVariable to clear the
// dependents
Handling try/catch and break/continue is too hard here, and failing to
do that properly can create incorrect smartcast. Better be conservative
and assume all code is live.
When a looping control structure has a reassignment with an explicit
receiver, we don't need to erase its smartcast info as it has to be a
non-local property and is thus automatically unstable anyway. However,
we should still do that upon reaching the assignment itself for slightly
more precise error messages (as the property not just "could be"
reassigned, but *has been* reassigned already).
* wrong method was called from FirDataFlowAnalyzer.exitFunctionCall;
* map from function to affected properties should be keyed by symbol,
not FirFunction, as the latter may change;
* arguments of `return` and assignment statements should be visited,
as they may contain lambdas.
* Change 1.6 to 1.7 constants
* Fix SAFE_CALL_WILL_CHANGE_NULLABILITY for testData
* Change EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING to EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_ERROR
* Change NON_EXHAUSTIVE_WHEN_STATEMENT to NO_ELSE_IN_WHEN
* Fix testData for SafeCallsAreAlwaysNullable
* Change T -> T & Any in test dumps
* Change INVALID_CHARACTERS_NATIVE_WARNING -> INVALID_CHARACTERS_NATIVE_ERROR
* TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_WARNING -> TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR