What is the difference between my variable name and 'it' when using 'let' in kotlin?

Viewed 237

In the following code snippet, what is the difference between the two Codeblocks?
If I check with println(name==it), that returns true, so they must be referencing the same object, right?

However, when the name variable has a value, everything works, but once I set it to null, Codeblock 1 works (meaning, the let block simply will not be executed), but Codeblock 2 throws an error. Why does kotlin not just skip/ignore Codeblock 2, when nameis null?

fun main() {
    
    var name:String? = "Cedric"
    //name = null
    
    //Codeblock 1
    name?.let{
        println("The length of name is ${name.length}")
    }
    
    //Codeblock 1
    name?.let{
        println("The length of name is ${it.length}")
    }
    
}

Thank you very much, any help is appreciated.

2 Answers

Code block 2 actually gives a compile-time error, while code block 1 doesn't. I think it's just a weird linting bug, as the two cases should be treated the same.

As I understand this, you discovered bug in compiler. I have two different behaviors in Android studio and in IntelliJ. In case when it is compiled, compiled code is optimized and it looks like this when it is decompiled:

   public final void main() {
      Object name = "Cedric";
      name = (String)null;
   }

In case when it is not compiled I get an error:

org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Failed to generate expression: KtNameReferenceExpression
File being compiled: (12,45) in D:/Projekti/kotlin playground/src/Main.kt
The root cause java.lang.AssertionError was thrown at: org.jetbrains.kotlin.codegen.ExpressionCodegen.visitSimpleNameExpression(ExpressionCodegen.java:1797)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:326)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:286)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.visitDotQualifiedExpression(ExpressionCodegen.java:3258)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.visitDotQualifiedExpression(ExpressionCodegen.java:112)
    at org.jetbrains.kotlin.psi.KtDotQualifiedExpression.accept(KtDotQualifiedExpression.kt:32)
    at org.jetbrains.kotlin.codegen.CodegenStatementVisitor.visitKtElement(CodegenStatementVisitor.java:31)
    at org.jetbrains.kotlin.codegen.CodegenStatementVisitor.visitKtElement(CodegenStatementVisitor.java:22)
    at org.jetbrains.kotlin.psi.KtVisitor.visitExpression(KtVisitor.java:182)
    at org.jetbrains.kotlin.psi.KtVisitor.visitQualifiedExpression(KtVisitor.java:286)
    at org.jetbrains.kotlin.psi.KtVisitor.visitDotQualifiedExpression(KtVisitor.java:302)
    at org.jetbrains.kotlin.psi.KtDotQualifiedExpression.accept(KtDotQualifiedExpression.kt:32)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:304)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genStatement(ExpressionCodegen.java:409)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:366)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeAppend(ExpressionCodegen.java:4108)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeAppendForEntries(ExpressionCodegen.java:874)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.lambda$visitStringTemplateExpression$6(ExpressionCodegen.java:864)
    at org.jetbrains.kotlin.codegen.OperationStackValue.putSelector(StackValue.kt:79)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:122)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:115)
    at org.jetbrains.kotlin.codegen.CallGenerator$DefaultCallGenerator.genValueAndPut(CallGenerator.kt:71)
    at org.jetbrains.kotlin.codegen.CallBasedArgumentGenerator.generateExpression(CallBasedArgumentGenerator.kt:42)
    at org.jetbrains.kotlin.codegen.ArgumentGenerator.generate(ArgumentGenerator.kt:68)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeMethodWithArguments(ExpressionCodegen.java:2534)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeMethodWithArguments(ExpressionCodegen.java:2506)
    at org.jetbrains.kotlin.codegen.Callable$invokeMethodWithArguments$1.invoke(Callable.kt:41)
    at org.jetbrains.kotlin.codegen.Callable$invokeMethodWithArguments$1.invoke(Callable.kt:13)
    at org.jetbrains.kotlin.codegen.OperationStackValue.putSelector(StackValue.kt:79)
    at org.jetbrains.kotlin.codegen.StackValueWithLeaveTask.putSelector(StackValue.kt:67)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:122)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:115)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.putStackValue(ExpressionCodegen.java:386)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:367)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.returnExpression(ExpressionCodegen.java:1731)
    at org.jetbrains.kotlin.codegen.FunctionGenerationStrategy$FunctionDefault.doGenerateBody(FunctionGenerationStrategy.java:64)
    at org.jetbrains.kotlin.codegen.ClosureGenerationStrategy.doGenerateBody(ClosureGenerationStrategy.kt:35)
    at org.jetbrains.kotlin.codegen.FunctionGenerationStrategy$CodegenBased.generateBody(FunctionGenerationStrategy.java:84)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethodBody(FunctionCodegen.java:654)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethodBody(FunctionCodegen.java:479)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:261)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:177)
    at org.jetbrains.kotlin.codegen.ClosureCodegen.generateClosureBody(ClosureCodegen.java:181)
    at org.jetbrains.kotlin.codegen.ClosureCodegen.generateBody(ClosureCodegen.java:169)
    at org.jetbrains.kotlin.codegen.MemberCodegen.generate(MemberCodegen.java:129)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genClosure(ExpressionCodegen.java:1038)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genClosure(ExpressionCodegen.java:1008)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.visitLambdaExpression(ExpressionCodegen.java:999)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.visitLambdaExpression(ExpressionCodegen.java:112)
    at org.jetbrains.kotlin.psi.KtLambdaExpression.accept(KtLambdaExpression.java:40)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:304)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:286)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:358)
    at org.jetbrains.kotlin.codegen.CallGenerator$DefaultCallGenerator.genValueAndPut(CallGenerator.kt:70)
    at org.jetbrains.kotlin.codegen.CallBasedArgumentGenerator.generateExpression(CallBasedArgumentGenerator.kt:42)
    at org.jetbrains.kotlin.codegen.ArgumentGenerator.generate(ArgumentGenerator.kt:68)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeMethodWithArguments(ExpressionCodegen.java:2534)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeMethodWithArguments(ExpressionCodegen.java:2506)
    at org.jetbrains.kotlin.codegen.Callable$invokeMethodWithArguments$1.invoke(Callable.kt:41)
    at org.jetbrains.kotlin.codegen.Callable$invokeMethodWithArguments$1.invoke(Callable.kt:13)
    at org.jetbrains.kotlin.codegen.OperationStackValue.putSelector(StackValue.kt:79)
    at org.jetbrains.kotlin.codegen.CoercionValue.putSelector(StackValue.kt:31)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:122)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:115)
    at org.jetbrains.kotlin.codegen.StackValue$StackValueWithSimpleReceiver.putReceiver(StackValue.java:2089)
    at org.jetbrains.kotlin.codegen.StackValueWithLeaveTask.putReceiver(StackValue.kt:63)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:120)
    at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:115)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.putStackValue(ExpressionCodegen.java:386)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:367)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.returnExpression(ExpressionCodegen.java:1731)
    at org.jetbrains.kotlin.codegen.FunctionGenerationStrategy$FunctionDefault.doGenerateBody(FunctionGenerationStrategy.java:64)
    at org.jetbrains.kotlin.codegen.FunctionGenerationStrategy$CodegenBased.generateBody(FunctionGenerationStrategy.java:84)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethodBody(FunctionCodegen.java:654)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethodBody(FunctionCodegen.java:479)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:261)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:177)
    at org.jetbrains.kotlin.codegen.FunctionCodegen.gen(FunctionCodegen.java:148)
    at org.jetbrains.kotlin.codegen.MemberCodegen.genSimpleMember(MemberCodegen.java:197)
    at org.jetbrains.kotlin.codegen.PackagePartCodegen.generateBody(PackagePartCodegen.java:95)
    at org.jetbrains.kotlin.codegen.MemberCodegen.generate(MemberCodegen.java:129)
    at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generateFile(PackageCodegenImpl.java:145)
    at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generate(PackageCodegenImpl.java:70)
    at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generatePackage(CodegenFactory.kt:88)
    at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generateModule(CodegenFactory.kt:67)
    at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.compileCorrectFiles(KotlinCodegenFacade.java:35)
    at org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow$Companion.compileSingleFile(KotlinBytecodeToolWindow.kt:335)
    at org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow$Companion.getBytecodeForFile(KotlinBytecodeToolWindow.kt:248)
    at org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow$UpdateBytecodeToolWindowTask.processRequest(KotlinBytecodeToolWindow.kt:127)
    at org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow$UpdateBytecodeToolWindowTask.processRequest(KotlinBytecodeToolWindow.kt:74)
    at org.jetbrains.kotlin.idea.util.LongRunningReadTask$1$1.run(LongRunningReadTask.java:115)
    at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:869)
    at org.jetbrains.kotlin.idea.util.LongRunningReadTask.lambda$runWithWriteActionPriority$0(LongRunningReadTask.java:235)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:166)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:627)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:572)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:61)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:153)
    at org.jetbrains.kotlin.idea.util.LongRunningReadTask.runWithWriteActionPriority(LongRunningReadTask.java:235)
    at org.jetbrains.kotlin.idea.util.LongRunningReadTask$1.run(LongRunningReadTask.java:110)
    at com.intellij.util.RunnableCallable.call(RunnableCallable.java:20)
    at com.intellij.util.RunnableCallable.call(RunnableCallable.java:11)
    at com.intellij.openapi.application.impl.ApplicationImpl$1.call(ApplicationImpl.java:255)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.AssertionError: Couldn't find descriptor for 'length'
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.visitSimpleNameExpression(ExpressionCodegen.java:1797)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.visitSimpleNameExpression(ExpressionCodegen.java:112)
    at org.jetbrains.kotlin.psi.KtNameReferenceExpression.accept(KtNameReferenceExpression.kt:59)
    at org.jetbrains.kotlin.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:304)
    ... 105 more

It looks like compiler does not follow optimization of code. So even if it should or should not compile, there are two different behaviors which means that one of those is not correct.

Related