-- in.cue --
a: {b: 2, c: int}

wrongConcreteType: {
	if a.b {
		2
	}
}

wrongType: {
	if a.c {
		2
	}
}

incomplete: {
	if a.d {
		2
	}
}

incomplete: {
	list: [1, 2, 3]
	for x in list if a.d {
		x
	}
}

// Issue #809
useDefault: {
	a: {
		x: *"foo" | string
		if x != _|_ {
			y: x
		}
	}

	issue809: {
		#A: {
			a: string
			b: *a | string
		}

		s: [Name=string]: #A & {a: Name}
		s: bar:           _

		foo: [
			for _, a in s if a.b != _|_ {a},
		]
	}
}

issue1972: {
	err1: {
		#patchs: []
		#patchs

		#someCondition: _
		if #someCondition {
		}
	}
	err1: {
		someCondition: _
		patchs: [...{}]
		patchs
		if someCondition {
			patchs: _
		}
	}
}
-- out/compile --
--- in.cue
{
  a: {
    b: 2
    c: int
  }
  wrongConcreteType: {
    if 〈1;a〉.b {
      2
    }
  }
  wrongType: {
    if 〈1;a〉.c {
      2
    }
  }
  incomplete: {
    if 〈1;a〉.d {
      2
    }
  }
  incomplete: {
    list: [
      1,
      2,
      3,
    ]
    for _, x in 〈0;list〉 if 〈2;a〉.d {
      〈1;x〉
    }
  }
  useDefault: {
    a: {
      x: (*"foo"|string)
      if (〈0;x〉 != _|_(explicit error (_|_ literal) in source)) {
        y: 〈1;x〉
      }
    }
    issue809: {
      #A: {
        a: string
        b: (*〈0;a〉|string)
      }
      s: {
        [string]: (〈1;#A〉 & {
          a: 〈1;-〉
        })
      }
      s: {
        bar: _
      }
      foo: [
        for _, a in 〈1;s〉 if (〈0;a〉.b != _|_(explicit error (_|_ literal) in source)) {
          〈1;a〉
        },
      ]
    }
  }
  issue1972: {
    err1: {
      #patchs: []
      〈0;#patchs〉
      #someCondition: _
      if 〈0;#someCondition〉 {}
    }
    err1: {
      someCondition: _
      patchs: [
        ...{},
      ]
      〈0;patchs〉
      if 〈0;someCondition〉 {
        patchs: _
      }
    }
  }
}
-- out/eval/stats --
Leaks:  0
Freed:  43
Reused: 35
Allocs: 8
Retain: 14

Unifications: 33
Conjuncts:    66
Disjuncts:    57
-- out/evalalpha --
Errors:
issue1972.err1: conflicting values [...{}] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
    ./in.cue:61:8
    ./in.cue:63:11
wrongConcreteType: cannot use 2 (type int) as type bool:
    ./in.cue:4:2
    ./in.cue:1:8
wrongType: cannot use int (type int) as type bool:
    ./in.cue:10:2
    ./in.cue:1:14

Result:
(_|_){
  // [eval]
  a: (struct){
    b: (int){ 2 }
    c: (int){ int }
  }
  wrongConcreteType: (_|_){
    // [eval] wrongConcreteType: cannot use 2 (type int) as type bool:
    //     ./in.cue:4:2
    //     ./in.cue:1:8
  }
  wrongType: (_|_){
    // [eval] wrongType: cannot use int (type int) as type bool:
    //     ./in.cue:10:2
    //     ./in.cue:1:14
  }
  incomplete: (_|_){
    // [incomplete] incomplete: undefined field: d:
    //     ./in.cue:16:7
    // incomplete: undefined field: d:
    //     ./in.cue:23:21
    list: (#list){
      0: (int){ 1 }
      1: (int){ 2 }
      2: (int){ 3 }
    }
  }
  useDefault: (struct){
    a: (struct){
      x: (string){ |(*(string){ "foo" }, (string){ string }) }
      y: (string){ |(*(string){ "foo" }, (string){ string }) }
    }
    issue809: (struct){
      #A: (#struct){
        a: (string){ string }
        b: (string){ string }
      }
      s: (struct){
        bar: (#struct){
          a: (string){ "bar" }
          b: (string){ |(*(string){ "bar" }, (string){ string }) }
        }
      }
      foo: (#list){
        0: (#struct){
          a: (string){ "bar" }
          b: (string){ |(*(string){ "bar" }, (string){ string }) }
        }
      }
    }
  }
  issue1972: (_|_){
    // [eval]
    err1: (_|_){
      // [eval] issue1972.err1: conflicting values [...{}] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
      //     ./in.cue:61:8
      //     ./in.cue:63:11
      #patchs: (_|_){// []
      }
      #someCondition: (_){ _ }
      someCondition: (_){ _ }
      patchs: (_|_){// [
        //   ...{},
        // ][e] & if 〈0;someCondition〉 _
      }
    }
  }
}
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -1,7 +1,7 @@
 Errors:
-issue1972.err1: conflicting values [] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
-    ./in.cue:54:12
+issue1972.err1: conflicting values [...{}] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
     ./in.cue:61:8
+    ./in.cue:63:11
 wrongConcreteType: cannot use 2 (type int) as type bool:
     ./in.cue:4:2
     ./in.cue:1:8
@@ -8,8 +8,6 @@
 wrongType: cannot use int (type int) as type bool:
     ./in.cue:10:2
     ./in.cue:1:14
-issue1972.err1: invalid list index someCondition (type string):
-    ./in.cue:65:6
 
 Result:
 (_|_){
@@ -66,17 +64,17 @@
   issue1972: (_|_){
     // [eval]
     err1: (_|_){
-      // [eval] issue1972.err1: conflicting values [] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
-      //     ./in.cue:54:12
+      // [eval] issue1972.err1: conflicting values [...{}] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
       //     ./in.cue:61:8
-      // issue1972.err1: invalid list index someCondition (type string):
-      //     ./in.cue:65:6
-      #patchs: (#list){
-      }
-      someCondition: (_){ _ }
-      patchs: (list){
+      //     ./in.cue:63:11
+      #patchs: (_|_){// []
       }
       #someCondition: (_){ _ }
+      someCondition: (_){ _ }
+      patchs: (_|_){// [
+        //   ...{},
+        // ][e] & if 〈0;someCondition〉 _
+      }
     }
   }
 }
-- diff/todo/p2 --
issue1972: "field not allowed" are somewhat correct (it is also a list), but
are already covered by the other error message and should be elided.
This may lead to a large number of errors otherwise.
-- out/eval --
Errors:
issue1972.err1: conflicting values [] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
    ./in.cue:54:12
    ./in.cue:61:8
wrongConcreteType: cannot use 2 (type int) as type bool:
    ./in.cue:4:2
    ./in.cue:1:8
wrongType: cannot use int (type int) as type bool:
    ./in.cue:10:2
    ./in.cue:1:14
issue1972.err1: invalid list index someCondition (type string):
    ./in.cue:65:6

Result:
(_|_){
  // [eval]
  a: (struct){
    b: (int){ 2 }
    c: (int){ int }
  }
  wrongConcreteType: (_|_){
    // [eval] wrongConcreteType: cannot use 2 (type int) as type bool:
    //     ./in.cue:4:2
    //     ./in.cue:1:8
  }
  wrongType: (_|_){
    // [eval] wrongType: cannot use int (type int) as type bool:
    //     ./in.cue:10:2
    //     ./in.cue:1:14
  }
  incomplete: (_|_){
    // [incomplete] incomplete: undefined field: d:
    //     ./in.cue:16:7
    // incomplete: undefined field: d:
    //     ./in.cue:23:21
    list: (#list){
      0: (int){ 1 }
      1: (int){ 2 }
      2: (int){ 3 }
    }
  }
  useDefault: (struct){
    a: (struct){
      x: (string){ |(*(string){ "foo" }, (string){ string }) }
      y: (string){ |(*(string){ "foo" }, (string){ string }) }
    }
    issue809: (struct){
      #A: (#struct){
        a: (string){ string }
        b: (string){ string }
      }
      s: (struct){
        bar: (#struct){
          a: (string){ "bar" }
          b: (string){ |(*(string){ "bar" }, (string){ string }) }
        }
      }
      foo: (#list){
        0: (#struct){
          a: (string){ "bar" }
          b: (string){ |(*(string){ "bar" }, (string){ string }) }
        }
      }
    }
  }
  issue1972: (_|_){
    // [eval]
    err1: (_|_){
      // [eval] issue1972.err1: conflicting values [] and {someCondition:_,patchs:[...{}],patchs,if someCondition {patchs:_}} (mismatched types list and struct):
      //     ./in.cue:54:12
      //     ./in.cue:61:8
      // issue1972.err1: invalid list index someCondition (type string):
      //     ./in.cue:65:6
      #patchs: (#list){
      }
      someCondition: (_){ _ }
      patchs: (list){
      }
      #someCondition: (_){ _ }
    }
  }
}
