Skip to content

evaluator, cmd/cue: inconsistency between lookup results #2312

@rogpeppe

Description

@rogpeppe

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

$ cue version
cue version v0.0.0-20230322121530-0b681f5d193a

go version devel go1.21-a4d5fbc3a4 Thu Feb 9 21:14:00 2023 +0000
      -buildmode exe
       -compiler gc
     CGO_ENABLED 1
          GOARCH amd64
            GOOS linux
         GOAMD64 v1
             vcs git
    vcs.revision 0b681f5d193a55893fdec8386f4a72a6effcebb1
        vcs.time 2023-03-22T12:15:30Z
    vcs.modified false

Does this issue reproduce with the latest stable release?

Yes.

What did you do?

Here are two testscript tests:

! exec cue def -e b x.cue
! exec cue def -e a.x x.cue
-- x.cue --
a: {
	x: "test"
	_y: 1&2
}
b: "test"
exec cue def -e b x.cue
cmp stdout want.cue

exec cue def -e a.x x.cue
cmp stdout want.cue
-- x.cue --
a: {
	x: "test"
	_y: 1&2
}
b: "test"
-- want.cue --
"test"

What did you expect to see?

I think that exactly one of those tests should pass.
That is, I believe there should be consistency in accessing a field in a struct when other fields in the same struct are bottom.

What did you see instead?

Instead, I get the following behaviour (failures in the same order as above):

> ! exec cue def -e b x.cue
[stdout]
"test"
FAIL: /tmp/testscript1376987841/x1.txtar/script.txtar:1: unexpected command success
> exec cue def -e b x.cue
[stdout]
"test"
> cmp stdout want.cue
> exec cue def -e a.x x.cue
[stderr]
a._y: conflicting values 2 and 1:
    ./x.cue:3:6
    ./x.cue:3:8
[exit status 1]
FAIL: /tmp/testscript1460282785/x2.txtar/script.txtar:4: unexpected command failure

That is, we can access the top level field directly, but not the second level field.

Interestingly, in the Go API, we can access both fields OK despite the containing structs being marked as an error.

For example, this Go code:

package main

import (
	"fmt"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
)

func main() {
	ctx := cuecontext.New()
	v := ctx.CompileString(`
a: {
    x: "test"
    y: 1&2
}
b: "test"
`)
	fmt.Printf("v: %v; error: %v\n", v, v.Err())
	a := v.LookupPath(cue.ParsePath("a"))
	b := v.LookupPath(cue.ParsePath("b"))
	fmt.Printf("v.a: %v; error: %v\n", a, a.Err())
	x := a.LookupPath(cue.ParsePath("x"))
	fmt.Printf("v.a.x: %v; error: %v\n", x, x.Err())
	fmt.Printf("v.b: %v; error: %v\n", b, b.Err())
}

produces the following result (as of cuelang.org/go v0.6.0-0.dev.0.20230324092610-eea60b9cd229):

v: _|_ // a.y: conflicting values 2 and 1; error: a.y: conflicting values 2 and 1
v.a: _|_ // a.y: conflicting values 2 and 1; error: a.y: conflicting values 2 and 1
v.a.x: "test"; error: <nil>
v.b: "test"; error: <nil>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions