Skip to content

Commit

Permalink
Remove unchecked cast for self types. Add self type scope to BodyReso…
Browse files Browse the repository at this point in the history
…lveContext
  • Loading branch information
maxim092001 committed Jun 12, 2022
1 parent 270f2f3 commit e48bffc
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 18 deletions.
14 changes: 7 additions & 7 deletions compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,30 @@ class JustSelfAnnotation {
@Self
class ReturnType {
fun returnTypeWithVal(): Self {
val res: Self = this <!UNCHECKED_CAST!>as Self<!>
val res: Self = this as Self
return res
}
}

@Self
class ReturnTypeWithTypeParameter<T> {
fun returnType(): Self {
return this <!UNCHECKED_CAST!>as Self<!>
return this as Self
}
}

@Self
class ReturnTypeWithTypeParameters<T, A, F> {
fun returnType(): Self {
return this <!UNCHECKED_CAST!>as Self<!>
return this as Self
}
}

class InnerClass {
@Self
inner class Inner {
fun returnType(): Self {
return this <!UNCHECKED_CAST!>as Self<!>
return this as Self
}
}
}
Expand All @@ -40,7 +40,7 @@ class StaticClass {
@Self
class Static {
fun returnType(): Self {
return this <!UNCHECKED_CAST!>as Self<!>
return this as Self
}
}
}
Expand All @@ -54,7 +54,7 @@ class InnerSelfClass {
}

fun returnType(): Self {
return this <!UNCHECKED_CAST!>as Self<!>
return this as Self
}

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

fun returnType(): Self {
return this <!UNCHECKED_CAST!>as Self<!>
return this as Self
}

fun returnTypealias(): TypeAliasSelf.Self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.name.SpecialNames

object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
Expand All @@ -38,7 +40,12 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
} else if (castType == CastingType.Always) {
reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context)
} else if (isCastErased(actualType, targetType, context)) {
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)

val isTargetTypeSelf = targetType.toSymbol(session)?.toLookupTag()?.name.let { it == SpecialNames.SELF_TYPE }
val isTargetTypeTypeArg = actualType.typeArguments.contains(targetType)

if (!(isTargetTypeTypeArg && isTargetTypeSelf))
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
}
} else if (expression.operation == FirOperation.IS) {
if (isCastErased(actualType, targetType, context)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
import org.jetbrains.kotlin.fir.scopes.impl.FirSelfTypeScope
import org.jetbrains.kotlin.fir.scopes.impl.FirWhenSubjectImportingScope
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
Expand Down Expand Up @@ -445,12 +446,15 @@ class BodyResolveContext(
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)

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

val forMembersResolution =
staticsAndCompanion
.addReceiver(labelName, towerElementsForClass.thisReceiver)
.addContextReceiverGroup(towerElementsForClass.contextReceivers)
.addNonLocalScopeIfNotNull(typeParameterScope)
.addNonLocalScopeIfNotNull(selfTypeScope)

val scopeForConstructorHeader =
staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,10 @@ open class FirBodyResolveTransformer(
} else {

typeResolverTransformer.withFile(context.file) {

val selfAnnotation =
context.topClassDeclaration?.annotations?.find { it.fqName(session)?.asString() == "kotlin.Self" }
val scopes =
if (context.topClassDeclaration != null && selfAnnotation != null)
listOf(FirSelfTypeScope(context.topClassDeclaration!!)) + components.createCurrentScopeList()
else
emptyList()

transformTypeRef(
typeRef,
ScopeClassDeclaration(
scopes,
components.createCurrentScopeList(),
context.containingClassDeclarations,
context.containers.lastOrNull { it is FirTypeParameterRefsOwner && it !is FirAnonymousFunction }
)
Expand Down

0 comments on commit e48bffc

Please sign in to comment.