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

Switch makes if in case an expression #11814

Open
ibilon opened this issue Nov 6, 2024 · 3 comments
Open

Switch makes if in case an expression #11814

ibilon opened this issue Nov 6, 2024 · 3 comments

Comments

@ibilon
Copy link
Member

ibilon commented Nov 6, 2024

The first addEventListener works, but in the second I wrap the if/elseif in a switch and I get the following error:

[ERROR] Test.hx:21: lines 21-23

 21 |      } else if (event.code == "ArrowRight") {
 22 |       rightKey = true;
 23 |      }
    |
    | Void should be Bool

The if now requires all its branch to unify to Bool despite not being used as an expression,
shown in the third addEventListener where I added an else with a Bool value and it works.

The fourth addEventListener has a return after the switch and the error doesn't trigger, but it seems that any statement works.

If instead of addEventListener I use a function where the argument is typed as (event:js.html.KeyboardEvent)->Void it works, but with haxe.Constraints.Function the error is present.

https://try.haxe.org/#5211741D

class Test {
	static function main() {
		var leftKey = false;
		var rightKey = true;

		js.Browser.document.addEventListener("keydown", (event:js.html.KeyboardEvent) -> {
			if (event.code == "ArrowLeft") {
				leftKey = true;
			} else if (event.code == "ArrowRight") {
				rightKey = true;
			}
		});

		js.Browser.document.addEventListener("keydown", (event:js.html.KeyboardEvent) -> {
			switch (0) {
				case _:

				case 0:
					if (event.code == "ArrowLeft") {
						leftKey = true;
					} else if (event.code == "ArrowRight") {
						rightKey = true;
					}
			}
		});

		js.Browser.document.addEventListener("keydown", (event:js.html.KeyboardEvent) -> {
			switch (0) {
				case _:

				case 0:
					if (event.code == "ArrowLeft") {
						leftKey = true;
					} else if (event.code == "ArrowRight") {
						rightKey = true;
					} else {
						true;
					}
			}
		});

		js.Browser.document.addEventListener("keydown", (event:js.html.KeyboardEvent) -> {
			switch (0) {
				case _:

				case 0:
					if (event.code == "ArrowLeft") {
						leftKey = true;
					} else if (event.code == "ArrowRight") {
						rightKey = true;
					}
			}

			return;
		});
	}
}
@RblSb
Copy link
Member

RblSb commented Nov 6, 2024

Another annoying case is:

class Main {
	static function main() {
		final arr = [1];
		foo(() -> {
			if (Std.random(1) == 0) {
				arr.remove(1);
			} else { // Int should be Bool
				arr.push(1);
			}
		});
	}

	static function foo(callback: Dynamic):Void {}
}

@ibilon
Copy link
Member Author

ibilon commented Nov 6, 2024

That's not just when unifying against Constraints.Function, Dynamic, or Any.
Creating the lambda is enough:
https://try.haxe.org/#33823dA8

function main() {
	final arr = [1];
	final foo = () -> {
		if (Std.random(1) == 0) {
			arr.remove(1);
		} else { // Int should be Bool
			arr.push(1);
		}
	};
	$type(foo);
	foo();    
}
[ERROR] Test.hx:6: lines 6-8

  6 |   } else { // Int should be Bool
  7 |    arr.push(1);
  8 |   }
    |
    | Int should be Bool

[WARNING] Test.hx:10: characters 8-11

 10 |  $type(foo);
    |        ^^^
    | () -> Bool

@Simn
Copy link
Member

Simn commented Nov 18, 2024

The compiler tries to find a minimal type between the branches, but there is no minimal type for () -> Int and () -> Bool. This all comes from the fact that lambdas have an implicit return, which means that we have to find some type for the expression.

I don't think there's anything to fix here. It works if one of the branches is Void because then we can assume () -> Void as the minimal type, but I don't think we should do this in other cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants