// This files tests that values are properly "frozen" in case of mutual
// references. Non-structural cyclic references are okay, as long a property
// that is dependended upon in the cycle is not changed after the fact,
// that is, a value may not become more specific after it is used.
-- in.cue --
freezing: t1: ok: {
	#a: x: "a"
	len(#a) // 1
}
-- comprehension.cue --
// This should be an incomplete error, as z is inserted in x, over which the
// comprehension loops. Adding a field z to x would fix this.
// This test would fail in the old evaluator, depending on ordering.
comprehension: t1: _
comprehension: t1: ok: {

	x: y: {}
	// order of comprehensions matter in old evaluator.
	for _ in x {
		if true {x: z: a: {}}
	}
	if true {
		if true {x: z: a: {}}
	}
}

comprehension: t2: err: {
	a: {
		x: 1
		for k, v in a {
			(k + "q"): v // This increases the set of fields in a.
		}
	}
}

comprehension: t3: err: {
	// mutual dependencies not okay in this case, as the set of fields grows.
	a: x: 1
	b: y: 1
	a: {
		for k, v in b {
			(k + "q"): v
		}
	}
	b: {
		for k, v in a {
			(k): v
		}
	}
}

comprehension: t4: ok: {
	// It is okay to make x more specific as long as no fields are added.
	x: y: {}
	for _ in x {
		if true {x: y: a: {}}
	}
}

comprehension: moreSpecific: ok: {
	a: {
		x: int
		for k, v in a {
			(k): 1
		}
	}
}

comprehension: moreSpecific: err: {
	a: {
		x: {y: 1}
		// len(v) should free the size of x.
		for k, v in a if len(v) > 0 {
			(k): {z: 1}
		}
	}
}
-- issue3178.cue --
// evalv3 regression: exporting via the Go API produced an error that evalv2
// did not, for a case involving chained comprehensions.
// https://cuelang.org/issue/3178
issue3178: {
	// This should pass. Reasoning:
	// - second comprehension runs
	// - in order to satisfy, first comprehension must run
	// - first comprehension runs and completes
	input: ["Value"]
	output: {...}
	for name in input {
		output: "\(name)": true
	}
	for name, v in output {}
}
-- out/compile --
--- comprehension.cue
{
  comprehension: {
    t1: _
  }
  comprehension: {
    t1: {
      ok: {
        x: {
          y: {}
        }
        for _, _ in 〈0;x〉 {
          if true {
            x: {
              z: {
                a: {}
              }
            }
          }
        }
        if true {
          if true {
            x: {
              z: {
                a: {}
              }
            }
          }
        }
      }
    }
  }
  comprehension: {
    t2: {
      err: {
        a: {
          x: 1
          for k, v in 〈1;a〉 {
            (〈1;k〉 + "q"): 〈1;v〉
          }
        }
      }
    }
  }
  comprehension: {
    t3: {
      err: {
        a: {
          x: 1
        }
        b: {
          y: 1
        }
        a: {
          for k, v in 〈1;b〉 {
            (〈1;k〉 + "q"): 〈1;v〉
          }
        }
        b: {
          for k, v in 〈1;a〉 {
            〈1;k〉: 〈1;v〉
          }
        }
      }
    }
  }
  comprehension: {
    t4: {
      ok: {
        x: {
          y: {}
        }
        for _, _ in 〈0;x〉 {
          if true {
            x: {
              y: {
                a: {}
              }
            }
          }
        }
      }
    }
  }
  comprehension: {
    moreSpecific: {
      ok: {
        a: {
          x: int
          for k, v in 〈1;a〉 {
            〈1;k〉: 1
          }
        }
      }
    }
  }
  comprehension: {
    moreSpecific: {
      err: {
        a: {
          x: {
            y: 1
          }
          for k, v in 〈1;a〉 if (len(〈0;v〉) > 0) {
            〈1;k〉: {
              z: 1
            }
          }
        }
      }
    }
  }
}
--- in.cue
{
  freezing: {
    t1: {
      ok: {
        #a: {
          x: "a"
        }
        len(〈0;#a〉)
      }
    }
  }
}
--- issue3178.cue
{
  issue3178: {
    input: [
      "Value",
    ]
    output: {
      ...
    }
    for _, name in 〈0;input〉 {
      output: {
        "\(〈2;name〉)": true
      }
    }
    for name, v in 〈0;output〉 {}
  }
}
