-- in.cue --
import "strings"

a: {x: 10, y: 100, z: 50}
b: {
	for k, v in a if v <= 50 {
		"\(k)": v
	}
	x: int
	if x > 3 {
		k: 20
	}
	k: int
	if k > 0 {
		l: 40
	}
}

c: {
	for k, v in a let y = v + 10 if y > 50 {
		"\(k)": y
	}
}

A: X: run: "dfoo"

if true {
	A: X: {
		run:   string
		files: "\(strings.Join([ run], "\n"))"
	}
}

matchOrder: {
  a1: {
    out: [string]: Val: 1
    out: in.a

    in: a: {
      if true {
        b: {}
      }
    }
  }
  a2: {
    out: [string]: Val: 1

    in: a: {
      if true {
        b: {}
      }
    }

    out: in.a
  }
  a3: {

    in: a: {
      if true {
        b: {}
      }
    }

    out: [string]: Val: 1
    out: in.a
  }
  a4: {
    out: in.a
    out: [string]: Val: 1

    in: a: {
      if true {
        b: {}
      }
    }
  }
  a5: {
    out: in.a

    in: a: {
      if true {
        b: {}
      }
    }

    out: [string]: Val: 1
  }
  a6: {
    in: a: {
      if true {
        b: {}
      }
    }

    out: in.a
    out: [string]: Val: 1
  }
}
-- issue3691.cue --
// Ensure that parent nodes are properly processed, even when a pending arc
// is evaluated early.
issue3691: original: {
	X: [string]: string
	a: [string]: X
	a: {
		if true {
			b: c: 1
		}
	}
}
// Structural cycles follow a different code path.
issue3691: structuralCycle: {
	X: [string]: string
	a: [string]: X
	a: {
		if true {
			b: c: a
		}
	}
}
-- out/eval/stats --
Leaks:  9
Freed:  72
Reused: 66
Allocs: 15
Retain: 19

Unifications: 81
Conjuncts:    121
Disjuncts:    94
-- out/evalalpha --
Errors:
issue3691.original.a.b.c: conflicting values string and 1 (mismatched types string and int):
    ./issue3691.cue:4:15
    ./issue3691.cue:8:10
issue3691.structuralCycle.a.b.c: conflicting values string and {[string]:X} (mismatched types string and struct):
    ./issue3691.cue:14:15
    ./issue3691.cue:15:5

Result:
(_|_){
  // [eval]
  a: (struct){
    x: (int){ 10 }
    y: (int){ 100 }
    z: (int){ 50 }
  }
  b: (struct){
    x: (int){ 10 }
    k: (int){ 20 }
    l: (int){ 40 }
    z: (int){ 50 }
  }
  c: (struct){
    y: (int){ 110 }
    z: (int){ 60 }
  }
  A: (struct){
    X: (struct){
      run: (string){ "dfoo" }
      files: (string){ "dfoo" }
    }
  }
  matchOrder: (struct){
    a1: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a2: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a3: (struct){
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
    }
    a4: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a5: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a6: (struct){
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
    }
  }
  issue3691: (_|_){
    // [eval]
    original: (_|_){
      // [eval]
      X: (struct){
      }
      a: (_|_){
        // [eval]
        b: (_|_){
          // [eval]
          c: (_|_){
            // [eval] issue3691.original.a.b.c: conflicting values string and 1 (mismatched types string and int):
            //     ./issue3691.cue:4:15
            //     ./issue3691.cue:8:10
          }
        }
      }
    }
    structuralCycle: (_|_){
      // [eval]
      X: (struct){
      }
      a: (_|_){
        // [eval]
        b: (_|_){
          // [eval]
          c: (_|_){
            // [eval] issue3691.structuralCycle.a.b.c: conflicting values string and {[string]:X} (mismatched types string and struct):
            //     ./issue3691.cue:14:15
            //     ./issue3691.cue:15:5
            b*: (_|_){// [e]if true {
              //   c: 〈3;a〉
              // }[e] & 〈1;X〉
            }
          }
        }
      }
    }
  }
}
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -1,14 +1,10 @@
 Errors:
 issue3691.original.a.b.c: conflicting values string and 1 (mismatched types string and int):
     ./issue3691.cue:4:15
-    ./issue3691.cue:7:3
     ./issue3691.cue:8:10
 issue3691.structuralCycle.a.b.c: conflicting values string and {[string]:X} (mismatched types string and struct):
     ./issue3691.cue:14:15
     ./issue3691.cue:15:5
-    ./issue3691.cue:17:3
-    ./issue3691.cue:18:10
-issue3691.structuralCycle.a.b.c.b.c: structural cycle
 
 Result:
 (_|_){
@@ -127,7 +123,6 @@
           c: (_|_){
             // [eval] issue3691.original.a.b.c: conflicting values string and 1 (mismatched types string and int):
             //     ./issue3691.cue:4:15
-            //     ./issue3691.cue:7:3
             //     ./issue3691.cue:8:10
           }
         }
@@ -145,13 +140,9 @@
             // [eval] issue3691.structuralCycle.a.b.c: conflicting values string and {[string]:X} (mismatched types string and struct):
             //     ./issue3691.cue:14:15
             //     ./issue3691.cue:15:5
-            //     ./issue3691.cue:17:3
-            //     ./issue3691.cue:18:10
-            b: (_|_){
-              // [structural cycle]
-              c: (_|_){
-                // [structural cycle] issue3691.structuralCycle.a.b.c.b.c: structural cycle
-              }
+            b*: (_|_){// [e]if true {
+              //   c: 〈3;a〉
+              // }[e] & 〈1;X〉
             }
           }
         }
