godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.56k stars 21.27k forks source link

Incorrect parsing error 'Cannot use subscript operator on a base of type "null"' #98152

Open mman2112 opened 1 month ago

mman2112 commented 1 month ago

Tested versions

System information

Windows 10.0.19045 - GLES3 (Compatibility) - AMD Radeon RX 7800 XT (Advanced Micro Devices, Inc.; 31.0.24019.1006) - AMD Ryzen 7 1700 Eight-Core Processor (16 Threads)

Issue description

Godot is in some circumstances incorrectly determining that a value is "null" at parsing time. It seems to be related to using higher-order functions in conditions - Godot seems to be assuming that the function returned by the high-order function always returns false, though that doesn't entirely explain it. When this occurs, the project refuses to run, ('Cannot use subscript operator on a base of type "null"') though the code is correct.

My full source code is included in "Steps to reproduce"

As an aside, I'm using the GDscript language server, and you can also see the error within VS code image

Steps to reproduce

Created a new project, created a single Node2D, added a script to it. Script is below:

extends Node2D

func returns_callable():
    var f = func(): return true
    return f

func uses_returns_callable():
    if returns_callable().call(): # Always true
        return [1, 2, 3]
    return null

func _ready():
    var value = uses_returns_callable()
    print(value) # prints [1, 2, 3]

    # Though the following line should work, if uncommented it results in an error during parsing 
    # 'Cannot use subscript operator on a base of type "null".gdscript(-1)'
    # if value: print(value[0])

    # Curiously, if I actually replace 'var value = uses_returns_callable()` with `var value = null`
    # no parsing error is produced

Minimal reproduction project (MRP)

minimal-parser-bug-example.zip

HolonProduction commented 1 month ago

When adding -> Variant as return type to uses_returns_callable no error is produced, so for some reason the analyzer tries to infer a return type of the function instead of using Variant by default