Skip to content

Commit

Permalink
internal/core: reimplementation of closedness algorithm
Browse files Browse the repository at this point in the history
Note: there are considerably more test lines, because
there is a) more position information, and b) there are
more tests. Insofar tests have been removed, it is because
the relevant code no longer exits.

So effectively, there are about 500 lines less code
related to closedness as a result of this change!

- Unify and UnifyAccept do all closedness checking wrt
  the parent locally. The AddVertex and UnifyAccept have
  been removed from eval.
- The old fieldSet is replaced with precomputed values in
  StructLit.
- Most optional and closedness logic has either been
  removed or moved from package eval to package adt.
- Instead of a separate Structs slice and closedness information
  there is now just a StructInfo slice with integrated CloseInfo.
- The Acceptor interface has been removed.
- A new algorithm computes closedness bottom up, instead
  of top-down. See closed.go in ADT for details.
- Recorded about a 15% reducing in running time, memory is
  of the same order.

Note that this removes many optimizations of the previous
implementation. Some of these (and others) could be added
later.

Fixes #599
Fixes #618

Change-Id: If6eec0b915b96067bcc4778bf63707827054b4d1
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7985
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
  • Loading branch information
mpvl committed Jan 2, 2021
1 parent 2be20f8 commit cea55b2
Show file tree
Hide file tree
Showing 36 changed files with 1,917 additions and 2,237 deletions.
4 changes: 4 additions & 0 deletions cmd/cue/cmd/testdata/script/eval_errs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ cmp stdout expect-stdout
bar: empty disjunction: 2 related errors:
bar.a: conflicting values "str" and int (mismatched types string and int):
./errs.cue:5:10
./errs.cue:6:6
./errs.cue:6:16
bar.b: conflicting values 2 and string (mismatched types int and string):
./errs.cue:5:21
./errs.cue:6:6
./errs.cue:6:26
x.q: conflicting values "goodbye" and "hello":
./errs.cue:1:4
./errs.cue:2:4
./errs.cue:3:8
./errs.cue:3:14
-- errs.cue --
a: "hello"
b: "goodbye"
Expand Down
2 changes: 2 additions & 0 deletions cue/testdata/builtins/closed.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ c: a & { a: c: int } // okay (non-recursive close)
Errors:
b: field `x` not allowed:
./in.cue:1:10
./in.cue:5:4
./in.cue:5:10

