godotengine / godot

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

Bug with lambda context #75421

Open DavidGasku opened 1 year ago

DavidGasku commented 1 year ago

Godot version

v4.0.1.stable.official [cacf49999]

System information

Ubuntu 22.04

Issue description

func _ready():
    $Button.toggled.connect(
        func(value):
            print_value_rpc.rpc_id(0, value)
#           print(self)
    )

@rpc("call_local")
func print_value_rpc(value):
    print(value)

In this code, an error is thrown: Invalid get index 'print_value_rpc' (on base: 'Nil'). I'm not sure how visiblity work with lambdas, but the fact that uncommenting the print(self) line gets rid of the error, makes me think it is a bug.

Steps to reproduce

Run the project and toggle the button, an error is thrown. Uncomment any commented line, and the error is fixed.

Minimal reproduction project

bug.zip

AThousandShips commented 1 year ago

Does this happen with functions called without rpc? It seems like it fails to treat this as a self-lambda, the engine distinguishes lambdas that invoke self and those that don't

AThousandShips commented 1 year ago

It seems there might be a missing check for RPC like this where normal function calls marks it as using self

AThousandShips commented 1 year ago

I'm not sure if this is the full solution but changing: https://github.com/godotengine/godot/blob/1222d35cdd832b3d4dfd96722d746d312e69a9bb/modules/gdscript/gdscript_analyzer.cpp#L3428-L3432

To add:

case GDScriptParser::ClassNode::Member::FUNCTION: {
    if (is_base && !base.is_meta_type) {
        p_identifier->set_datatype(make_callable_type(member.function->info));
        p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_VARIABLE;
        return;
    }

Solves it, if this is doesn't have any issues I'll open a PR for it

AThousandShips commented 1 year ago

A workaround is to just explicitly use self.print_value_rpc.rpc_id(...)

illegalFruit commented 6 days ago

Unfortunately this glitch still exists. There seems to be something wrong with RPC calls and lambda functions but its inconsistent, at least in my testing. For whatever reason, "send_username" is found no problem and works but the function immediately below it ("send chat message") that operates the exact same way fails to be located. Adding "self" to the function call does work as a fix. fun_err

illegalFruit commented 5 days ago

I did a little more troubleshooting and the lambda function works properly if inside the function itself you're referencing the tree in some way. If the "panel_main_menu.show()" is removed, the lambda function will become lost and unable to find send_username, throwing the error.