-- in.cue --
import "regexp"

// Issue #655
// When evaluating a value into a struct, and then back into a value, the
// evaluation mode flips from Partial to AllConjunctsDone to Back. This is
// typically not an issue, but if a referred field is within a struct generated
// by a builtin, effectively the entire struct needs to be evaluated and special
// care should be taking to not evaluate too early.
builtinCyclePerm0: {
	X: "mod.test"

	Y: {
		#components: regexp.FindNamedSubmatch(#"^(?P<host>[[:alnum:].]+)$"#, X)
		host:        #components.host
	}

	X: Y.host
}

builtinCyclePerm1: {
	X: Y.host

	Y: {
		#components: regexp.FindNamedSubmatch(#"^(?P<host>[[:alnum:].]+)$"#, X)
		host:        #components.host
	}

	X: "mod.test"
}

builtinCyclePerm2: {
	Y: {
		#components: regexp.FindNamedSubmatch(#"^(?P<host>[[:alnum:].]+)$"#, X)
		host:        #components.host
	}

	X: Y.host
	X: "mod.test"
}

builtinCyclePerm3: {
	Y: {
		#components: regexp.FindNamedSubmatch(#"^(?P<host>[[:alnum:].]+)$"#, X)
		host:        #components.host
	}

	X: "mod.test"
	X: Y.host
}

builtinCyclePerm4: {
	X: "mod.test"
	X: Y.host

	Y: {
		#components: regexp.FindNamedSubmatch(#"^(?P<host>[[:alnum:].]+)$"#, X)
		host:        #components.host
	}
}

builtinCyclePerm5: {
	X: Y.host
	X: "mod.test"

	Y: {
		#components: regexp.FindNamedSubmatch(#"^(?P<host>[[:alnum:].]+)$"#, X)
		host:        #components.host
	}
}
-- matchn.cue --
// This should not be a structural cycle, as the list type is "optional".
issue3410: {
	_s
	_s: {
		#x: matchN(1, [_s, [..._s]])
	}
}
issue3420: {
	matches1: {
		#S: matchN(1, [_, _|_])
		s: 2
	}
}
issue3443: {
	matchIf: {
		#S: matchIf({x?: "b"}, {n?: #S & (int | {})}, _)
	}
	noCycle: {
		// This is not a structural cycle, and should not hang, as n? is optional.
		#S: matchN(1, [{n?: #S & (int | {})}])

		noHang: {
			s: #S
			s: n: n: _
		}
	}

	noCycle2: {
		#S: matchN(1, [{n?: (int | #S)}])
	}

	cycle1: {
		// This correct CUE, as matchN allows for schema to be errors. We should
		// probably have a vet rule to catch this,though.
		#S: matchN(1, [{n: #S}])

		// This is not an error as the result is structure shared. Not sure if
		// this should be accepted.
		ok: {
			s: #S
			s: _
		}

		// This unifies deep enough to cause a structural cycle. It probably
		// should not.
		cycle: {
			s: #S
			s: n: n: _
		}
	}

	cycle2: {
		// TODO: this should probably fail, or at least be consistent with
		// cycle1.cycle.
		fail: #S: matchN(1, [{n: #S}]) & {n: n: n: _}
	}
}
issue3633: final: {
	// With nested matchNs as below, the schema will become an incomplete error
	// as a value of the root vertex. Make sure this edge case is properly
	// handled.
	data: {} & #s
	#s: matchN(1, [matchN(1, [{a!: _}])])
}
-- cycle.cue --
noCycle: t1: {
	_s
	_s: {
		#x: matchN(1, [_s])
        #x: {} // insert concrete value to trigger application of validator.
	}
}
issue3649: noCycle: t1: {
	data: #c
	data: a: b: "foo"
	#c: {
		// There should be no cycle because of these optional fields.
		b?: string
		a?: matchN(1, [#c])
	}
}
// Same as above, but with longer paths.
issue3649: noCycle: t2: {
	x: c
	x: y: a: d: b: "foo"
	c: {
		b?: string
		y: a?: matchN(1, [{d: c}])
	}
}
issue3649: cycle: t1: {
	data: #c
	data: a: b: "foo"
	#c: {
		b: string
		a: matchN(1, [#c])
	}
}
-- yamlcycle.cue --
import "encoding/yaml"

yamlNoCycle: {
	// the validator is invoked recursively and also unifies with a concrete
	// value. This should nonetheless not result in a cycle error.
    #c: {
        b?: string
        a?: yaml.Validate(#c)
    }
    data: #c
    data: a: #"{a: "b: foo"}"#
}
selfCycle: t1: {
	c: matchN(1, [{d: c}])
	c: d: {}
}
selfCycle: t2: {
	// Even though only part of the path is unified with concrete data, this
	// should still result in a cycle error.
	c: matchN(1, [{d: c}])
	c: {}
}
selfCycle: yamlVal: t1: {
	x: y: yaml.Validate(x)
	x: y: "{}"
}
selfCycle: yamlVal: t2: {
	// Duplicating validators can cause some tricky code paths, like finalizing
	// a node while still in the middle of validation.
	x: y: yaml.Validate(x)
	x: y: "{}"
	x: y: yaml.Validate(x)
	x: y: "{}"
}
selfCycle: yamlFun: t1:{
	x: y?: yaml.Validate("{}", x)
}
selfCycle: yamlFun: t2: {
	z: x & __no_sharing
	z: y: "{}"
	x: y: yaml.Validate("{}", x)
}
selfCycle: yamlValidatePartial: {
	x: y: yaml.ValidatePartial(x)
	x: y: "{}"
}
-- jsoncycle.cue --
import "encoding/json"

jsonCycle: t1: {
	x: y: json.Validate(x)
	x: y: "{}"
}
-- listmatchncycle.cue --
import "list"

listMatchN: structCycle: {
	x: y: list.MatchN(1, x)
	x: y: [{}]
}
listMatchN: ok: {
	x: y?: list.MatchN(1, x)
    z: x
	z: y: [{}]
}
-- issue3634.cue --
import "list"

issue3634: full: {
	#Schema: {
		required?: [...string] 
		properties?: [string]: null | #Schema
	}
	
	out: len([...#Schema] & list.Repeat([{
		#Schema // removing this fixes the bug!
		properties: foo: required: ["bar", "baz"]
	}], 3))
}
issue3634: reduced: {
	#D: {
		b?: int
		a?: #D
	}
	out: len(#D & list.Repeat([#D & { a: b: 1 }], 1)[0])
}
-- out/evalalpha/stats --
Leaks:  478
Freed:  0
Reused: 0
Allocs: 478
Retain: 0

Unifications: 407
Conjuncts:    745
Disjuncts:    42