Result:
Expand All @@ -28,6 +29,7 @@ Result:
x: (_|_){
// [eval] b: field `x` not allowed:
// ./in.cue:1:10
// ./in.cue:5:4
// ./in.cue:5:10
}
}
Expand Down
2 changes: 2 additions & 0 deletions cue/testdata/builtins/issue490.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ B: A & {
Errors:
B: field `c` not allowed:
./test.cue:1:10
./test.cue:6:4
./test.cue:7:2

Result:
Expand All @@ -27,6 +28,7 @@ Result:
c: (_|_){
// [eval] B: field `c` not allowed:
// ./test.cue:1:10
// ./test.cue:6:4
// ./test.cue:7:2
}
}
Expand Down
16 changes: 16 additions & 0 deletions cue/testdata/cycle/structural.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,10 @@ b13.root.a.0.0: structural cycle
b14.root.b.1.1: structural cycle
b4.x.y.0: structural cycle
b6.b.a.0: conflicting values 1 and [1] (mismatched types int and list):
./in.cue:63:8
./in.cue:63:16
./in.cue:63:17
./in.cue:64:12
b6.b.a.0.0: structural cycle
b6.x.a.0: structural cycle
b7.a.0: structural cycle
Expand All @@ -417,22 +419,26 @@ e3.a: conflicting values [a] and {c:a} (mismatched types list and struct):
./in.cue:290:8
e3.a.0: conflicting values [a] and {c:a} (mismatched types list and struct):
./in.cue:289:8
./in.cue:289:9
./in.cue:290:8
e3.a.0: structural cycle
e3.a.c: conflicting values [a] and {c:a} (mismatched types list and struct):
./in.cue:289:8
./in.cue:290:8
./in.cue:290:11
e3.a.c: structural cycle
e3.b: conflicting values [b] and {c:b} (mismatched types list and struct):
./in.cue:292:8
./in.cue:293:8
e3.b.0: conflicting values [b] and {c:b} (mismatched types list and struct):
./in.cue:292:8
./in.cue:292:9
./in.cue:293:8
e3.b.0: structural cycle
e3.b.c: conflicting values [b] and {c:b} (mismatched types list and struct):
./in.cue:292:8
./in.cue:293:8
./in.cue:293:11
e3.b.c: structural cycle
e4.a.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:297:13
Expand All @@ -442,6 +448,7 @@ e4.a.0.0: conflicting values [{c:1}] and {c:1} (mismatched types list and struct
./in.cue:298:9
./in.cue:298:10
e4.a.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:297:9
./in.cue:297:13
./in.cue:298:9
e4.a.0.0: empty disjunction: 2 related errors:
Expand All @@ -454,6 +461,7 @@ e4.b.0.0: conflicting values [{c:1}] and {c:1} (mismatched types list and struct
./in.cue:300:10
e4.b.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:300:9
./in.cue:301:9
./in.cue:301:13
e4.b.0.0: empty disjunction: 2 related errors:
p2.#T.a.b.link: structural cycle
Expand Down Expand Up @@ -594,8 +602,10 @@ Result:
// [eval]
0: (_|_){
// [eval] b6.b.a.0: conflicting values 1 and [1] (mismatched types int and list):
// ./in.cue:63:8
// ./in.cue:63:16
// ./in.cue:63:17
// ./in.cue:64:12
0: (_|_){
// [structural cycle] b6.b.a.0.0: structural cycle
}
Expand Down Expand Up @@ -1150,6 +1160,7 @@ Result:
// [eval] e3.a.c: conflicting values [a] and {c:a} (mismatched types list and struct):
// ./in.cue:289:8
// ./in.cue:290:8
// ./in.cue:290:11
// e3.a.c: structural cycle
c: (_|_){// 〈1;a〉
}
Expand All @@ -1159,6 +1170,7 @@ Result:
0: (_|_){
// [eval] e3.a.0: conflicting values [a] and {c:a} (mismatched types list and struct):
// ./in.cue:289:8
// ./in.cue:289:9
// ./in.cue:290:8
// e3.a.0: structural cycle
c: (_|_){// 〈1;a〉
Expand All @@ -1175,6 +1187,7 @@ Result:
// [eval] e3.b.c: conflicting values [b] and {c:b} (mismatched types list and struct):
// ./in.cue:292:8
// ./in.cue:293:8
// ./in.cue:293:11
// e3.b.c: structural cycle
c: (_|_){// 〈1;b〉
}
Expand All @@ -1184,6 +1197,7 @@ Result:
0: (_|_){
// [eval] e3.b.0: conflicting values [b] and {c:b} (mismatched types list and struct):
// ./in.cue:292:8
// ./in.cue:292:9
// ./in.cue:293:8
// e3.b.0: structural cycle
c: (_|_){// 〈1;b〉
Expand All @@ -1206,6 +1220,7 @@ Result:
// ./in.cue:298:9
// ./in.cue:298:10
// e4.a.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
// ./in.cue:297:9
// ./in.cue:297:13
// ./in.cue:298:9
// e4.a.0.0: empty disjunction: 2 related errors:
Expand All @@ -1226,6 +1241,7 @@ Result:
// ./in.cue:300:10
// e4.b.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
// ./in.cue:300:9
// ./in.cue:301:9
// ./in.cue:301:13
// e4.b.0.0: empty disjunction: 2 related errors:
0: (struct){
Expand Down
2 changes: 2 additions & 0 deletions cue/testdata/definitions/033_Issue_#153.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ listOfCloseds.0: field `b` not allowed:
./in.cue:2:21
./in.cue:5:10
./in.cue:13:1
./in.cue:14:18
./in.cue:16:4

Result:
Expand All @@ -81,6 +82,7 @@ Result:
// ./in.cue:2:21
// ./in.cue:5:10
// ./in.cue:13:1
// ./in.cue:14:18
// ./in.cue:16:4
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Errors:
#E: field `f3` not allowed:
./in.cue:1:5
./in.cue:27:5
./in.cue:27:10
./in.cue:29:3
a: field `f3` not allowed:
./in.cue:1:5
Expand Down Expand Up @@ -137,6 +138,7 @@ Result:
// [eval] #E: field `f3` not allowed:
// ./in.cue:1:5
// ./in.cue:27:5
// ./in.cue:27:10
// ./in.cue:29:3
}
}
Expand Down
2 changes: 1 addition & 1 deletion cue/testdata/definitions/embed.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Result:
a: (#struct){
x: (int){ int }
y: (int){ int }
b: (#struct){
b: (struct){
c: (int){ int }
}
}
Expand Down
87 changes: 69 additions & 18 deletions cue/testdata/definitions/hidden.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,83 @@ import "example.com/pkg"
_name: d: int
}

d: pkg.#D & { _name: d: int, _val: 4 }
d: pkg.#D & { _name: d: int, _val: f: 4 }

// TODO: this should fail, as the _name restricting it is in this
// package.
e: pkg.#D & #def & { _name: e: int, _val: int }
f: e._val
e: pkg.#D & #def & {
// This should fail as c is disallowed by the _name defined
// in this package
_name: c: int

// This should not fail, as this is a different _val
_val: g: int
}

f: pkg.#D & { _val: f: 4 }
g: f._val

-- pkg/bar.cue --
package pkg

#D: { _val: 3 }
#D: { _val: f: 3 }

-- out/eval --
(struct){
Errors:
e._name: field `c` not allowed:
./in.cue:6:10
./in.cue:13:13
./in.cue:16:10

Result:
(_|_){
// [eval]
#def: (#struct){
_name(:foo): (#struct){
d: (int){ int }
}
}
d: (#struct){
_val(example.com:pkg): (int){ 3 }
_name(:foo): (#struct){
_val(example.com:pkg): (#struct){
f: (int){ 3 }
}
_name(:foo): (struct){
d: (int){ int }
}
_val(:foo): (int){ 4 }
_val(:foo): (struct){
f: (int){ 4 }
}
}
e: (#struct){
_val(example.com:pkg): (int){ 3 }
_name(:foo): (#struct){
e: (_|_){
// [eval]
_val(example.com:pkg): (#struct){
f: (int){ 3 }
}
_name(:foo): (_|_){
// [eval]
d: (int){ int }
e: (int){ int }
c: (_|_){
// [eval] e._name: field `c` not allowed:
// ./in.cue:6:10
// ./in.cue:13:13
// ./in.cue:16:10
}
}
_val(:foo): (int){ int }
_val(:foo): (struct){
g: (int){ int }
}
}
f: (#struct){
_val(example.com:pkg): (#struct){
f: (int){ 3 }
}
_val(:foo): (struct){
f: (int){ 4 }
}
}
g: (struct){
f: (int){ 4 }
}
f: (int){ int }
}
-- out/compile --
--- in.cue
Expand All @@ -60,13 +102,22 @@ package pkg
_name: {
d: int
}
_val: 4
_val: {
f: 4
}
})
e: ((〈import;"example.com/pkg"〉.#D & 〈0;#def〉) & {
_name: {
e: int
c: int
}
_val: {
g: int
}
})
f: (〈import;"example.com/pkg"〉.#D & {
_val: {
f: 4
}
_val: int
})
f: 〈0;e〉._val
g: 〈0;f〉._val
}
2 changes: 1 addition & 1 deletion cue/testdata/definitions/list.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ c: #R & {
w: (#list){
0: (#struct){
}
1: (#struct){
1: (struct){
b: (int){ int }
}
}
Expand Down
2 changes: 2 additions & 0 deletions cue/testdata/eval/conflicts.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Errors:
t0.v: conflicting values int and string (mismatched types int and string):
./in.cue:1:4
./in.cue:2:4
./in.cue:5:12
t1.x.a.b: conflicting values 4 and 3:
./in.cue:10:15
./in.cue:14:15
Expand All @@ -40,6 +41,7 @@ Result:
// [eval] t0.v: conflicting values int and string (mismatched types int and string):
// ./in.cue:1:4
// ./in.cue:2:4
// ./in.cue:5:12
}
}
t1: (_|_){
Expand Down
5 changes: 5 additions & 0 deletions cue/testdata/eval/disjunctions.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ Errors:
f: empty disjunction: 2 related errors:
f.name: conflicting values "int" and "str":
./in.cue:5:8
./in.cue:15:4
./in.cue:15:16
f.val: conflicting values 3 and string (mismatched types int and string):
./in.cue:9:7
./in.cue:15:4
./in.cue:15:28

Result:
Expand Down Expand Up @@ -97,14 +99,17 @@ Result:
// [eval] f: empty disjunction: 2 related errors:
// f.name: conflicting values "int" and "str":
// ./in.cue:5:8
// ./in.cue:15:4
// ./in.cue:15:16
// f.val: conflicting values 3 and string (mismatched types int and string):
// ./in.cue:9:7
// ./in.cue:15:4
// ./in.cue:15:28
name: (string){ "str" }
val: (_|_){
// [eval] f.val: conflicting values 3 and string (mismatched types int and string):
// ./in.cue:9:7
// ./in.cue:15:4
// ./in.cue:15:28
}
}
Expand Down

0 comments on commit cea55b2

Please sign in to comment.