Before this commit, explicit extension receiver type check was performed
during found candidates analysis (together with arguments type check etc.)
Now we do it just after candidate is found, and filter the candidate
out if explicit receiver type is inappropriate.
This commit slightly changes resolve semantics,
replacing WRONG_RECEIVER with UNRESOLVED_REFERENCE in certain situations.
However, it provides significant performance boost.
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
This commit doesn't change behaviour of any inference algorithm, it
introduces opportunity to switch constraint system that is used for
overload resolution and fix problematic cases by changing one enum
entry.
Due to fundamental changes, there are cases where a new inference
algorithm reports overload resolution ambiguity errors (#KT-31670,
#KT-31758), which is correct from its point of view. However, this is
a breaking change and to really make it, we should be very confident
and have enough motivation for it, therefore, we don't change behavior
now in order to collect more examples (if there are any). And if we
find a lot of erroneous examples, we'll be able to change the behavior
quite simply
The main idea of this refactoring is to separate two usages of
`AnnotationDeserializer.resolveValue`: the one where we load annotation
argument values, and the one where we load constant values of properties
for JS/Native/Common
(`AnnotationAndConstantLoaderImpl.loadPropertyConstant`).
In the latter case, `expectedType` is the type of the property and it
can be a supertype of the actual value (e.g. see `arrayConst` in
compiler/testData/serialization/builtinsSerializer/compileTimeConstants.kt).
But in the former case, we need to check that the value conforms to the
expected type and disregard it if it's not the case, which is possible
if the annotation was recompiled separately.
#KT-28927
Ideally, the type of `IrWhen` should be provided by type inference for
a consistent behavior. `USED_AS_EXPRESSION` from CFG isn't always
consistent with type inference, unfortunately.
The behavior is now aligned with `if`. The type of `when` is kept when
it *can* be an expression, instead of whether it is used or not.
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
Previously, a lot of clients used JvmPlatform as platform-marker,
without thinking about jvmTarget.
For the sake of migration, this commits introduced so-called
UnspecifiedJvmPlatform, which can be used for a time being, but
generally, all usages should be removed in future.
This is needed because platform of the module is determined by the
suffix after last '-' in 'createModule', and for string 'test-module'
that would be 'module', which obviously doesn't make any sense.
Howwever, due to how MultiTargetPlatform was implemented, it was
possible to create platform with such name, and everything was fine
as long as no one actually tried to switch on such a malformed
"platform".
After switching to more strict TargetPlatform representation, some tests
that had been trying to create platforms with such names started failing.
Seems that it was purely a mistake introduced in the
af1264a46d, so this commit fixes it by
specifying proper module name
This is a large commit, which introduces general API for working with
abstraction of Platform.
- Add new abstraction to 'core' - SimplePlatform - which represents
exactly one platform
- Clients are strongly prohibited to create instances of SimplePlatform
by hand, instead, corresponding *Platforms abstraction should be used
(e.g. JvmPlatforms, JsPlatforms, KonanPlatforms)
- Move TargetPlatform to 'core', it represents now a collection of
SimplePlatforms
- Clients are strongly encouraged to use TargetPlatform
(not SimplePlatform) in API, to enforce checks for multiplatform
- Provide a helper-extensions to work with TargetPlatform
(in particular, for getting a specific component platform)
- Remove MultiTargetPlatform in favour of TargetPlatform
- Notably, this commit leaves another widely used duplicated abstraction,
namely, IdePlatform. For the sake sanity, removal of IdePlatform is
extracted in the separate commit.
This decouples simple data (TargetPlatform) from other subsystem-specific
logic (like default imports, built-ins, etc.).
Aside from purely aesthetic improvements, it also makes it easier
to move 'TargetPlatform' into core (see next commits)