Stability fixes
diff --git a/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.fir.txt b/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.fir.txt
index 9e36ee1..8f2e737 100644
--- a/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.fir.txt
+++ b/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.fir.txt
@@ -61,3 +61,22 @@
         R|/foo6<Inapplicable(INAPPLICABLE): /foo6>#|<R|kotlin/Nothing | TypeVariable(T)|, R|kotlin/Nothing | TypeVariable(V)|>(Q|E3|, Q|E2|)
         R|/foo6<Inapplicable(INAPPLICABLE): /foo6>#|<R|kotlin/Nothing | TypeVariable(T)|, R|kotlin/Nothing | TypeVariable(V)|>(Q|E3|, Q|E3|)
     }
+    public final inline fun <T, E1 : R|kotlin/Nothing | Error|, E2 : R|kotlin/Nothing | Error|> R|T | E1|.onError(f: R|(kotlin/Nothing | E1) -> kotlin/Nothing | E2|): R|T | E2| {
+        when () {
+            (this@R|/onError| is R|kotlin/Nothing | Error|) ->  {
+                ^onError R|<local>/f|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Nothing | E2|>|(this@R|/onError|)
+            }
+            else ->  {
+                ^onError this@R|/onError|
+            }
+        }
+
+    }
+    public final fun onErrorCaller(v: R|kotlin/Int | E1|): R|kotlin/Nothing | E1| {
+        lval v2: R|kotlin/Int| = R|<local>/v|.R|/onError|<R|kotlin/Int|, R|kotlin/Nothing | E1|, R|kotlin/Nothing | TypeVariable(E2)|>(<L> = onError@fun <anonymous>(it: R|kotlin/Nothing | E1|): R|kotlin/Nothing | TypeVariable(E2)| <inline=Inline, kind=UNKNOWN>  {
+            ^onErrorCaller R|<local>/it|
+        }
+        )
+        lval v3: R|kotlin/Int| = R|<local>/v2|
+        Null(null)!!
+    }
diff --git a/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.kt b/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.kt
index 114da2a..e867625 100644
--- a/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.kt
+++ b/compiler/fir/analysis-tests/testData/resolve/rich-errors/genericCalls.kt
@@ -48,3 +48,17 @@
     <!INAPPLICABLE_CANDIDATE!>foo6<!>(E3, E2)
     <!INAPPLICABLE_CANDIDATE!>foo6<!>(E3, E3)
 }
+
+inline fun <T : Any?, E1 : KError, E2: KError> (T | E1).onError(f: (E1) -> E2): T | E2 {
+    if (this is KError) {
+        return f(this)
+    } else {
+        return this
+    }
+}
+
+fun onErrorCaller(v: Int | E1): E1 {
+    val v2 = v.onError { return it }
+    val v3: Int = v2
+    null!!
+}
diff --git a/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.fir.txt b/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.fir.txt
index 4fb65e1..e54d6ea 100644
--- a/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.fir.txt
+++ b/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.fir.txt
@@ -37,3 +37,11 @@
         public get(): R|kotlin/Int|
     public final val v52: R|kotlin/Int?| = R|/identity|<R|kotlin/Int? | E1|>(R|/neString|?.{ $subj$.R|/foo|() })
         public get(): R|kotlin/Int?|
+    public final fun foo(v: R|kotlin/Int | E1|): R|kotlin/Int| {
+        lval tmp: R|kotlin/Nothing | E1| = R|<local>/v|?.{ $subj$.R|kotlin/let|<R|kotlin/Int|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Nothing| <inline=Inline, kind=EXACTLY_ONCE>  {
+            ^foo R|<local>/it|
+        }
+        ) }
+        lval tmp2: R|kotlin/Nothing | E1| = R|<local>/tmp|
+        Null(null)!!
+    }
diff --git a/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.kt b/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.kt
index c7e0bb8..a157351 100644
--- a/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.kt
+++ b/compiler/fir/analysis-tests/testData/resolve/rich-errors/safeCall.kt
@@ -1,22 +1,28 @@
-// RUN_PIPELINE_TILL: FRONTEND
+// RUN_PIPELINE_TILL: BACKEND
 
 error object E1
 