-- diff/todo/p2 --
Missing error positions.
-- out/eval --
Errors:
issue3691.original.a.b.c: conflicting values string and 1 (mismatched types string and int):
    ./issue3691.cue:4:15
    ./issue3691.cue:7:3
    ./issue3691.cue:8:10
issue3691.structuralCycle.a.b.c: conflicting values string and {[string]:X} (mismatched types string and struct):
    ./issue3691.cue:14:15
    ./issue3691.cue:15:5
    ./issue3691.cue:17:3
    ./issue3691.cue:18:10
issue3691.structuralCycle.a.b.c.b.c: structural cycle

Result:
(_|_){
  // [eval]
  a: (struct){
    x: (int){ 10 }
    y: (int){ 100 }
    z: (int){ 50 }
  }
  b: (struct){
    x: (int){ 10 }
    k: (int){ 20 }
    l: (int){ 40 }
    z: (int){ 50 }
  }
  c: (struct){
    y: (int){ 110 }
    z: (int){ 60 }
  }
  A: (struct){
    X: (struct){
      run: (string){ "dfoo" }
      files: (string){ "dfoo" }
    }
  }
  matchOrder: (struct){
    a1: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a2: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a3: (struct){
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
    }
    a4: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a5: (struct){
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
    }
    a6: (struct){
      in: (struct){
        a: (struct){
          b: (struct){
          }
        }
      }
      out: (struct){
        b: (struct){
          Val: (int){ 1 }
        }
      }
    }
  }
  issue3691: (_|_){
    // [eval]
    original: (_|_){
      // [eval]
      X: (struct){
      }
      a: (_|_){
        // [eval]
        b: (_|_){
          // [eval]
          c: (_|_){
            // [eval] issue3691.original.a.b.c: conflicting values string and 1 (mismatched types string and int):
            //     ./issue3691.cue:4:15
            //     ./issue3691.cue:7:3
            //     ./issue3691.cue:8:10
          }
        }
      }
    }
    structuralCycle: (_|_){
      // [eval]
      X: (struct){
      }
      a: (_|_){
        // [eval]
        b: (_|_){
          // [eval]
          c: (_|_){
            // [eval] issue3691.structuralCycle.a.b.c: conflicting values string and {[string]:X} (mismatched types string and struct):
            //     ./issue3691.cue:14:15
            //     ./issue3691.cue:15:5
            //     ./issue3691.cue:17:3
            //     ./issue3691.cue:18:10
            b: (_|_){
              // [structural cycle]
              c: (_|_){
                // [structural cycle] issue3691.structuralCycle.a.b.c.b.c: structural cycle
              }
            }
          }
        }
      }
    }
  }
}
-- out/compile --
--- in.cue
{
  a: {
    x: 10
    y: 100
    z: 50
  }
  b: {
    for k, v in 〈1;a〉 if (〈0;v〉 <= 50) {
      "\(〈1;k〉)": 〈1;v〉
    }
    x: int
    if (〈0;x〉 > 3) {
      k: 20
    }
    k: int
    if (〈0;k〉 > 0) {
      l: 40
    }
  }
  c: {
    for k, v in 〈1;a〉 let y = (〈0;v〉 + 10) if (〈0;y〉 > 50) {
      "\(〈2;k〉)": 〈1;y〉
    }
  }
  A: {
    X: {
      run: "dfoo"
    }
  }
  if true {
    A: {
      X: {
        run: string
        files: "\(〈import;strings〉.Join([
          〈1;run〉,
        ], "\n"))"
      }
    }
  }
  matchOrder: {
    a1: {
      out: {
        [string]: {
          Val: 1
        }
      }
      out: 〈0;in〉.a
      in: {
        a: {
          if true {
            b: {}
          }
        }
      }
    }
    a2: {
      out: {
        [string]: {
          Val: 1
        }
      }
      in: {
        a: {
          if true {
            b: {}
          }
        }
      }
      out: 〈0;in〉.a
    }
    a3: {
      in: {
        a: {
          if true {
            b: {}
          }
        }
      }
      out: {
        [string]: {
          Val: 1
        }
      }
      out: 〈0;in〉.a
    }
    a4: {
      out: 〈0;in〉.a
      out: {
        [string]: {
          Val: 1
        }
      }
      in: {
        a: {
          if true {
            b: {}
          }
        }
      }
    }
    a5: {
      out: 〈0;in〉.a
      in: {
        a: {
          if true {
            b: {}
          }
        }
      }
      out: {
        [string]: {
          Val: 1
        }
      }
    }
    a6: {
      in: {
        a: {
          if true {
            b: {}
          }
        }
      }
      out: 〈0;in〉.a
      out: {
        [string]: {
          Val: 1
        }
      }
    }
  }
}
--- issue3691.cue
{
  issue3691: {
    original: {
      X: {
        [string]: string
      }
      a: {
        [string]: 〈1;X〉
      }
      a: {
        if true {
          b: {
            c: 1
          }
        }
      }
    }
  }
  issue3691: {
    structuralCycle: {
      X: {
        [string]: string
      }
      a: {
        [string]: 〈1;X〉
      }
      a: {
        if true {
          b: {
            c: 〈3;a〉
          }
        }
      }
    }
  }
}
