Skip to content

Fix resolution of candidates with empty intersections#6520

Open
Kirill Rakhman (cypressious) wants to merge 4 commits into
masterfrom
krakhman/empty_intersection
Open

Fix resolution of candidates with empty intersections#6520
Kirill Rakhman (cypressious) wants to merge 4 commits into
masterfrom
krakhman/empty_intersection

Conversation

@cypressious

Copy link
Copy Markdown
Contributor
  • [Tests] Reproduce #KT-86740
  • [FIR] Fix resolution of candidates with empty intersection warning
  • [FE] Move OnlyForDefaultLanguageFeatureDisabled to core.language.version-settings
  • [FE] Mark RESOLVED_NEED_PRESERVE_COMPATIBILITY with OnlyForDefaultLanguageFeatureDisabled

^RCA: The applicability of InferredEmptyIntersectionDiagnostic was
previously always INAPPLICABLE. When a callable reference resolved to a
candidate with only this diagnostic, it would be marked as unsuccesful
and in FirCallResolver.resolveCallableReference an early return would
happen before the call to
containingCallCS.replaceContentWith(chosenCandidate.system.currentStorage()).

As a result, constraints that were created during the resolution of the
callable reference would be lost. This isn't usually a problem because
the candidate is unsuccessful anyway and we would expect the code
to be red (or a different candidate to be chosen). However,
InferredEmptyIntersectionDiagnostic is only mapped to a warning
when ForbidInferringTypeVariablesIntoEmptyIntersection is disabled
(which it currently is).

As a result, the code is wrongly green and the compiler (maybe?)
crashes in the backend.

The handling of constraint systems of callable references was changed
in KT-73771 which made the bug observable. However, the real cause
is b64cb67 when the logic was
implemented to "downgrade" InferredEmptyIntersectionDiagnostic to
warnings.

As a fix, the applicability of InferredEmptyIntersectionDiagnostic
is set to RESOLVED_LOW_PRIORITY when it only leads to a warning.

The reason why RESOLVED_LOW_PRIORITY is used instead of RESOLVED is
because this diagnostic previously affected overload selection, and we
want to prevent a breaking change in the form of introduced
OVERLOAD_RESOLUTION_AMBIGUITYs.

If an empty intersection leads to an error is additionally determined
by its EmptyIntersectionTypeKind. This logic, which is also used in
NewConstraintSystemImpl, is extracted to a helper
EmptyIntersectionTypeKind.isError to prevent drift.

This fix leads to red->green changes when there are multiple candidates,
one has only an empty intersection warning, and the rest is otherwise
inapplicable. Previously NONE_APPLICABLE would be reported, after the
fix the candidate with the empty intersection warning is chosen.
(see kt52393.kt and kt52431.kt)

Because of this, a LF targeted to 2.5 is introduced to toggle the fix.

#KT-86740 Fixed
…ion-settings

... and allow providing more than one feature
@kotlin-safemerge

Copy link
Copy Markdown

Code Owners

RuleOwnersApproval
/​compiler/​fir/​, /​compiler/​resolution.​common/​, /​compiler/​resolution/​, /​compiler/​testData/​diagnostics/​, /​core/​language.​version-​settings/​
kotlin-frontend

UNASSIGNED
/​core/​language.​version-​settings/​src/​org/​jetbrains/​kotlin/​config/​LanguageVersionSettings.​kt
kotlin-language-evolution

UNASSIGNED

@cypressious

Copy link
Copy Markdown
Contributor Author

/dry-run

@KotlinBuild

Build Server (KotlinBuild) commented Jul 3, 2026

Copy link
Copy Markdown

THIS IS A DRY RUN

Quality gate is triggered at https://buildserver.labs.intellij.net/build/993138263 — use this link to get full insight.

Quality gate was triggered with the following revisions:

kotlin
Branch: refs/merge/GITHUB-6520/safe-merge
Commit: 7a07f9c


Quality gate failed. See https://buildserver.labs.intellij.net/build/993138263 to get full insight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants