Skip to content

evaluator: recursive disjunction fails inappropriately #2405

@rogpeppe

Description

@rogpeppe

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

$ cue version
cue version v0.0.0-20230511092117-a670427406af

go version devel go1.21-3ed8a1e629 Tue Mar 28 05:41:44 2023 +0000
      -buildmode exe
       -compiler gc
  DefaultGODEBUG panicnil=1
     CGO_ENABLED 1
          GOARCH amd64
            GOOS linux
         GOAMD64 v1
             vcs git
    vcs.revision a670427406af7451da77cf477c0786d6f1b129c8
        vcs.time 2023-05-11T09:21:17Z
    vcs.modified false

Does this issue reproduce with the latest stable release?

Yes.

What did you do?

exec cue export x.cue
cmp stdout want-stdout

-- x.cue --
#Copy: {
	param: {...}
	result: {
		for k, v in param {
			(k): (#Copy & {param: v}).result
		}
	}
} | {
	param: [...]
	result: [
		for v in param {
			(#Copy & {param: v}).result
		},
	]
} | {
	param:  number
	result: param
}

foo: #Copy
foo: param: a: [{b: 134}]

-- want-stdout --
{
    "foo": {
        "param": {
            "a": [
                {
                    "b": 134
                }
            ]
        },
        "result": {
            "a": [
                {
                    "b": 134
                }
            ]
        }
    }
}

What did you expect to see?

A passing test.

What did you see instead?

> exec cue-v0.5.0 export x.cue
[stderr]
foo: 8 errors in empty disjunction:
foo.param: conflicting values [...] and {a:[{b:134}]} (mismatched types list and struct):
    ./x.cue:9:9
    ./x.cue:21:13
foo.param: conflicting values number and {a:[{b:134}]} (mismatched types number and struct):
    ./x.cue:16:10
    ./x.cue:21:13
param: conflicting values [...] and {b:134} (mismatched types list and struct):
    ./x.cue:9:9
    ./x.cue:12:21
    ./x.cue:21:17
param: conflicting values [{b:134}] and {...} (mismatched types list and struct):
    ./x.cue:2:9
    ./x.cue:5:10
    ./x.cue:21:16
param: conflicting values number and [{b:134}] (mismatched types number and list):
    ./x.cue:5:26
    ./x.cue:16:10
    ./x.cue:21:16
param: conflicting values number and {b:134} (mismatched types number and struct):
    ./x.cue:12:21
    ./x.cue:16:10
    ./x.cue:21:17
6 errors in empty disjunction::
    ./x.cue:5:10
3 errors in empty disjunction::
    ./x.cue:12:5
[exit status 1]
FAIL: /tmp/testscript648883949/x.txtar/script.txtar:1: unexpected command failure

It seems like the disjunction logic is failing to match somehow.

This non-recursive definition tailored to the input in question works OK:

exec cue export x.cue
cmp stdout want-stdout

-- x.cue --
#Copy: {
	param: {...}
	result: {
		for k, v in param {
			(k): (#Copy1 & {param: v}).result
		}
	}
}

#Copy1: {
	param: [...]
	result: [
		for v in param {
			(#Copy2 & {param: v}).result
		},
	]
}

#Copy2: {
	param: {...}
	result: {
		for k, v in param {
			(k): (#Copy3 & {param: v}).result
		}
	}
}

#Copy3: {
	param: number
	result: param
}

foo: #Copy
foo: param: a: [{b: 134}]

-- want-stdout --
{
    "foo": {
        "param": {
            "a": [
                {
                    "b": 134
                }
            ]
        },
        "result": {
            "a": [
                {
                    "b": 134
                }
            ]
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions