-- in.cue --
// Given the existence of this field, embedDefault is a struct. This
// means that embedding this conjunction into `embedDefault` itself should
// make it resolve to `{a: 2}`.

default: {
	y: *1 | {a: 2}
	y
}

unambiguous: {
	y: 1 | {a: 2}
	y
}

forDefault: {
	y: *1 | {a: 2}
	for x in [1] {y}
}

// Carry over default to first disjunct.
openDefault: {
	#y: *1 | {a: 2}
	#y
}

openAmbiguous: {
	#y: 1 | {a: 2}
	#y
}

forceStruct: {
	#y: 1 | {a: 2}
	#y
	{}
}

defaultsMulti: {
	a: {
		#def: {
			*{} | {a: string} | {b: string}
			*{} | {c: string} | {d: string}
		}

		a: #def & {a: "foo"}
	}

	b: {
		#def: {
			*{} | {a: string} | {b: string}
			*{} | {c: string} | {d: string}
			*{} | {d: string} | {e: string}
		}

		a: #def & {a: "foo", e: "bar"}
	}
}

nested: {
	a: 1 | 2 | *(
		(3 | 4 | *( 5 | 6 | *7)) & ( 3 | 4 | ( *7 | 8 )))
}
-- issue3415.cue --
issue3415: full: {
	A: #A & {
		i: {
		  _a + _b
		  _a: 1
		  _b: 10
		}
	}
	#A: {
		i: *0 | number
	}
}
issue3415: reduced: {
	a: {
		1 + #b
		#b: 10
	}
	a: *0 | number
}
-- out/evalalpha/stats --
Leaks:  221
Freed:  0
Reused: 0
Allocs: 221
Retain: 0

Unifications: 73
Conjuncts:    219
Disjuncts:    106
-- diff/-out/evalalpha/stats<==>+out/eval/stats --
diff old new
--- old
+++ new
@@ -1,9 +1,9 @@
-Leaks:  19
-Freed:  430
-Reused: 413
-Allocs: 36
-Retain: 5
+Leaks:  221
+Freed:  0
+Reused: 0
+Allocs: 221
+Retain: 0
 
-Unifications: 268
-Conjuncts:    502
-Disjuncts:    438
+Unifications: 73
+Conjuncts:    219
+Disjuncts:    106
-- out/eval/stats --
Leaks:  19
Freed:  430
Reused: 413
Allocs: 36
Retain: 5

