cue: Value.Equal should not only consider values

It is verified that this is the same behavior as v0.2.2.
So this brings v0.3 closer to v0.2.

This also fixes builtins that still relied on the old
behavior.

Fixes #784

Change-Id: I80714da319f91bc09d2d6c3495deaa369d80c9d6
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8901
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 8e09deb..b8bec80 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -1831,7 +1831,7 @@
 	if v.v == nil || other.v == nil {
 		return false
 	}
-	return adt.Equal(v.ctx().opCtx, v.v, other.v, adt.CheckStructural)
+	return adt.Equal(v.ctx().opCtx, v.v, other.v, 0)
 }
 
 // Format prints a debug version of a value.
diff --git a/cue/types_test.go b/cue/types_test.go
index d8212fb..3b4c7d1 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -1493,6 +1493,21 @@
 			a: "foo",
 		}`,
 		false,
+	}, {
+		// Ignore closedness
+		`{ #Foo: { k: 1 }, a: #Foo }`,
+		`{ #Foo: { k: 1 }, a: { k: 1 } }`,
+		true,
+	}, {
+		// Ignore optional fields
+		`{ #Foo: { k: 1 }, a: #Foo }`,
+		`{ #Foo: { k: 1 }, a: { #Foo, i?: 1 } }`,
+		true,
+	}, {
+		// Treat embedding as equal
+		`{ a: 2, b: { 3 } }`,
+		`{ a: { 2 }, b: 3 }`,
+		true,
 	}}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {
diff --git a/internal/core/adt/equality.go b/internal/core/adt/equality.go
index d1b5a1d..9f2d7ad 100644
--- a/internal/core/adt/equality.go
+++ b/internal/core/adt/equality.go
@@ -57,11 +57,13 @@
 	}
 
 	// TODO: this really should be subsumption.
-	if x.IsClosed(ctx) != y.IsClosed(ctx) {
-		return false
-	}
-	if flags != 0 && !equalClosed(ctx, x, y, flags) {
-		return false
+	if flags != 0 {
+		if x.IsClosed(ctx) != y.IsClosed(ctx) {
+			return false
+		}
+		if !equalClosed(ctx, x, y, flags) {
+			return false
+		}
 	}
 
 loop1: