This problem is only relevant when isTypeRefinementEnabled == true (HMPP projects)
Ambiguity accidentally was removed after 471134d
There, for areCallableDescriptorsEquivalent we stopped assuming
as impossible a situation of having identity-different descriptors
in the same containing declaraton that still might be considered equal
So, before 471134d we were comparing
"fun foo(x: String)" with "[substituted] fun foo(x: String)"
and areCallableDescriptorsEquivalent returned false for such case.
Thus, both overrides were left in the resulting set.
After 471134d, those two descriptors
becamed considered as equal thus having a possibility to remove any of them.
The problem is that "areCallableDescriptorsEquivalent" has kind of
unclear contract. Effectively it checks whether two descriptors match
to the same declaration.
But some of the usages expect that it also makes sure that descriptors
have the same substitution (see org.jetbrains.kotlin.resolve.calls.smartcasts.IdentifierInfo.Variable#equals)
So, the straight solution is using original descriptors for the cases
where we need to make sure that descriptors relates to actually different
declarations
^KT-34027 Fixed
The changes introduced 471134d31e are only needed
for the case of HMPP project while for other cases it might break the behavior
a bit like in KT-34027
See org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver#filterOutEquivalentCalls
Before 471134d we were comparing
"fun foo(x: String)" with "[substituted] fun foo(x: String)"
and areCallableDescriptorsEquivalent returned false for such case.
Thus, both overrides were left in the resulting set.
After 471134d, those two descriptors
becamed considered as equal thus having a possibility to remove any of them.
The problem is that "areCallableDescriptorsEquivalent" has kind of
unclear contract. Effectively it checks whether two descriptors match
to the same declaration
But straightforward fixing of this exact call-site (using original descriptors)
doesn't help: behavior might change in a very subtle way (see org.jetbrains.kotlin.spec.checkers.DiagnosticsTestSpecGenerated.NotLinked.Dfa.Pos#test72)
So, the main idea is changing the contract for areCallableDescriptorsEquivalent
only when project is HMPP one.
^KT-34027 In Progress
This call was needed at some point for smartcasts on qualified
expressions but become obsolete (most likely after
daa27016ca).
Now `ComplexDataFlowBenchmark` has similar results for NI and OI
Relates to KT-8834, we continue reducing differences between old and new
inference. Note that as for `SamConversionPerArgument`, this feature
is enabled in the compiler and not in the IDE to avoid breaking code
for those users that already enabled new inference in the compiler
Bug was introduced in b99efb because of lack of tests.
All code in `AbstractTypeCheckerContextForConstraintSystem.extractTypeVariableForSubtype`
related to IN projection looks suspicious and needs further investigation
There was a problem when we get type from type projection even if
it is a star projection what is meaningless. Now we try to fold argument
only if it's not a star projection
This commit introduces TypeConstructor.refine method.
It's implementation can be roughly split in three parts:
- trivial implementations which just return 'this': mostly, it used for
typeConstructors which can not be refined at all (e.g.
IntegerValueTypeConstructor and other special cases of constructors)
- delegating implementations which call 'refine' recursively for
component typeConstructors -- obviously, they are used in composite
typeConstructors (like IntersectionTypeConstructor)
- finally, the most interesting one is in 'AbstractTypeConstructor'
which returns lightweight wrapper called 'ModuleViewTypeConstructor'.
The idea here is to propagate refinement to supertypes without eagerly
computing them all.
VERY IMPORTANT CAVEAT of TypeConstructor.refine is that call to this
method CAN NOT add new supertypes, so returned supertypes are not
entirely "valid". See the KDoc for TypeConstructor.refine for details
Candidate ordering should be the same in ordinary Kotlin code and in evaluated expressions.
With the invention of 'foo_field' syntax, there is no need to do these nasty things any more.
If new inference is enabled only for IDE analysis, then this feature
will be disabled to reduce difference between new and old inference,
but if new inference is enabled in the compiler, then this feature
will be enabled too to preserve behavior of new inference for
compilation
#KT-32175 Fixed
#KT-32143 Fixed
#KT-32123 Fixed
#KT-32230 Fixed
This call have interesting rules for resolution, see
`KtQualifiedExpression.elementChain` function and it's usages:
resolution results for such call can be omitted and be replaced with
some other information, while diagnostics will be reported from
builder-inference.
To mitigate this problem, we'll just skip this call from builder-inference
as such calls can't have type parameters anyway
#KT-32094 Fixed
Consider call `foo(bar())` where bar() returns some type variable `T`;
We had a contract that call `bar` can be completed without completion
of foo (type variables can be inferred from the current context) if `T`
has at least one proper lower constraint (ProperType <: T).
Indeed, new constraints can be added only as upper ones, so there is
no need to grow constraint system.
Unfortunately, we have Exact annotation that is used on return type of
elvis. Now, consider the following situation:
```
fun foo(a: Any) {}
fun bar(e: T): @Exact T
foo(bar("str"))
```
Here, because of Exact annotation, constraint with `Any`-type will be
added as an equal one => our prerequisite that there will be no new
lower constraints is false. `bar("str")` is inferred to Any in OI,
this seems conceptually wrong, but it's another topic of discussion.
In NI we can't just grow constraint system to use outer call because
of another important use-case:
```
fun <T> generic(i: Inv<T>) {}
fun test(a: Inv<*>?, b: Inv<*>) {
generic(a ?: b)
}
```
Common constraint system for these two calls can't be solved
(fundamentally) for this example, only if (a ?: b) and generic(result)
are computed separately.
So, to mitigate initial issue, we'll grow constraint system only if
there is at least one non-proper constraint.
#KT-31969 Fixed
annotationsViaActualTypeAliasFromBinary.kt is ignored because
ExpectActualRemover can't find actual for the expected constructor of
Anno now, because `ExpectedActualResolver.findActualForExpected`
incorrectly filters out actual declarations without any source file, and
Java classes loaded in the fast mode don't have any source files.
This will need to be fixed separately, probably by making
ExpectedActualResolver look for the actual class of an expected class
member first (with source file-based filtering), and then
unconditionally locating the corresponding member there
'getContributedDescriptors' isn't obliged to apply filters, inlcuding
kindFilter, and may return declarations of different kind, so we have to
call 'filterIsInstance' explicitly
It's enough to have at least one good constraint.
Note that the whole algorithm can be a bit more general:
we could check also Out<T>, In<T> and verify that T has good only
lower constraint or upper constraint, but there are questions for
types like Inv<Out<T>>, where T should have lower and upper constraints
#KT-31514 Fixed