CloseIDElems: 126
NumCloseIDs: 191
-- diff/-out/evalalpha/stats<==>+out/eval/stats --
diff old new
--- old
+++ new
@@ -1,9 +1,12 @@
-Leaks:  25
-Freed:  446
-Reused: 434
-Allocs: 37
-Retain: 99
-
-Unifications: 441
-Conjuncts:    821
-Disjuncts:    537
+Leaks:  478
+Freed:  0
+Reused: 0
+Allocs: 478
+Retain: 0
+
+Unifications: 407
+Conjuncts:    745
+Disjuncts:    42
+
+CloseIDElems: 126
+NumCloseIDs: 191
-- out/eval/stats --
Leaks:  25
Freed:  446
Reused: 434
Allocs: 37
Retain: 99

Unifications: 441
Conjuncts:    821
Disjuncts:    537
-- out/evalalpha --
Errors:
noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:4:7
    ./cycle.cue:4:14
    ./cycle.cue:5:13
noCycle.t1.#x.#x: structural cycle:
    ./cycle.cue:4:7
noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:4:7
    ./cycle.cue:4:14
    ./cycle.cue:5:13
issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:31:6
    ./cycle.cue:28:11
    ./cycle.cue:31:13
issue3649.cycle.t1.data.a.a: structural cycle:
    ./cycle.cue:31:6
jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle:
    ./jsoncycle.cue:4:8
    ./jsoncycle.cue:5:8
listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1:
    ./listmatchncycle.cue:4:8
    ./listmatchncycle.cue:4:20
    ./listmatchncycle.cue:5:8
issue3443.matchIf.#S: cannot call non-function matchIf (type struct):
    ./matchn.cue:16:7
issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:35:7
    ./matchn.cue:35:14
    ./matchn.cue:47:7
    ./matchn.cue:48:7
issue3443.cycle1.cycle.s.n: invalid value {n:_} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:35:7
    ./matchn.cue:35:14
    ./matchn.cue:35:22
    ./matchn.cue:48:10
issue3443.cycle1.cycle.s.n.n: structural cycle:
    ./matchn.cue:35:7
issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:55:13
    ./matchn.cue:55:20
issue3443.cycle2.fail.#S.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:55:13
    ./matchn.cue:55:20
    ./matchn.cue:55:28
    ./matchn.cue:55:40
issue3443.cycle2.fail.#S.n.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:55:13
    ./matchn.cue:55:20
    ./matchn.cue:55:28
    ./matchn.cue:55:40
    ./matchn.cue:55:43
issue3443.cycle2.fail.#S.n.n.n: structural cycle:
    ./matchn.cue:55:13
selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:14:5
    ./yamlcycle.cue:14:12
    ./yamlcycle.cue:15:5
selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:14:5
    ./yamlcycle.cue:14:12
    ./yamlcycle.cue:14:20
    ./yamlcycle.cue:15:8
selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:14:5
    ./yamlcycle.cue:14:12
    ./yamlcycle.cue:14:20
    ./yamlcycle.cue:15:8
selfCycle.t1.c.d.d.d: structural cycle:
    ./yamlcycle.cue:14:5
selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
    ./yamlcycle.cue:24:8
    ./yamlcycle.cue:25:8
selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
    ./yamlcycle.cue:30:8
    ./yamlcycle.cue:31:8
    ./yamlcycle.cue:32:8
    ./yamlcycle.cue:33:8
selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle:
    ./yamlcycle.cue:41:8
selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle:
    ./yamlcycle.cue:41:8
selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle:
    ./yamlcycle.cue:44:8
    ./yamlcycle.cue:45:8

Result:
(_|_){
  // [eval]
  noCycle: (_|_){
    // [eval]
    t1: (_|_){
      // [eval]
      _s: (_|_){
        // [eval]
        #x: (_|_){
          // [eval] noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
          //     ./cycle.cue:4:7
          //     ./cycle.cue:4:14
          //     ./cycle.cue:5:13
        }
      }
      #x: (_|_){
        // [eval] noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./cycle.cue:4:7
        //     ./cycle.cue:4:14
        //     ./cycle.cue:5:13
        // noCycle.t1.#x.#x: structural cycle:
        //     ./cycle.cue:4:7
      }
    }
  }
  issue3649: (_|_){
    // [eval]
    noCycle: (struct){
      t1: (struct){
        data: (#struct){
          a: (#struct){
            b: (string){ "foo" }
          }
          b?: (string){ string }
        }
        #c: (#struct){
          b?: (string){ string }
          a?: (_){ matchN(1, (#list){
              0: (_|_){// 〈2;#c〉
              }
            }) }
        }
      }
      t2: (struct){
        x: (struct){
          y: (struct){
            a: (struct){
              d: (struct){
                b: (string){ "foo" }
              }
            }
          }
          b?: (string){ string }
        }
        c: (struct){
          b?: (string){ string }
          y: (struct){
            a?: (_){ matchN(1, (#list){
                0: (_|_){// {
                  //   d: 〈4;c〉
                  // }
                }
              }) }
          }
        }
      }
    }
    cycle: (_|_){
      // [eval]
      t1: (_|_){
        // [eval]
        data: (_|_){
          // [eval]
          a: (_|_){
            // [eval] issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1:
            //     ./cycle.cue:31:6
            //     ./cycle.cue:28:11
            //     ./cycle.cue:31:13
            // issue3649.cycle.t1.data.a.a: structural cycle:
            //     ./cycle.cue:31:6
            b: (string){ "foo" }
          }
          b: (string){ string }
        }
        #c: (#struct){
          b: (string){ string }
          a: (_){ matchN(1, (#list){
              0: (_|_){// 〈2;#c〉
              }
            }) }
        }
      }
    }
  }
  builtinCyclePerm0: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  builtinCyclePerm1: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  builtinCyclePerm2: (struct){
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
    X: (string){ "mod.test" }
  }
  builtinCyclePerm3: (struct){
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
    X: (string){ "mod.test" }
  }
  builtinCyclePerm4: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  builtinCyclePerm5: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  issue3634: (struct){
    full: (struct){
      #Schema: (#struct){
        required?: (list){
        }
        properties?: (#struct){
        }
      }
      out: (int){ 3 }
    }
    reduced: (struct){
      #D: (#struct){
        b?: (int){ int }
        a?: (_|_){
          // [structural cycle] issue3634.reduced.#D.a: structural cycle
        }
      }
      out: (int){ 1 }
    }
  }
  jsonCycle: (_|_){
    // [structural cycle]
    t1: (_|_){
      // [structural cycle]
      x: (_|_){
        // [structural cycle]
        y: (_|_){
          // [structural cycle] jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle:
          //     ./jsoncycle.cue:4:8
          //     ./jsoncycle.cue:5:8
        }
      }
    }
  }
  listMatchN: (_|_){
    // [eval]
    structCycle: (_|_){
      // [eval]
      x: (_|_){
        // [eval]
        y: (_|_){
          // [eval] listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1:
          //     ./listmatchncycle.cue:4:8
          //     ./listmatchncycle.cue:4:20
          //     ./listmatchncycle.cue:5:8
          0: (struct){
          }
        }
      }
    }
    ok: (struct){
      x: (struct){
        y?: (list){ list.MatchN(1, listMatchN.ok.x) }
      }
      z: (struct){
        y: (#list){
          0: (struct){
          }
        }
      }
    }
  }
  issue3410: (struct){
    _s: (struct){
      #x: (_){ matchN(1, (#list){
          0: (_|_){// 〈2;_s〉
          }
          1: (_|_){// [
            //   ...〈3;_s〉,
            // ]
          }
        }) }
    }
    #x: (_){ matchN(1, (#list){
        0: (_|_){// 〈2;_s〉
        }
        1: (_|_){// [
          //   ...〈3;_s〉,
          // ]
        }
      }) }
  }
  issue3420: (struct){
    matches1: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// _
          }
          1: (_|_){// _|_(explicit error (_|_ literal) in source)
          }
        }) }
      s: (int){ 2 }
    }
  }
  issue3443: (_|_){
    // [eval]
    matchIf: (_|_){
      // [eval]
      #S: (_|_){
        // [eval] issue3443.matchIf.#S: cannot call non-function matchIf (type struct):
        //     ./matchn.cue:16:7
      }
    }
    noCycle: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// {
            //   n?: (〈2;#S〉 & (int|{}))
            // }
          }
        }) }
      noHang: (struct){
        s: (#struct){
          n: (struct){
            n: (_){ _ }
          }
        }
      }
    }
    noCycle2: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// {
            //   n?: (int|〈2;#S〉)
            // }
          }
        }) }
    }
    cycle1: (_|_){
      // [eval]
      #S: (_){ matchN(1, (#list){
          0: (_|_){// {
            //   n: 〈2;#S〉
            // }
          }
        }) }
      ok: (struct){
        s: (_){ matchN(1, (#list){
            0: (_|_){// {
              //   n: 〈2;#S〉
              // }
            }
          }) }
      }
      cycle: (_|_){
        // [eval]
        s: (_|_){
          // [eval] issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:35:7
          //     ./matchn.cue:35:14
          //     ./matchn.cue:47:7
          //     ./matchn.cue:48:7
          // issue3443.cycle1.cycle.s.n: invalid value {n:_} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:35:7
          //     ./matchn.cue:35:14
          //     ./matchn.cue:35:22
          //     ./matchn.cue:48:10
          // issue3443.cycle1.cycle.s.n.n: structural cycle:
          //     ./matchn.cue:35:7
          n: (struct){
            n: (_){ _ }
          }
        }
      }
    }
    cycle2: (_|_){
      // [eval]
      fail: (_|_){
        // [eval]
        #S: (_|_){
          // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:55:13
          //     ./matchn.cue:55:20
          // issue3443.cycle2.fail.#S.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:55:13
          //     ./matchn.cue:55:20
          //     ./matchn.cue:55:28
          //     ./matchn.cue:55:40
          // issue3443.cycle2.fail.#S.n.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:55:13
          //     ./matchn.cue:55:20
          //     ./matchn.cue:55:28
          //     ./matchn.cue:55:40
          //     ./matchn.cue:55:43
          // issue3443.cycle2.fail.#S.n.n.n: structural cycle:
          //     ./matchn.cue:55:13
          n: (#struct){
            n: (#struct){
              n: (_){ _ }
            }
          }
        }
      }
    }
  }
  issue3633: (struct){
    final: (struct){
      data: (_|_){
        // [incomplete] issue3633.final.data: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./matchn.cue:63:6
        //     ./matchn.cue:62:8
        //     ./matchn.cue:63:13
        // issue3633.final.data: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./matchn.cue:63:17
        //     ./matchn.cue:62:8
        //     ./matchn.cue:63:24
        // issue3633.final.data.a: field is required but not present:
        //     ./matchn.cue:63:17
        //     ./matchn.cue:63:29
      }
      #s: (_){ matchN(1, (#list){
          0: (_|_){// matchN(1, [
            //   {
            //     a!: _
            //   },
            // ])
          }
        }) }
    }
  }
  yamlNoCycle: (struct){
    #c: (#struct){
      b?: (string){ string }
      a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) }
    }
    data: (#struct){
      a: (string){ "{a: \"b: foo\"}" }
      b?: (string){ string }
    }
  }
  selfCycle: (_|_){
    // [eval]
    t1: (_|_){
      // [eval]
      c: (_|_){
        // [eval] selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:14:5
        //     ./yamlcycle.cue:14:12
        //     ./yamlcycle.cue:15:5
        // selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:14:5
        //     ./yamlcycle.cue:14:12
        //     ./yamlcycle.cue:14:20
        //     ./yamlcycle.cue:15:8
        // selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:14:5
        //     ./yamlcycle.cue:14:12
        //     ./yamlcycle.cue:14:20
        //     ./yamlcycle.cue:15:8
        // selfCycle.t1.c.d.d.d: structural cycle:
        //     ./yamlcycle.cue:14:5
        d: (struct){
        }
      }
    }
    t2: (struct){
      c: (struct){
      }
    }
    yamlVal: (_|_){
      // [eval]
      t1: (_|_){
        // [eval]
        x: (_|_){
          // [eval]
          y: (_|_){
            // [eval] selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
            //     ./yamlcycle.cue:24:8
            //     ./yamlcycle.cue:25:8
          }
        }
      }
      t2: (_|_){
        // [eval]
        x: (_|_){
          // [eval]
          y: (_|_){
            // [eval] selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
            //     ./yamlcycle.cue:30:8
            //     ./yamlcycle.cue:31:8
            //     ./yamlcycle.cue:32:8
            //     ./yamlcycle.cue:33:8
          }
        }
      }
    }
    yamlFun: (_|_){
      // [eval]
      t1: (struct){
        x: (struct){
          y?: (bool){ true }
        }
      }
      t2: (_|_){
        // [eval]
        z: (_|_){
          // [eval]
          y: (_|_){
            // [eval] selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle:
            //     ./yamlcycle.cue:41:8
          }
        }
        x: (_|_){
          // [eval]
          y: (_|_){
            // [eval] selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle:
            //     ./yamlcycle.cue:41:8
          }
        }
      }
    }
    yamlValidatePartial: (_|_){
      // [structural cycle]
      x: (_|_){
        // [structural cycle]
        y: (_|_){
          // [structural cycle] selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle:
          //     ./yamlcycle.cue:44:8
          //     ./yamlcycle.cue:45:8
        }
      }
    }
  }
}
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -3,24 +3,39 @@
     ./cycle.cue:4:7
     ./cycle.cue:4:14
     ./cycle.cue:5:13
-noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-    ./cycle.cue:4:7
-    ./cycle.cue:4:14
-    ./cycle.cue:5:13
+noCycle.t1.#x.#x: structural cycle:
+    ./cycle.cue:4:7
 noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
     ./cycle.cue:4:7
     ./cycle.cue:4:14
     ./cycle.cue:5:13
-noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-    ./cycle.cue:4:7
-    ./cycle.cue:4:14
-    ./cycle.cue:5:13
-jsonCycle.t1.x.y.y: structural cycle:
-    ./jsoncycle.cue:4:22
-listMatchN.structCycle.x.y.y: structural cycle:
-    ./listmatchncycle.cue:4:23
+issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1:
+    ./cycle.cue:31:6
+    ./cycle.cue:28:11
+    ./cycle.cue:31:13
+issue3649.cycle.t1.data.a.a: structural cycle:
+    ./cycle.cue:31:6
+jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle:
+    ./jsoncycle.cue:4:8
+    ./jsoncycle.cue:5:8
+listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1:
+    ./listmatchncycle.cue:4:8
+    ./listmatchncycle.cue:4:20
+    ./listmatchncycle.cue:5:8
 issue3443.matchIf.#S: cannot call non-function matchIf (type struct):
     ./matchn.cue:16:7
+issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN): 0 matched, expected 1:
+    ./matchn.cue:35:7
+    ./matchn.cue:35:14
+    ./matchn.cue:47:7
+    ./matchn.cue:48:7
+issue3443.cycle1.cycle.s.n: invalid value {n:_} (does not satisfy matchN): 0 matched, expected 1:
+    ./matchn.cue:35:7
+    ./matchn.cue:35:14
+    ./matchn.cue:35:22
+    ./matchn.cue:48:10
+issue3443.cycle1.cycle.s.n.n: structural cycle:
+    ./matchn.cue:35:7
 issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
     ./matchn.cue:55:13
     ./matchn.cue:55:20
@@ -53,26 +68,21 @@
     ./yamlcycle.cue:15:8
 selfCycle.t1.c.d.d.d: structural cycle:
     ./yamlcycle.cue:14:5
-selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-    ./yamlcycle.cue:20:5
-    ./yamlcycle.cue:20:12
-    ./yamlcycle.cue:21:5
-selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-    ./yamlcycle.cue:20:5
-    ./yamlcycle.cue:20:12
-    ./yamlcycle.cue:20:20
-selfCycle.t2.c.d.d: structural cycle:
-    ./yamlcycle.cue:20:5
-selfCycle.yamlVal.t1.x.y.y: structural cycle:
-    ./yamlcycle.cue:24:22
-selfCycle.yamlVal.t2.x.y.y: structural cycle:
-    ./yamlcycle.cue:32:22
-selfCycle.yamlFun.t1.x.y.y: structural cycle:
-    ./yamlcycle.cue:36:29
-selfCycle.yamlFun.t2.x.y.y: structural cycle:
-    ./yamlcycle.cue:41:28
-selfCycle.yamlValidatePartial.x.y.y: structural cycle:
-    ./yamlcycle.cue:44:29
+selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
+    ./yamlcycle.cue:24:8
+    ./yamlcycle.cue:25:8
+selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
+    ./yamlcycle.cue:30:8
+    ./yamlcycle.cue:31:8
+    ./yamlcycle.cue:32:8
+    ./yamlcycle.cue:33:8
+selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle:
+    ./yamlcycle.cue:41:8
+selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle:
+    ./yamlcycle.cue:41:8
+selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle:
+    ./yamlcycle.cue:44:8
+    ./yamlcycle.cue:45:8
 
 Result:
 (_|_){
@@ -88,10 +98,6 @@
           //     ./cycle.cue:4:7
           //     ./cycle.cue:4:14
           //     ./cycle.cue:5:13
-          // noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-          //     ./cycle.cue:4:7
-          //     ./cycle.cue:4:14
-          //     ./cycle.cue:5:13
         }
       }
       #x: (_|_){
@@ -99,21 +105,20 @@
         //     ./cycle.cue:4:7
         //     ./cycle.cue:4:14
         //     ./cycle.cue:5:13
-        // noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-        //     ./cycle.cue:4:7
-        //     ./cycle.cue:4:14
-        //     ./cycle.cue:5:13
-      }
-    }
-  }
-  issue3649: (struct){
-    noCycle: (struct){
-      t1: (struct){
-        data: (#struct){
-          b?: (string){ string }
-          a: (struct){
-            b: (string){ "foo" }
-          }
+        // noCycle.t1.#x.#x: structural cycle:
+        //     ./cycle.cue:4:7
+      }
+    }
+  }
+  issue3649: (_|_){
+    // [eval]
+    noCycle: (struct){
+      t1: (struct){
+        data: (#struct){
+          a: (#struct){
+            b: (string){ "foo" }
+          }
+          b?: (string){ string }
         }
         #c: (#struct){
           b?: (string){ string }
@@ -125,7 +130,6 @@
       }
       t2: (struct){
         x: (struct){
-          b?: (string){ string }
           y: (struct){
             a: (struct){
               d: (struct){
@@ -133,6 +137,7 @@
               }
             }
           }
+          b?: (string){ string }
         }
         c: (struct){
           b?: (string){ string }
@@ -147,13 +152,22 @@
         }
       }
     }
-    cycle: (struct){
-      t1: (struct){
-        data: (#struct){
-          b: (string){ string }
-          a: (struct){
-            b: (string){ "foo" }
-          }
+    cycle: (_|_){
+      // [eval]
+      t1: (_|_){
+        // [eval]
+        data: (_|_){
+          // [eval]
+          a: (_|_){
+            // [eval] issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1:
+            //     ./cycle.cue:31:6
+            //     ./cycle.cue:28:11
+            //     ./cycle.cue:31:13
+            // issue3649.cycle.t1.data.a.a: structural cycle:
+            //     ./cycle.cue:31:6
+            b: (string){ "foo" }
+          }
+          b: (string){ string }
         }
         #c: (#struct){
           b: (string){ string }
@@ -244,8 +258,12 @@
     t1: (_|_){
       // [structural cycle]
       x: (_|_){
-        // [structural cycle] jsonCycle.t1.x.y.y: structural cycle:
-        //     ./jsoncycle.cue:4:22
+        // [structural cycle]
+        y: (_|_){
+          // [structural cycle] jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle:
+          //     ./jsoncycle.cue:4:8
+          //     ./jsoncycle.cue:5:8
+        }
       }
     }
   }
@@ -254,8 +272,15 @@
     structCycle: (_|_){
       // [eval]
       x: (_|_){
-        // [eval] listMatchN.structCycle.x.y.y: structural cycle:
-        //     ./listmatchncycle.cue:4:23
+        // [eval]
+        y: (_|_){
+          // [eval] listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1:
+          //     ./listmatchncycle.cue:4:8
+          //     ./listmatchncycle.cue:4:20
+          //     ./listmatchncycle.cue:5:8
+          0: (struct){
+          }
+        }
       }
     }
     ok: (struct){
@@ -318,7 +343,7 @@
           }
         }) }
       noHang: (struct){
-        s: (struct){
+        s: (#struct){
           n: (struct){
             n: (_){ _ }
           }
@@ -333,7 +358,8 @@
           }
         }) }
     }
-    cycle1: (struct){
+    cycle1: (_|_){
+      // [eval]
       #S: (_){ matchN(1, (#list){
           0: (_|_){// {
             //   n: 〈2;#S〉
@@ -348,8 +374,21 @@
             }
           }) }
       }
