-- in.cue --
given: {
	INC: USD: 2.0
	USD: GBP: 3.0
}
hydrated: {
	for k, v in given {
		for k1, r in v {
			"\(k)": "\(k)":   1.0
			"\(k1)": "\(k1)": 1.0
			"\(k)": "\(k1)":  r
			"\(k1)": "\(k)":  number
		}
	}
}

foo: {
	a: 10
	if a < 20 {
		if a < 50 {
			b: 20
		}
	}
}

indirectlyNested: {
	a: true // must be declared outside of the nested comprehensions for test.
	if true {
		b: {
			if a {
				a
			}
		}
	}
}

directlyNestedEmpty: {
	a: true
	if true {
		if a {
		}
	}
}

directlyDoublyNestedEmpty: {
	a: true 
	if true {
		if a {
		}
	}
}

indirectlyDoublyNestedEmpty: {
	a: true
	b: {
		if true {
			if a {
				if a {
					a
				}
			}
			if a {
				a
			}
		}
	}
}

indirectlyDoublyNested: {
	a: true
	if true {
		if a {
			if a {
				b: 1
			}
		}
		if a {
			c: 1
		}
	}
}

// This case used to trigger an over-aggressive deduplication.
issue1974: {
	X: {
		foo: {
			bar: ""
			baz: ""
		}
	}
	out: {
		for k, v in X for vk, vv in v {
			"\(k)": "\(vk)": vv
		}
	}
}
-- pending.cue --
// Trigger notification while an arc is still pending.
T: int
for C in Y {
	let X = C.M
	T:  X.V
}
Y: x: {
	M: V: 1
	for _ in M {
		if true { M: {} }
	}
}
-- out/eval/stats --
Leaks:  2
Freed:  50
Reused: 45
Allocs: 7
Retain: 12

Unifications: 52
Conjuncts:    91
Disjuncts:    57
-- out/eval --
(struct){
  given: (struct){
    INC: (struct){
      USD: (float){ 2.0 }
    }
    USD: (struct){
      GBP: (float){ 3.0 }
    }
  }
  hydrated: (struct){
    INC: (struct){
      INC: (float){ 1.0 }
      USD: (float){ 2.0 }
    }
    USD: (struct){
      USD: (float){ 1.0 }
      INC: (number){ number }
      GBP: (float){ 3.0 }
    }
    GBP: (struct){
      GBP: (float){ 1.0 }
      USD: (number){ number }
    }
  }
  foo: (struct){
    a: (int){ 10 }
    b: (int){ 20 }
  }
  indirectlyNested: (struct){
    a: (bool){ true }
    b: (bool){ true }
  }
  directlyNestedEmpty: (struct){
    a: (bool){ true }
  }
  directlyDoublyNestedEmpty: (struct){
    a: (bool){ true }
  }
  indirectlyDoublyNestedEmpty: (struct){
    a: (bool){ true }
    b: (bool){ true }
  }
  indirectlyDoublyNested: (struct){
    a: (bool){ true }
    c: (int){ 1 }
    b: (int){ 1 }
  }
  issue1974: (struct){
    X: (struct){
      foo: (struct){
        bar: (string){ "" }
        baz: (string){ "" }
      }
    }
    out: (struct){
      foo: (struct){
        bar: (string){ "" }
        baz: (string){ "" }
      }
    }
  }
  T: (int){ 1 }
  let X#1multi = 〈1;C〉.M
  Y: (struct){
    x: (struct){
      M: (struct){
        V: (int){ 1 }
      }
    }
  }
}
-- out/compile --
--- in.cue
{
  given: {
    INC: {
      USD: 2.0
    }
    USD: {
      GBP: 3.0
    }
  }
  hydrated: {
    for k, v in 〈1;given〉 {
      for k1, r in 〈1;v〉 {
        "\(〈3;k〉)": {
          "\(〈4;k〉)": 1.0
        }
        "\(〈1;k1〉)": {
          "\(〈2;k1〉)": 1.0
        }
        "\(〈3;k〉)": {
          "\(〈2;k1〉)": 〈2;r〉
        }
        "\(〈1;k1〉)": {
          "\(〈4;k〉)": number
        }
      }
    }
  }
  foo: {
    a: 10
    if (〈0;a〉 < 20) {
      if (〈1;a〉 < 50) {
        b: 20
      }
    }
  }
  indirectlyNested: {
    a: true
    if true {
      b: {
        if 〈2;a〉 {
          〈3;a〉
        }
      }
    }
  }
  directlyNestedEmpty: {
    a: true
    if true {
      if 〈1;a〉 {}
    }
  }
  directlyDoublyNestedEmpty: {
    a: true
    if true {
      if 〈1;a〉 {}
    }
  }
  indirectlyDoublyNestedEmpty: {
    a: true
    b: {
      if true {
        if 〈2;a〉 {
          if 〈3;a〉 {
            〈4;a〉
          }
        }
        if 〈2;a〉 {
          〈3;a〉
        }
      }
    }
  }
  indirectlyDoublyNested: {
    a: true
    if true {
      if 〈1;a〉 {
        if 〈2;a〉 {
          b: 1
        }
      }
      if 〈1;a〉 {
        c: 1
      }
    }
  }
  issue1974: {
    X: {
      foo: {
        bar: ""
        baz: ""
      }
    }
    out: {
      for k, v in 〈1;X〉 for vk, vv in 〈0;v〉 {
        "\(〈2;k〉)": {
          "\(〈2;vk〉)": 〈2;vv〉
        }
      }
    }
  }
}
--- pending.cue
{
  T: int
  for _, C in 〈0;Y〉 {
    let X#1multi = 〈1;C〉.M
    T: 〈0;let X#1〉.V
  }
  Y: {
    x: {
      M: {
        V: 1
      }
      for _, _ in 〈0;M〉 {
        if true {
          M: {}
        }
      }
    }
  }
}
