Skip to content

Commit e48bffc

Browse files
committed
Remove unchecked cast for self types. Add self type scope to BodyResolveContext
1 parent 270f2f3 commit e48bffc

File tree

4 files changed

+20
-18
lines changed

4 files changed

+20
-18
lines changed

compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,30 @@ class JustSelfAnnotation {
88
@Self
99
class ReturnType {
1010
fun returnTypeWithVal(): Self {
11-
val res: Self = this <!UNCHECKED_CAST!>as Self<!>
11+
val res: Self = this as Self
1212
return res
1313
}
1414
}
1515

1616
@Self
1717
class ReturnTypeWithTypeParameter<T> {
1818
fun returnType(): Self {
19-
return this <!UNCHECKED_CAST!>as Self<!>
19+
return this as Self
2020
}
2121
}
2222

2323
@Self
2424
class ReturnTypeWithTypeParameters<T, A, F> {
2525
fun returnType(): Self {
26-
return this <!UNCHECKED_CAST!>as Self<!>
26+
return this as Self
2727
}
2828
}
2929

3030
class InnerClass {
3131
@Self
3232
inner class Inner {
3333
fun returnType(): Self {
34-
return this <!UNCHECKED_CAST!>as Self<!>
34+
return this as Self
3535
}
3636
}
3737
}
@@ -40,7 +40,7 @@ class StaticClass {
4040
@Self
4141
class Static {
4242
fun returnType(): Self {
43-
return this <!UNCHECKED_CAST!>as Self<!>
43+
return this as Self
4444
}
4545
}
4646
}
@@ -54,7 +54,7 @@ class InnerSelfClass {
5454
}
5555

5656
fun returnType(): Self {
57-
return this <!UNCHECKED_CAST!>as Self<!>
57+
return this as Self
5858
}
5959

6060
fun returnSelfClassType(): InnerSelfClass.Self {
@@ -68,7 +68,7 @@ class TypeAliasSelf {
6868
typealias Self = String
6969

7070
fun returnType(): Self {
71-
return this <!UNCHECKED_CAST!>as Self<!>
71+
return this as Self
7272
}
7373

7474
fun returnTypealias(): TypeAliasSelf.Self {

compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.expressions.FirOperation
1717
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
1818
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
1919
import org.jetbrains.kotlin.fir.types.coneType
20+
import org.jetbrains.kotlin.fir.types.toSymbol
21+
import org.jetbrains.kotlin.name.SpecialNames
2022

2123
object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
2224
override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -38,7 +40,12 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
3840
} else if (castType == CastingType.Always) {
3941
reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context)
4042
} else if (isCastErased(actualType, targetType, context)) {
41-
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
43+
44+
val isTargetTypeSelf = targetType.toSymbol(session)?.toLookupTag()?.name.let { it == SpecialNames.SELF_TYPE }
45+
val isTargetTypeTypeArg = actualType.typeArguments.contains(targetType)
46+
47+
if (!(isTargetTypeTypeArg && isTargetTypeSelf))
48+
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
4249
}
4350
} else if (expression.operation == FirOperation.IS) {
4451
if (isCastErased(actualType, targetType, context)) {

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
3232
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
3333
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
3434
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
35+
import org.jetbrains.kotlin.fir.scopes.impl.FirSelfTypeScope
3536
import org.jetbrains.kotlin.fir.scopes.impl.FirWhenSubjectImportingScope
3637
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
3738
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
@@ -445,12 +446,15 @@ class BodyResolveContext(
445446
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
446447

447448
val typeParameterScope = (owner as? FirRegularClass)?.typeParameterScope()
449+
val selfTypeScope: FirSelfTypeScope? =
450+
owner.annotations.find { it.fqName(holder.session)?.asString() == "kotlin.Self" }?.let { FirSelfTypeScope(owner) }
448451

449452
val forMembersResolution =
450453
staticsAndCompanion
451454
.addReceiver(labelName, towerElementsForClass.thisReceiver)
452455
.addContextReceiverGroup(towerElementsForClass.contextReceivers)
453456
.addNonLocalScopeIfNotNull(typeParameterScope)
457+
.addNonLocalScopeIfNotNull(selfTypeScope)
454458

455459
val scopeForConstructorHeader =
456460
staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope)

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,10 @@ open class FirBodyResolveTransformer(
6868
} else {
6969

7070
typeResolverTransformer.withFile(context.file) {
71-
72-
val selfAnnotation =
73-
context.topClassDeclaration?.annotations?.find { it.fqName(session)?.asString() == "kotlin.Self" }
74-
val scopes =
75-
if (context.topClassDeclaration != null && selfAnnotation != null)
76-
listOf(FirSelfTypeScope(context.topClassDeclaration!!)) + components.createCurrentScopeList()
77-
else
78-
emptyList()
79-
8071
transformTypeRef(
8172
typeRef,
8273
ScopeClassDeclaration(
83-
scopes,
74+
components.createCurrentScopeList(),
8475
context.containingClassDeclarations,
8576
context.containers.lastOrNull { it is FirTypeParameterRefsOwner && it !is FirAnonymousFunction }
8677
)

0 commit comments

Comments
 (0)