Skip to content

parser, cgen: fix option variable error (fix #17460)#17479

Merged
spytheman merged 4 commits intovlang:masterfrom
yuyi98:fix_if_guard_ident
Mar 4, 2023
Merged

parser, cgen: fix option variable error (fix #17460)#17479
spytheman merged 4 commits intovlang:masterfrom
yuyi98:fix_if_guard_ident

Conversation

@yuyi98
Copy link
Copy Markdown
Member

@yuyi98 yuyi98 commented Mar 3, 2023

This PR fix option variable error (fix #17460, fix #17461).

  • Fix option variable error.
  • Add test.
struct Foo {
	name ?string
}

fn main() {
	foo := Foo{}
	other := foo.name

	println(typeof(other).name)
	if name := other {
		println('with name: ${name}')
		assert false
	} else {
		println('without name')
		assert true
	}

	println(foo.name)
}

PS D:\Test\v\tt1> v run .
?string
without name
Option(error: none)
struct Foo {
	name ?string
}

fn main() {
	foo := Foo{}
	other := foo.name
	mut counter := 0
	val := other or {
		counter++
		'default'
	}

	assert val == 'default'
	assert counter == 1
}

PS D:\Test\v\tt1> v run .

@spytheman
Copy link
Copy Markdown
Contributor

Why does the second example print without name 2 times?

@spytheman
Copy link
Copy Markdown
Contributor

spytheman commented Mar 3, 2023

it generated wrongly :-| :

    if (other.state != 0) {
        IError err = other.err;
        println(_SLIT("without name"));
        *(string*) other.data = _SLIT("default");
    }
    string val = /*opt*/(*(string*)other.data);
    if (other.state != 0) {
        println(_SLIT("without name"));
        val = _SLIT("default");
    }
    ;

The second if body should not be there, then it will produce the without name just once.

@yuyi98
Copy link
Copy Markdown
Member Author

yuyi98 commented Mar 3, 2023

Ok, I'll fix it.

@spytheman
Copy link
Copy Markdown
Contributor

Something like this can test it:

struct Foo {
	name ?string
}

fn test_or_block_should_be_evaluated_just_once() {
	foo := Foo{}
	other := foo.name
	mut counter := 0
	val := other or {
		counter++
		'default'
	}
	assert val == 'default'
	assert counter == 1
}

@yuyi98 yuyi98 force-pushed the fix_if_guard_ident branch from b28112e to ed069c1 Compare March 4, 2023 06:51
Copy link
Copy Markdown
Contributor

@spytheman spytheman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work.

@spytheman spytheman merged commit 6944d54 into vlang:master Mar 4, 2023
@yuyi98 yuyi98 deleted the fix_if_guard_ident branch March 4, 2023 12:49
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

Successfully merging this pull request may close these issues.

Cgen error for or block for variable with Option type error if guard condition expression is illegal for variable with Option type

2 participants