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

internal/eval: type assertion issue on complex definition - different behavior than with native types #1161

Open
grouville opened this issue Jul 29, 2021 · 1 comment

Comments

@grouville
Copy link

grouville commented Jul 29, 2021

What version of CUE are you using (cue version)?

$ cue version
cue version 0.4.0 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What did you do?

When asserting types between a native one and an open definition, the assertion doesn't work entirely

First, let's see the normal behaviors:

-- first.cue --
package test

x: string | int

if (x & string) == _|_ {
	z: "int"
}

//x: "ok"
x: 1

if (x & int) == _|_ {
	z: "string"
}
-- second.cue --
package test

x: string | int

if (x & string) == _|_ {
	z: "int"
}

//x: "ok"
x: 1

if (x & string) != _|_ {
	z: "string"
}
-- third.cue --
package test

#Jo: {
}

x: string | #Jo

if (x & string) == _|_ {
	z: "int"
}

//x: "ok"
x: #Jo & {}

if (x & string) != _|_ {
	z: "string"
}

You need to eval each file independently. They all eval to the same z value : z: "int"
If you uncomment the other x value in the above files and comment their currently assigned one, the inverse of the type assertion works.

Now, with our more complex open definition:

-- first.cue --
package test

#Op: {
	do: string
	...
}

#Artifact: {
	@decorator(now)
	#up: [...#Op]
	_
	...
}

x: string | #Artifact

x: "ok"
//x: #Artifact & {}

if (x & string) == _|_ {
	z: "int"
}

if (x & string) != _|_ {
	z: "string"
}

-(output)-
x: {
	"ok" | {
		"ok"
		@decorator(now)
	}
	@decorator(now)
}

-- second.cue --
#Op: {
	do: string
	...
}

#Artifact: {
	@decorator(now)
	#up: [...#Op]
	_
	...
}

x: string | #Artifact

//x: "ok"
x: #Artifact & {}

if (x & string) == _|_ {
	z: "int"
}

if (x & string) != _|_ {
	z: "string"
}

-(output)-
z: "int"

//x: "ok"
x: {
	@decorator(now)
}

Here, again, run cue eval on both files separately.

What did you expect to see?

When running the (x & string) != _|_ (x is a string) type assertion with the #Artifact definition being one of the possible type, and with x being a string, I expect to enter in the if statement.

The inverse assertion (checking that the type doesn't match) however works.

What did you see instead?

x: {
	"ok" | {
		"ok"
		@decorator(now)
	}
	@decorator(now)
}

The only way to make it work is by doing the inverse of the don't match assertion !((x & string) == _|_). (Works when only 2 types are involved)

-- third.cue --
package test

#Op: {
	do: string
	...
}

#Artifact: {
	@decorator(now)
	#up: [...#Op]
	_
	...
}

x: string | #Artifact

x: "ok"
//x: #Artifact & {}

if (x & string) == _|_ {
	z: "int"
}

if !((x & string) == _|_) {
	z: "string"
}

-(output)-
z: "string"
x: {
	"ok" | {
		"ok"
		@decorator(now)
	}
	@decorator(now)
}
@grouville grouville added NeedsInvestigation Triage Requires triage/attention labels Jul 29, 2021
@myitcv myitcv removed the Triage Requires triage/attention label Jul 29, 2021
@myitcv myitcv changed the title Type assertion issue on complex definition - different behavior than with native types internal/eval: type assertion issue on complex definition - different behavior than with native types Jul 29, 2021
@myitcv
Copy link
Member

myitcv commented Jul 29, 2021

@grouville apologies for the delay in getting round to this issue.

As you will see from #943, comparison against _|_ is not well defined. And in the light of that proposal, is also not something we are likely to fix/address.

I have, however, added an explicit note to ensure we document how type assertion will work with these replacement builtins.

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

No branches or pull requests

3 participants