cue: allow raw subsumption, taking defaults into account
Change-Id: I2046b8967147dd8383bffb45add57a0ad553898e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9262
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/types.go b/cue/types.go
index fb8961f..d3f0dc8 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -1717,11 +1717,14 @@
// Without options, the entire value is considered for assumption, which means
// Subsume tests whether v is a backwards compatible (newer) API version of w.
//
-// Use the Final option to check subsumption if a w is known to be final,
-// and should assumed to be closed.
+// Use the Final option to check subsumption if a w is known to be final, and
+// should assumed to be closed.
//
-// Value v and w must be obtained from the same build.
-// TODO: remove this requirement.
+// Use the Raw option to do a low-level subsumption, taking defaults into
+// account.
+//
+// Value v and w must be obtained from the same build. TODO: remove this
+// requirement.
func (v Value) Subsume(w Value, opts ...Option) error {
o := getOptions(opts)
p := subsume.CUE
@@ -1733,7 +1736,9 @@
case o.ignoreClosedness:
p = subsume.API
}
- p.Defaults = true
+ if !o.raw {
+ p.Defaults = true
+ }
ctx := v.ctx().opCtx
return p.Value(ctx, v.v, w.v)
}
diff --git a/cue/types_test.go b/cue/types_test.go
index a327ea8..f5ab493 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -1435,6 +1435,42 @@
pathB: b,
options: []Option{Final()},
want: true,
+ }, {
+ // default
+ value: `
+ a: <5
+ b: *3 | int
+ `,
+ pathA: a,
+ pathB: b,
+ want: true,
+ }, {
+ // Disable default elimination.
+ value: `
+ a: <5
+ b: *3 | int
+ `,
+ pathA: a,
+ pathB: b,
+ options: []Option{Raw()},
+ want: false,
+ }, {
+ value: `
+ #A: {
+ exact: string
+ } | {
+ regex: string
+ }
+ #B: {
+ exact: string
+ } | {
+ regex: string
+ }
+ `,
+ pathA: ParsePath("#A"),
+ pathB: ParsePath("#B"),
+ options: []Option{},
+ want: true,
}}
for _, tc := range testCases {
t.Run(tc.value, func(t *testing.T) {
diff --git a/internal/core/subsume/subsume.go b/internal/core/subsume/subsume.go
index 734dfdb..2c15bad 100644
--- a/internal/core/subsume/subsume.go
+++ b/internal/core/subsume/subsume.go
@@ -72,7 +72,7 @@
if !s.values(a, b) {
return s.getError()
}
- return s.errs
+ return nil // ignore errors here even if there are some.
}
// Check reports whether b is an instance of a.