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

Compiler error when adding #optional_ok to procedure used in "for in" syntax #3282

Closed
thetarnav opened this issue Mar 15, 2024 · 0 comments
Closed

Comments

@thetarnav
Copy link
Contributor

thetarnav commented Mar 15, 2024

A proc with #optional_ok, when used with the iterator syntax sugar (for value in iterate(&it)), the boolean return value gets ignored, and the value gets iterated instead.
Which causes a compile error is the value is not iterable.

Example:

package bug

main :: proc() {
	int_with_optional :: proc() -> (value: int, cond: bool) #optional_ok {return}

	for value in int_with_optional() {
		#assert(type_of(value) == int)
	}

	for {
		value := int_with_optional() or_break
		#assert(type_of(value) == int)
	}

	int_without_optional :: proc() -> (value: int, cond: bool) {return}

	for value in int_without_optional() {
		#assert(type_of(value) == int)
	}

	for {
		value := int_without_optional() or_break
		#assert(type_of(value) == int)
	}

	slice_with_optional :: proc() -> (value: []int, cond: bool) #optional_ok {return}

	for value in slice_with_optional() {
		#assert(type_of(value) == []int)
	}

	for {
		value := slice_with_optional() or_break
		#assert(type_of(value) == []int)
	}

	slice_without_optional :: proc() -> (value: []int, cond: bool) {return}

	for value in slice_without_optional() {
		#assert(type_of(value) == []int)
	}

	for {
		value := slice_without_optional() or_break
		#assert(type_of(value) == []int)
	}
}

Errors:

bug/main.odin(6:15) Error: Cannot iterate over 'int_with_optional()' of type 'int'
        for value in int_with_optional() {
                     ^~~~~~~~~~~~~~~~~~^
bug/main.odin(7:19) Error: Undeclared name: value
        #assert(type_of(value) == int)
                        ^~~~^
bug/main.odin(7:29) Error: 'int' is not an expression but a type
        #assert(type_of(value) == int)
                                  ^~^
bug/main.odin(7:3) Error: 'type_of(value) == int' is not a constant boolean
        #assert(type_of(value) == int)
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
bug/main.odin(29:3) Error: Compile time assertion: type_of(value) == []int
        #assert(type_of(value) == []int)
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

Odin report:

        Odin:    dev-2024-03:04f0fbf23
        OS:      Ubuntu 22.04.4 LTS, Linux 6.5.0-25-generic
        CPU:     Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
        RAM:     7631 MiB
        Backend: LLVM 17.0.6

Expected Behavior

I would expect that the last return value will always be used as a condition for the for loop, with #optional_ok or without. And the returned value should only be iterated on if the procedure returns a single value.

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

1 participant