-val nString: String? = null!!
-val eString: String | E1 = null!!
-val neString: String? | E1 = null!!
+//val nString: String? = null!!
+//val eString: String | E1 = null!!
+//val neString: String? | E1 = null!!
+//
+//fun String.foo(): Int = null!!
+//
+//fun <T : Any? | E1> identity(v: T): T = v
+//
+//val v1: Int? = nString?.foo()
+//val v2: Int | E1 = eString?.foo()
+//val v3: Int? | E1 = neString?.foo()
+//val v4: Int = <!INITIALIZER_TYPE_MISMATCH!>eString?.foo()<!>
+//val v5: Int? = <!INITIALIZER_TYPE_MISMATCH!>neString?.foo()<!>
+//val v12: Int? = identity(nString?.foo())
+//val v22: Int | E1 = identity(eString?.foo())
+//val v32: Int? | E1 = identity(neString?.foo())
+//val v42: Int = <!INITIALIZER_TYPE_MISMATCH!>identity(eString?.foo())<!>
+//val v52: Int? = <!INITIALIZER_TYPE_MISMATCH!>identity(neString?.foo())<!>
 
-fun String.foo(): Int = null!!
-
-fun <T : Any? | E1> identity(v: T): T = v
-
-val v1: Int? = nString?.foo()
-val v2: Int | E1 = eString?.foo()
-val v3: Int? | E1 = neString?.foo()
-val v4: Int = <!INITIALIZER_TYPE_MISMATCH!>eString?.foo()<!>
-val v5: Int? = <!INITIALIZER_TYPE_MISMATCH!>neString?.foo()<!>
-val v12: Int? = identity(nString?.foo())
-val v22: Int | E1 = identity(eString?.foo())
-val v32: Int? | E1 = identity(neString?.foo())
-val v42: Int = <!INITIALIZER_TYPE_MISMATCH!>identity(eString?.foo())<!>
-val v52: Int? = <!INITIALIZER_TYPE_MISMATCH!>identity(neString?.foo())<!>
+fun foo(v: Int | E1): Int {
+    val tmp = v?.let { return it }
+    val tmp2: E1 = tmp
+    null!!
+}
diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt
index ef96b1f..5cb24d1 100644
--- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt
+++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt
@@ -77,6 +77,7 @@
 
     companion object {
         fun create(valueType: ConeValueType, errorType: CEType): ConeErrorUnionType {
+            if (errorType is CEBotType) error("Unexpected")
             return ConeErrorUnionType(valueType, errorType)
         }
 
@@ -86,7 +87,7 @@
         }
 
         fun addErrorComponent(original: ConeKotlinType, errorType: CEType): ConeKotlinType {
-            if (errorType == CEBotType) return original
+            if (errorType is CEBotType) return original
 
             return when (original) {
                 is ConeFlexibleType -> {
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/utils/IrElementsCreationUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/utils/IrElementsCreationUtils.kt
index 99d30fd..b9ec115 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/utils/IrElementsCreationUtils.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/utils/IrElementsCreationUtils.kt
@@ -39,6 +39,8 @@
 import org.jetbrains.kotlin.ir.types.IrSimpleType
 import org.jetbrains.kotlin.ir.types.IrType
 import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
+import org.jetbrains.kotlin.ir.types.isAny
+import org.jetbrains.kotlin.ir.types.isNullableAny
 import org.jetbrains.kotlin.ir.types.makeNullable
 import org.jetbrains.kotlin.name.*
 
@@ -114,8 +116,8 @@
         IrGetValueImpl(startOffset, endOffset, receiverVariableSymbol),
     )
 
-    // TODO: RE: HIGH: make errorable too
-    val resultType = expressionOnNotNull.type.makeNullable()
+    val mayHaveErrors = receiverVariable.type.isAny() || receiverVariable.type.isNullableAny()
+    val resultType = if (mayHaveErrors) receiverVariable.type else expressionOnNotNull.type.makeNullable()
 
     return IrBlockImpl(startOffset, endOffset, resultType, IrStatementOrigin.SAFE_CALL).apply {
         statements += receiverVariable
@@ -123,10 +125,11 @@
             branches += IrBranchImpl(
                 conditionNull(), IrConstImpl.constNull(startOffset, endOffset, builtins.nothingNType)
             )
-            // TODO: RE: HIGH: Do not add if receiverVariable.type is not appropriate
-            branches += IrBranchImpl(
-                conditionError(), IrGetValueImpl(startOffset, endOffset, receiverVariableSymbol)
-            )
+            if (mayHaveErrors) {
+                branches += IrBranchImpl(
+                    conditionError(), IrGetValueImpl(startOffset, endOffset, receiverVariableSymbol)
+                )
+            }
             branches += IrElseBranchImpl(
                 IrConstImpl.boolean(startOffset, endOffset, builtins.booleanType, true),
                 expressionOnNotNull
diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt
index eb6a4be..034ff9d 100644
--- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt
+++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt
@@ -771,12 +771,37 @@
                     !subTs.isSubtypeOfAtomic(CEBotType)
         }
 
-        return unsatisfiedSubTs.map { it to upperType }
+        val containedVariablesSub = subTs.filter { it is CETypeVariableType }
+
+        if (unsatisfiedSubTs.isEmpty()) {
+            val containedVariablesSuper = superTs.filter { it is CETypeVariableType }
+
+            return buildList {
+                containedVariablesSub.forEach { subV ->
+                    add(subV to CETopType)
+                }
+                containedVariablesSuper.forEach { superV ->
+                    add(superV to CETopType)
+                }
+            }
+        }
+
+        val lostSubV = containedVariablesSub.filter { subV ->
+            !unsatisfiedSubTs.contains(subV)
+        }
+
+        return buildList {
+            unsatisfiedSubTs.forEach { subT ->
+                add(subT to upperType)
+            }
+            lostSubV.forEach { subV ->
+                add(subV to CETopType)
+            }
+        }
     }
 
     override fun ErrorTypeMarker.isPossibleSubtypeOf(other: ErrorTypeMarker): Boolean {
         require(this !is CEUnionType) { "Expected atomic" }
-        require(!this.isSubtypeOf(other)) { "Already a subtype" }
 
         val subT = this as CEType
         val superTs = (other as CEType).collectAtomics(mutableListOf())
diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt
index 0c9a655..4103742 100644
--- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt
+++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt
@@ -778,7 +778,7 @@
     }
 }
 
-fun CEType.toConeType(): ConeRigidType = ConeErrorUnionType.create(StandardTypes.Nothing, this)
+fun CEType.toConeType(): ConeRigidType = ConeErrorUnionType.createNormalized(StandardTypes.Nothing, this)
 
 fun ConeKotlinType.isSubtypeOf(superType: ConeKotlinType, session: FirSession, errorTypesEqualToAnything: Boolean = false): Boolean =
     AbstractTypeChecker.isSubtypeOf(
diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt
index cc8ccf9..7434579 100644
--- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt
+++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt
@@ -638,7 +638,7 @@
                                         baseModuleData,
                                         callableIdForName(it.firValueParameter.name),
                                         classIsExpect,
-                                        currentDispatchReceiverType()?.expectNonErrorClassSoft,
+                                        currentDispatchReceiverType(),
                                         context
                                     )
                                 }
diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt
index e3ee9d1..9ae4ea1 100644
--- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt
+++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt
@@ -40,6 +40,7 @@
 import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
 import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
 import org.jetbrains.kotlin.fir.types.ConeClassLikeType
+import org.jetbrains.kotlin.fir.types.ConeRigidType
 import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
 import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
 import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -117,7 +118,7 @@
         moduleData: FirModuleData,
         callableId: CallableId,
         isExpect: Boolean,
-        currentDispatchReceiver: ConeClassLikeType?,
+        currentDispatchReceiver: ConeRigidType?,
         context: Context<T>
     ): FirProperty {
         val name = this.firValueParameter.name
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt
index d4a12fd..4d10845 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt
@@ -602,7 +602,7 @@
         } else {
             valueType
         }
-        ConeErrorUnionType.create(newValueComponent, newErrorComponent)
+        ConeErrorUnionType.createNormalized(newValueComponent, newErrorComponent)
     } else {
         intersectedUpperType
     }
diff --git a/compiler/psi/src/org/jetbrains/kotlin/resolve/ModifierCheckerHelpers.kt b/compiler/psi/src/org/jetbrains/kotlin/resolve/ModifierCheckerHelpers.kt
index c9fe4b6..a123e3c 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/resolve/ModifierCheckerHelpers.kt
+++ b/compiler/psi/src/org/jetbrains/kotlin/resolve/ModifierCheckerHelpers.kt
@@ -216,7 +216,7 @@
         KotlinTarget.BACKING_FIELD
     ),
     DATA_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS, KotlinTarget.STANDALONE_OBJECT),
-    ERROR_KEYWORD to EnumSet.of(KotlinTarget.STANDALONE_OBJECT),
+    ERROR_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS, KotlinTarget.STANDALONE_OBJECT),
     INLINE_KEYWORD to EnumSet.of(
         KotlinTarget.FUNCTION,
         KotlinTarget.PROPERTY,
diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt
index b093f5b..073ccf6 100644
--- a/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt
+++ b/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt
@@ -341,7 +341,7 @@
                     preparedSubType.projectOnValue(),
                     preparedSuperType.projectOnValue(),
                     isFromNullabilityConstraint
-                )
+                ) && completeIsSubTypeOfErrors(state, botTypeOfErrors(), preparedSuperTypeUb.errorType())
             }
             preparedSubTypeLb is ErrorUnionTypeMarker && preparedSuperTypeUb is ValueTypeMarker -> {
                 completeIsSubTypeOfValues(