Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GDScript] Conflict between Variable Name and Type in Unresolvable Scope #92008

Open
luckyabsoluter opened this issue May 16, 2024 · 3 comments

Comments

@luckyabsoluter
Copy link

Tested versions

v4.2.1.stable.official [b09f793]
v4.2.2.stable.official [15073af]

System information

N/A

Issue description

When declaring a variable with the syntax var a: TypeName followed by var TypeName in Godot Engine, an error is raised stating "Local variable 'TypeName' cannot be used as a type." This issue arises due to an unresolvable scope conflict where the engine cannot distinguish between TypeName as both a type and a variable.

Example Code:

func my_func():
	var a: TypeName # error
	var TypeName

Error Message:

Local variable "TypeName" cannot be used as a type.

The engine should either:

  1. Allow the declaration without raising an error, correctly differentiating between the type and the variable name.
  2. Provide a more informative error message that clearly explains the conflict and suggests using a different variable name.

Also,

var Variant
func my_func():
	var a: Variant # no error
func my_func():
	var Variant
	var a: Variant # error
func my_func():
	var a: Variant # error
	var Variant

Steps to reproduce

func my_func():
	var a: Variant # error
	var Variant

Minimal reproduction project (MRP)

N/A

@luckyabsoluter luckyabsoluter changed the title Conflict between Variable Name and Type in Unresolvable Scope [GDScript] Conflict between Variable Name and Type in Unresolvable Scope May 16, 2024
@RedMser
Copy link
Contributor

RedMser commented May 16, 2024

Allow the declaration without raising an error, correctly differentiating between the type and the variable name.

I don't think this is possible, since you can still call static functions that exist on the types (not sure if Godot currently has any?). And for the "x is y" operator, it would be ambiguous if variables could in the future store types as values.

Also for classes, it wouldn't work due to static functions and methods like .new()

@luckyabsoluter
Copy link
Author

luckyabsoluter commented May 16, 2024

@RedMser
It seems there is a misunderstanding. My argument is not that variables should be used as types. My point is that variables declared below should not be referenced above.

To clarify, please see the following example:

const Apple = preload("res://apple.gd")
func my_func() :
	var my_var: Apple
	var Apple = "pineapple"
	print(Apple)

The Apple in var my_var: Apple does not reference a variable. (currently it will raise an error)
Similarly, the Variant in var my_var: Variant is also not a variable.
It's a discussion about shadowing, an unpreferred coding practice where an identifier is covered.
Please let me know if I am misunderstood.

@dalexeev
Copy link
Member

dalexeev commented May 16, 2024

This issue arises due to an unresolvable scope conflict where the engine cannot distinguish between TypeName as both a type and a variable.

A local constant can be used as a type hint if it contains a preloaded class or enum. So while we don't support types as first-class citizens, types share the same scope as variables, constants, functions, etc. So if you declare a local identifier, then you can no longer use the same name class or global identifier, no matter what it is: a variable, a type, etc.

The only bug here is that a constant declared after use should not shadow the identifier, only produce a warning. We fixed a similar bug in #79880, I'll look at that later for types.

Also note that we recommend using PascalCase only for types and constants that contain a preloaded type. Local variables should use snake_case, so the example would not be possible if you followed the recommended style. Shadowing is also generally seen as a bad practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Up for grabs
Development

No branches or pull requests

3 participants