Unifications: 268
Conjuncts:    502
Disjuncts:    438
-- out/eval --
(struct){
  default: (struct){
    y: ((int|struct)){ |(*(int){ 1 }, (struct){
        a: (int){ 2 }
      }) }
    a: (int){ 2 }
  }
  unambiguous: (struct){
    y: ((int|struct)){ |((int){ 1 }, (struct){
        a: (int){ 2 }
      }) }
    a: (int){ 2 }
  }
  forDefault: (struct){
    y: ((int|struct)){ |(*(int){ 1 }, (struct){
        a: (int){ 2 }
      }) }
    a: (int){ 2 }
  }
  openDefault: ((int|struct)){ |(*(int){
      1
      #y: ((int|struct)){ |(*(int){ 1 }, (#struct){
          a: (int){ 2 }
        }) }
    }, (#struct){
      #y: ((int|struct)){ |(*(int){ 1 }, (#struct){
          a: (int){ 2 }
        }) }
      a: (int){ 2 }
    }) }
  openAmbiguous: ((int|struct)){ |((int){
      1
      #y: ((int|struct)){ |((int){ 1 }, (#struct){
          a: (int){ 2 }
        }) }
    }, (#struct){
      #y: ((int|struct)){ |((int){ 1 }, (#struct){
          a: (int){ 2 }
        }) }
      a: (int){ 2 }
    }) }
  forceStruct: (#struct){
    #y: ((int|struct)){ |((int){ 1 }, (#struct){
        a: (int){ 2 }
      }) }
    a: (int){ 2 }
  }
  defaultsMulti: (struct){
    a: (struct){
      #def: (#struct){ |(*(#struct){
        }, (#struct){
          c: (string){ string }
        }, (#struct){
          d: (string){ string }
        }, (#struct){
          a: (string){ string }
        }, (#struct){
          a: (string){ string }
          c: (string){ string }
        }, (#struct){
          a: (string){ string }
          d: (string){ string }
        }, (#struct){
          b: (string){ string }
        }, (#struct){
          b: (string){ string }
          c: (string){ string }
        }, (#struct){
          b: (string){ string }
          d: (string){ string }
        }) }
      a: (#struct){ |(*(#struct){
          a: (string){ "foo" }
        }, (#struct){
          a: (string){ "foo" }
          c: (string){ string }
        }, (#struct){
          a: (string){ "foo" }
          d: (string){ string }
        }) }
    }
    b: (struct){
      #def: (#struct){ |(*(#struct){
        }, (#struct){
          d: (string){ string }
        }, (#struct){
          e: (string){ string }
        }, (#struct){
          c: (string){ string }
        }, (#struct){
          c: (string){ string }
          d: (string){ string }
        }, (#struct){
          c: (string){ string }
          e: (string){ string }
        }, (#struct){
          d: (string){ string }
          e: (string){ string }
        }, (#struct){
          a: (string){ string }
        }, (#struct){
          a: (string){ string }
          d: (string){ string }
        }, (#struct){
          a: (string){ string }
          e: (string){ string }
        }, (#struct){
          a: (string){ string }
          c: (string){ string }
        }, (#struct){
          a: (string){ string }
          c: (string){ string }
          d: (string){ string }
        }, (#struct){
          a: (string){ string }
          c: (string){ string }
          e: (string){ string }
        }, (#struct){
          a: (string){ string }
          d: (string){ string }
          e: (string){ string }
        }, (#struct){
          b: (string){ string }
        }, (#struct){
          b: (string){ string }
          d: (string){ string }
        }, (#struct){
          b: (string){ string }
          e: (string){ string }
        }, (#struct){
          b: (string){ string }
          c: (string){ string }
        }, (#struct){
          b: (string){ string }
          c: (string){ string }
          d: (string){ string }
        }, (#struct){
          b: (string){ string }
          c: (string){ string }
          e: (string){ string }
        }, (#struct){
          b: (string){ string }
          d: (string){ string }
          e: (string){ string }
        }) }
      a: (#struct){ |(*(#struct){
          a: (string){ "foo" }
          e: (string){ "bar" }
        }, (#struct){
          a: (string){ "foo" }
          e: (string){ "bar" }
          c: (string){ string }
        }, (#struct){
          a: (string){ "foo" }
          e: (string){ "bar" }
          d: (string){ string }
        }) }
    }
  }
  nested: (struct){
    a: (int){ |(*(int){ 7 }, (int){ 2 }, (int){ 3 }, (int){ 4 }, (int){ 1 }) }
  }
  issue3415: (struct){
    full: (struct){
      A: (#struct){
        i: (int){
          11
          _a: (int){ 1 }
          _b: (int){ 10 }
        }
      }
      #A: (#struct){
        i: (number){ |(*(int){ 0 }, (number){ number }) }
      }
    }
    reduced: (struct){
      a: (int){
        11
        #b: (int){ 10 }
      }
    }
  }
}
-- out/compile --
--- in.cue
{
  default: {
    y: (*1|{
      a: 2
    })
    〈0;y〉
  }
  unambiguous: {
    y: (1|{
      a: 2
    })
    〈0;y〉
  }
  forDefault: {
    y: (*1|{
      a: 2
    })
    for _, x in [
      1,
    ] {
      〈2;y〉
    }
  }
  openDefault: {
    #y: (*1|{
      a: 2
    })
    〈0;#y〉
  }
  openAmbiguous: {
    #y: (1|{
      a: 2
    })
    〈0;#y〉
  }
  forceStruct: {
    #y: (1|{
      a: 2
    })
    〈0;#y〉
    {}
  }
  defaultsMulti: {
    a: {
      #def: {
        (*{}|{
          a: string
        }|{
          b: string
        })
        (*{}|{
          c: string
        }|{
          d: string
        })
      }
      a: (〈0;#def〉 & {
        a: "foo"
      })
    }
    b: {
      #def: {
        (*{}|{
          a: string
        }|{
          b: string
        })
        (*{}|{
          c: string
        }|{
          d: string
        })
        (*{}|{
          d: string
        }|{
          e: string
        })
      }
      a: (〈0;#def〉 & {
        a: "foo"
        e: "bar"
      })
    }
  }
  nested: {
    a: (1|2|*((3|4|*(5|6|*7)) & (3|4|(*7|8))))
  }
}
--- issue3415.cue
{
  issue3415: {
    full: {
      A: (〈0;#A〉 & {
        i: {
          (〈0;_a〉 + 〈0;_b〉)
          _a: 1
          _b: 10
        }
      })
      #A: {
        i: (*0|number)
      }
    }
  }
  issue3415: {
    reduced: {
      a: {
        (1 + 〈0;#b〉)
        #b: 10
      }
      a: (*0|number)
    }
  }
}