-      cycle: (struct){
-        s: (struct){
+      cycle: (_|_){
+        // [eval]
+        s: (_|_){
+          // [eval] issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN): 0 matched, expected 1:
+          //     ./matchn.cue:35:7
+          //     ./matchn.cue:35:14
+          //     ./matchn.cue:47:7
+          //     ./matchn.cue:48:7
+          // issue3443.cycle1.cycle.s.n: invalid value {n:_} (does not satisfy matchN): 0 matched, expected 1:
+          //     ./matchn.cue:35:7
+          //     ./matchn.cue:35:14
+          //     ./matchn.cue:35:22
+          //     ./matchn.cue:48:10
+          // issue3443.cycle1.cycle.s.n.n: structural cycle:
+          //     ./matchn.cue:35:7
           n: (struct){
             n: (_){ _ }
           }
@@ -393,13 +432,13 @@
         //     ./matchn.cue:63:6
         //     ./matchn.cue:62:8
         //     ./matchn.cue:63:13
-        // issue3633.final.a: field is required but not present:
-        //     ./matchn.cue:63:17
-        //     ./matchn.cue:63:29
         // issue3633.final.data: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
         //     ./matchn.cue:63:17
         //     ./matchn.cue:62:8
         //     ./matchn.cue:63:24
+        // issue3633.final.data.a: field is required but not present:
+        //     ./matchn.cue:63:17
+        //     ./matchn.cue:63:29
       }
       #s: (_){ matchN(1, (#list){
           0: (_|_){// matchN(1, [
@@ -417,8 +456,8 @@
       a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) }
     }
     data: (#struct){
-      b?: (string){ string }
       a: (string){ "{a: \"b: foo\"}" }
+      b?: (string){ string }
     }
   }
   selfCycle: (_|_){
@@ -446,19 +485,8 @@
         }
       }
     }
-    t2: (_|_){
-      // [eval]
-      c: (_|_){
-        // [eval] selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-        //     ./yamlcycle.cue:20:5
-        //     ./yamlcycle.cue:20:12
-        //     ./yamlcycle.cue:21:5
-        // selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
-        //     ./yamlcycle.cue:20:5
-        //     ./yamlcycle.cue:20:12
-        //     ./yamlcycle.cue:20:20
-        // selfCycle.t2.c.d.d: structural cycle:
-        //     ./yamlcycle.cue:20:5
+    t2: (struct){
+      c: (struct){
       }
     }
     yamlVal: (_|_){
@@ -466,25 +494,33 @@
       t1: (_|_){
         // [eval]
         x: (_|_){
-          // [eval] selfCycle.yamlVal.t1.x.y.y: structural cycle:
-          //     ./yamlcycle.cue:24:22
-        }
-      }
-      t2: (_|_){
-        // [eval]
-        x: (_|_){
-          // [eval] selfCycle.yamlVal.t2.x.y.y: structural cycle:
-          //     ./yamlcycle.cue:32:22
+          // [eval]
+          y: (_|_){
+            // [eval] selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
+            //     ./yamlcycle.cue:24:8
+            //     ./yamlcycle.cue:25:8
+          }
+        }
+      }
+      t2: (_|_){
+        // [eval]
+        x: (_|_){
+          // [eval]
+          y: (_|_){
+            // [eval] selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle:
+            //     ./yamlcycle.cue:30:8
+            //     ./yamlcycle.cue:31:8
+            //     ./yamlcycle.cue:32:8
+            //     ./yamlcycle.cue:33:8
+          }
         }
       }
     }
     yamlFun: (_|_){
       // [eval]
-      t1: (_|_){
-        // [structural cycle]
-        x: (_|_){
-          // [structural cycle] selfCycle.yamlFun.t1.x.y.y: structural cycle:
-          //     ./yamlcycle.cue:36:29
+      t1: (struct){
+        x: (struct){
+          y?: (bool){ true }
         }
       }
       t2: (_|_){
@@ -492,13 +528,16 @@
         z: (_|_){
           // [eval]
           y: (_|_){
-            // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle:
-            //     ./yamlcycle.cue:41:28
-          }
-        }
-        x: (_|_){
-          // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle:
-          //     ./yamlcycle.cue:41:28
+            // [eval] selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle:
+            //     ./yamlcycle.cue:41:8
+          }
+        }
+        x: (_|_){
+          // [eval]
+          y: (_|_){
+            // [eval] selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle:
+            //     ./yamlcycle.cue:41:8
+          }
         }
       }
     }
@@ -505,8 +544,12 @@
     yamlValidatePartial: (_|_){
       // [structural cycle]
       x: (_|_){
-        // [structural cycle] selfCycle.yamlValidatePartial.x.y.y: structural cycle:
-        //     ./yamlcycle.cue:44:29
+        // [structural cycle]
+        y: (_|_){
+          // [structural cycle] selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle:
+          //     ./yamlcycle.cue:44:8
+          //     ./yamlcycle.cue:45:8
+        }
       }
     }
   }
-- diff/todo/p2 --
issue3443: Sort out differences in reporting of cycles.
-- out/eval --
Errors:
noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:4:7
    ./cycle.cue:4:14
    ./cycle.cue:5:13
noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:4:7
    ./cycle.cue:4:14
    ./cycle.cue:5:13
noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:4:7
    ./cycle.cue:4:14
    ./cycle.cue:5:13
noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./cycle.cue:4:7
    ./cycle.cue:4:14
    ./cycle.cue:5:13
jsonCycle.t1.x.y.y: structural cycle:
    ./jsoncycle.cue:4:22
listMatchN.structCycle.x.y.y: structural cycle:
    ./listmatchncycle.cue:4:23
issue3443.matchIf.#S: cannot call non-function matchIf (type struct):
    ./matchn.cue:16:7
issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:55:13
    ./matchn.cue:55:20
issue3443.cycle2.fail.#S.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:55:13
    ./matchn.cue:55:20
    ./matchn.cue:55:28
    ./matchn.cue:55:40
issue3443.cycle2.fail.#S.n.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
    ./matchn.cue:55:13
    ./matchn.cue:55:20
    ./matchn.cue:55:28
    ./matchn.cue:55:40
    ./matchn.cue:55:43
issue3443.cycle2.fail.#S.n.n.n: structural cycle:
    ./matchn.cue:55:13
selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:14:5
    ./yamlcycle.cue:14:12
    ./yamlcycle.cue:15:5
selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:14:5
    ./yamlcycle.cue:14:12
    ./yamlcycle.cue:14:20
    ./yamlcycle.cue:15:8
selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:14:5
    ./yamlcycle.cue:14:12
    ./yamlcycle.cue:14:20
    ./yamlcycle.cue:15:8
selfCycle.t1.c.d.d.d: structural cycle:
    ./yamlcycle.cue:14:5
selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:20:5
    ./yamlcycle.cue:20:12
    ./yamlcycle.cue:21:5
selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
    ./yamlcycle.cue:20:5
    ./yamlcycle.cue:20:12
    ./yamlcycle.cue:20:20
selfCycle.t2.c.d.d: structural cycle:
    ./yamlcycle.cue:20:5
selfCycle.yamlVal.t1.x.y.y: structural cycle:
    ./yamlcycle.cue:24:22
selfCycle.yamlVal.t2.x.y.y: structural cycle:
    ./yamlcycle.cue:32:22
selfCycle.yamlFun.t1.x.y.y: structural cycle:
    ./yamlcycle.cue:36:29
selfCycle.yamlFun.t2.x.y.y: structural cycle:
    ./yamlcycle.cue:41:28
selfCycle.yamlValidatePartial.x.y.y: structural cycle:
    ./yamlcycle.cue:44:29

Result:
(_|_){
  // [eval]
  noCycle: (_|_){
    // [eval]
    t1: (_|_){
      // [eval]
      _s: (_|_){
        // [eval]
        #x: (_|_){
          // [eval] noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
          //     ./cycle.cue:4:7
          //     ./cycle.cue:4:14
          //     ./cycle.cue:5:13
          // noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
          //     ./cycle.cue:4:7
          //     ./cycle.cue:4:14
          //     ./cycle.cue:5:13
        }
      }
      #x: (_|_){
        // [eval] noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./cycle.cue:4:7
        //     ./cycle.cue:4:14
        //     ./cycle.cue:5:13
        // noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./cycle.cue:4:7
        //     ./cycle.cue:4:14
        //     ./cycle.cue:5:13
      }
    }
  }
  issue3649: (struct){
    noCycle: (struct){
      t1: (struct){
        data: (#struct){
          b?: (string){ string }
          a: (struct){
            b: (string){ "foo" }
          }
        }
        #c: (#struct){
          b?: (string){ string }
          a?: (_){ matchN(1, (#list){
              0: (_|_){// 〈2;#c〉
              }
            }) }
        }
      }
      t2: (struct){
        x: (struct){
          b?: (string){ string }
          y: (struct){
            a: (struct){
              d: (struct){
                b: (string){ "foo" }
              }
            }
          }
        }
        c: (struct){
          b?: (string){ string }
          y: (struct){
            a?: (_){ matchN(1, (#list){
                0: (_|_){// {
                  //   d: 〈4;c〉
                  // }
                }
              }) }
          }
        }
      }
    }
    cycle: (struct){
      t1: (struct){
        data: (#struct){
          b: (string){ string }
          a: (struct){
            b: (string){ "foo" }
          }
        }
        #c: (#struct){
          b: (string){ string }
          a: (_){ matchN(1, (#list){
              0: (_|_){// 〈2;#c〉
              }
            }) }
        }
      }
    }
  }
  builtinCyclePerm0: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  builtinCyclePerm1: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  builtinCyclePerm2: (struct){
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
    X: (string){ "mod.test" }
  }
  builtinCyclePerm3: (struct){
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
    X: (string){ "mod.test" }
  }
  builtinCyclePerm4: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  builtinCyclePerm5: (struct){
    X: (string){ "mod.test" }
    Y: (struct){
      #components: (#struct){
        host: (string){ "mod.test" }
      }
      host: (string){ "mod.test" }
    }
  }
  issue3634: (struct){
    full: (struct){
      #Schema: (#struct){
        required?: (list){
        }
        properties?: (#struct){
        }
      }
      out: (int){ 3 }
    }
    reduced: (struct){
      #D: (#struct){
        b?: (int){ int }
        a?: (_|_){
          // [structural cycle] issue3634.reduced.#D.a: structural cycle
        }
      }
      out: (int){ 1 }
    }
  }
  jsonCycle: (_|_){
    // [structural cycle]
    t1: (_|_){
      // [structural cycle]
      x: (_|_){
        // [structural cycle] jsonCycle.t1.x.y.y: structural cycle:
        //     ./jsoncycle.cue:4:22
      }
    }
  }
  listMatchN: (_|_){
    // [eval]
    structCycle: (_|_){
      // [eval]
      x: (_|_){
        // [eval] listMatchN.structCycle.x.y.y: structural cycle:
        //     ./listmatchncycle.cue:4:23
      }
    }
    ok: (struct){
      x: (struct){
        y?: (list){ list.MatchN(1, listMatchN.ok.x) }
      }
      z: (struct){
        y: (#list){
          0: (struct){
          }
        }
      }
    }
  }
  issue3410: (struct){
    _s: (struct){
      #x: (_){ matchN(1, (#list){
          0: (_|_){// 〈2;_s〉
          }
          1: (_|_){// [
            //   ...〈3;_s〉,
            // ]
          }
        }) }
    }
    #x: (_){ matchN(1, (#list){
        0: (_|_){// 〈2;_s〉
        }
        1: (_|_){// [
          //   ...〈3;_s〉,
          // ]
        }
      }) }
  }
  issue3420: (struct){
    matches1: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// _
          }
          1: (_|_){// _|_(explicit error (_|_ literal) in source)
          }
        }) }
      s: (int){ 2 }
    }
  }
  issue3443: (_|_){
    // [eval]
    matchIf: (_|_){
      // [eval]
      #S: (_|_){
        // [eval] issue3443.matchIf.#S: cannot call non-function matchIf (type struct):
        //     ./matchn.cue:16:7
      }
    }
    noCycle: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// {
            //   n?: (〈2;#S〉 & (int|{}))
            // }
          }
        }) }
      noHang: (struct){
        s: (struct){
          n: (struct){
            n: (_){ _ }
          }
        }
      }
    }
    noCycle2: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// {
            //   n?: (int|〈2;#S〉)
            // }
          }
        }) }
    }
    cycle1: (struct){
      #S: (_){ matchN(1, (#list){
          0: (_|_){// {
            //   n: 〈2;#S〉
            // }
          }
        }) }
      ok: (struct){
        s: (_){ matchN(1, (#list){
            0: (_|_){// {
              //   n: 〈2;#S〉
              // }
            }
          }) }
      }
      cycle: (struct){
        s: (struct){
          n: (struct){
            n: (_){ _ }
          }
        }
      }
    }
    cycle2: (_|_){
      // [eval]
      fail: (_|_){
        // [eval]
        #S: (_|_){
          // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:55:13
          //     ./matchn.cue:55:20
          // issue3443.cycle2.fail.#S.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:55:13
          //     ./matchn.cue:55:20
          //     ./matchn.cue:55:28
          //     ./matchn.cue:55:40
          // issue3443.cycle2.fail.#S.n.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1:
          //     ./matchn.cue:55:13
          //     ./matchn.cue:55:20
          //     ./matchn.cue:55:28
          //     ./matchn.cue:55:40
          //     ./matchn.cue:55:43
          // issue3443.cycle2.fail.#S.n.n.n: structural cycle:
          //     ./matchn.cue:55:13
          n: (#struct){
            n: (#struct){
              n: (_){ _ }
            }
          }
        }
      }
    }
  }
  issue3633: (struct){
    final: (struct){
      data: (_|_){
        // [incomplete] issue3633.final.data: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./matchn.cue:63:6
        //     ./matchn.cue:62:8
        //     ./matchn.cue:63:13
        // issue3633.final.a: field is required but not present:
        //     ./matchn.cue:63:17
        //     ./matchn.cue:63:29
        // issue3633.final.data: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./matchn.cue:63:17
        //     ./matchn.cue:62:8
        //     ./matchn.cue:63:24
      }
      #s: (_){ matchN(1, (#list){
          0: (_|_){// matchN(1, [
            //   {
            //     a!: _
            //   },
            // ])
          }
        }) }
    }
  }
  yamlNoCycle: (struct){
    #c: (#struct){
      b?: (string){ string }
      a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) }
    }
    data: (#struct){
      b?: (string){ string }
      a: (string){ "{a: \"b: foo\"}" }
    }
  }
  selfCycle: (_|_){
    // [eval]
    t1: (_|_){
      // [eval]
      c: (_|_){
        // [eval] selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:14:5
        //     ./yamlcycle.cue:14:12
        //     ./yamlcycle.cue:15:5
        // selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:14:5
        //     ./yamlcycle.cue:14:12
        //     ./yamlcycle.cue:14:20
        //     ./yamlcycle.cue:15:8
        // selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:14:5
        //     ./yamlcycle.cue:14:12
        //     ./yamlcycle.cue:14:20
        //     ./yamlcycle.cue:15:8
        // selfCycle.t1.c.d.d.d: structural cycle:
        //     ./yamlcycle.cue:14:5
        d: (struct){
        }
      }
    }
    t2: (_|_){
      // [eval]
      c: (_|_){
        // [eval] selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:20:5
        //     ./yamlcycle.cue:20:12
        //     ./yamlcycle.cue:21:5
        // selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1:
        //     ./yamlcycle.cue:20:5
        //     ./yamlcycle.cue:20:12
        //     ./yamlcycle.cue:20:20
        // selfCycle.t2.c.d.d: structural cycle:
        //     ./yamlcycle.cue:20:5
      }
    }
    yamlVal: (_|_){
      // [eval]
      t1: (_|_){
        // [eval]
        x: (_|_){
          // [eval] selfCycle.yamlVal.t1.x.y.y: structural cycle:
          //     ./yamlcycle.cue:24:22
        }
      }
      t2: (_|_){
        // [eval]
        x: (_|_){
          // [eval] selfCycle.yamlVal.t2.x.y.y: structural cycle:
          //     ./yamlcycle.cue:32:22
        }
      }
    }
    yamlFun: (_|_){
      // [eval]
      t1: (_|_){
        // [structural cycle]
        x: (_|_){
          // [structural cycle] selfCycle.yamlFun.t1.x.y.y: structural cycle:
          //     ./yamlcycle.cue:36:29
        }
      }
      t2: (_|_){
        // [eval]
        z: (_|_){
          // [eval]
          y: (_|_){
            // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle:
            //     ./yamlcycle.cue:41:28
          }
        }
        x: (_|_){
          // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle:
          //     ./yamlcycle.cue:41:28
        }
      }
    }
    yamlValidatePartial: (_|_){
      // [structural cycle]
      x: (_|_){
        // [structural cycle] selfCycle.yamlValidatePartial.x.y.y: structural cycle:
        //     ./yamlcycle.cue:44:29
      }
    }
  }
}
-- out/compile --
--- cycle.cue
{
  noCycle: {
    t1: {
      〈0;_s〉
      _s: {
        #x: matchN(1, [
          〈2;_s〉,
        ])
        #x: {}
      }
    }
  }
  issue3649: {
    noCycle: {
      t1: {
        data: 〈0;#c〉
        data: {
          a: {
            b: "foo"
          }
        }
        #c: {
          b?: string
          a?: matchN(1, [
            〈2;#c〉,
          ])
        }
      }
    }
  }
  issue3649: {
    noCycle: {
      t2: {
        x: 〈0;c〉
        x: {
          y: {
            a: {
              d: {
                b: "foo"
              }
            }
          }
        }
        c: {
          b?: string
          y: {
            a?: matchN(1, [
              {
                d: 〈4;c〉
              },
            ])
          }
        }
      }
    }
  }
  issue3649: {
    cycle: {
      t1: {
        data: 〈0;#c〉
        data: {
          a: {
            b: "foo"
          }
        }
        #c: {
          b: string
          a: matchN(1, [
            〈2;#c〉,
          ])
        }
      }
    }
  }
}
--- in.cue
{
  builtinCyclePerm0: {
    X: "mod.test"
    Y: {
      #components: 〈import;regexp〉.FindNamedSubmatch("^(?P<host>[[:alnum:].]+)$", 〈1;X〉)
      host: 〈0;#components〉.host
    }
    X: 〈0;Y〉.host
  }
  builtinCyclePerm1: {
    X: 〈0;Y〉.host
    Y: {
      #components: 〈import;regexp〉.FindNamedSubmatch("^(?P<host>[[:alnum:].]+)$", 〈1;X〉)
      host: 〈0;#components〉.host
    }
    X: "mod.test"
  }
  builtinCyclePerm2: {
    Y: {
      #components: 〈import;regexp〉.FindNamedSubmatch("^(?P<host>[[:alnum:].]+)$", 〈1;X〉)
      host: 〈0;#components〉.host
    }
    X: 〈0;Y〉.host
    X: "mod.test"
  }
  builtinCyclePerm3: {
    Y: {
      #components: 〈import;regexp〉.FindNamedSubmatch("^(?P<host>[[:alnum:].]+)$", 〈1;X〉)
      host: 〈0;#components〉.host
    }
    X: "mod.test"
    X: 〈0;Y〉.host
  }
  builtinCyclePerm4: {
    X: "mod.test"
    X: 〈0;Y〉.host
    Y: {
      #components: 〈import;regexp〉.FindNamedSubmatch("^(?P<host>[[:alnum:].]+)$", 〈1;X〉)
      host: 〈0;#components〉.host
    }
  }
  builtinCyclePerm5: {
    X: 〈0;Y〉.host
    X: "mod.test"
    Y: {
      #components: 〈import;regexp〉.FindNamedSubmatch("^(?P<host>[[:alnum:].]+)$", 〈1;X〉)
      host: 〈0;#components〉.host
    }
  }
}
--- issue3634.cue
{
  issue3634: {
    full: {
      #Schema: {
        required?: [
          ...string,
        ]
        properties?: {
          [string]: (null|〈2;#Schema〉)
        }
      }
      out: len(([
        ...〈1;#Schema〉,
      ] & 〈import;list〉.Repeat([
        {
          〈2;#Schema〉
          properties: {
            foo: {
              required: [
                "bar",
                "baz",
              ]
            }
          }
        },
      ], 3)))
    }
  }
  issue3634: {
    reduced: {
      #D: {
        b?: int
        a?: 〈1;#D〉
      }
      out: len((〈0;#D〉 & 〈import;list〉.Repeat([
        (〈1;#D〉 & {
          a: {
            b: 1
          }
        }),
      ], 1)[0]))
    }
  }
}
--- jsoncycle.cue
{
  jsonCycle: {
    t1: {
      x: {
        y: 〈import;"encoding/json"〉.Validate(〈1;x〉)
      }
      x: {
        y: "{}"
      }
    }
  }
}
--- listmatchncycle.cue
{
  listMatchN: {
    structCycle: {
      x: {
        y: 〈import;list〉.MatchN(1, 〈1;x〉)
      }
      x: {
        y: [
          {},
        ]
      }
    }
  }
  listMatchN: {
    ok: {
      x: {
        y?: 〈import;list〉.MatchN(1, 〈1;x〉)
      }
      z: 〈0;x〉
      z: {
        y: [
          {},
        ]
      }
    }
  }
}
--- matchn.cue
{
  issue3410: {
    〈0;_s〉
    _s: {
      #x: matchN(1, [
        〈2;_s〉,
        [
          ...〈3;_s〉,
        ],
      ])
    }
  }
  issue3420: {
    matches1: {
      #S: matchN(1, [
        _,
        _|_(explicit error (_|_ literal) in source),
      ])
      s: 2
    }
  }
  issue3443: {
    matchIf: {
      #S: 〈1;matchIf〉({
        x?: "b"
      }, {
        n?: (〈1;#S〉 & (int|{}))
      }, _)
    }
    noCycle: {
      #S: matchN(1, [
        {
          n?: (〈2;#S〉 & (int|{}))
        },
      ])
      noHang: {
        s: 〈1;#S〉
        s: {
          n: {
            n: _
          }
        }
      }
    }
    noCycle2: {
      #S: matchN(1, [
        {
          n?: (int|〈2;#S〉)
        },
      ])
    }
    cycle1: {
      #S: matchN(1, [
        {
          n: 〈2;#S〉
        },
      ])
      ok: {
        s: 〈1;#S〉
        s: _
      }
      cycle: {
        s: 〈1;#S〉
        s: {
          n: {
            n: _
          }
        }
      }
    }
    cycle2: {
      fail: {
        #S: (matchN(1, [
          {
            n: 〈2;#S〉
          },
        ]) & {
          n: {
            n: {
              n: _
            }
          }
        })
      }
    }
  }
  issue3633: {
    final: {
      data: ({} & 〈0;#s〉)
      #s: matchN(1, [
        matchN(1, [
          {
            a!: _
          },
        ]),
      ])
    }
  }
}
--- yamlcycle.cue
{
  yamlNoCycle: {
    #c: {
      b?: string
      a?: 〈import;"encoding/yaml"〉.Validate(〈1;#c〉)
    }
    data: 〈0;#c〉
    data: {
      a: "{a: \"b: foo\"}"
    }
  }
  selfCycle: {
    t1: {
      c: matchN(1, [
        {
          d: 〈2;c〉
        },
      ])
      c: {
        d: {}
      }
    }
  }
  selfCycle: {
    t2: {
      c: matchN(1, [
        {
          d: 〈2;c〉
        },
      ])
      c: {}
    }
  }
  selfCycle: {
    yamlVal: {
      t1: {
        x: {
          y: 〈import;"encoding/yaml"〉.Validate(〈1;x〉)
        }
        x: {
          y: "{}"
        }
      }
    }
  }
  selfCycle: {
    yamlVal: {
      t2: {
        x: {
          y: 〈import;"encoding/yaml"〉.Validate(〈1;x〉)
        }
        x: {
          y: "{}"
        }
        x: {
          y: 〈import;"encoding/yaml"〉.Validate(〈1;x〉)
        }
        x: {
          y: "{}"
        }
      }
    }
  }
  selfCycle: {
    yamlFun: {
      t1: {
        x: {
          y?: 〈import;"encoding/yaml"〉.Validate("{}", 〈1;x〉)
        }
      }
    }
  }
  selfCycle: {
    yamlFun: {
      t2: {
        z: (〈0;x〉 & _|_(no sharing))
        z: {
          y: "{}"
        }
        x: {
          y: 〈import;"encoding/yaml"〉.Validate("{}", 〈1;x〉)
        }
      }
    }
  }
  selfCycle: {
    yamlValidatePartial: {
      x: {
        y: 〈import;"encoding/yaml"〉.ValidatePartial(〈1;x〉)
      }
      x: {
        y: "{}"
      }
    }
  }
}
