-- in.cue --
// All these should pass. These look like recursive inlined calls, but they are
// not.

ok1: {
	f: {
		in:  number
		out: in
	}
	k00: 0
	k10: (f & {in: k00}).out
	k20: (f & {in: k10}).out
	k30: (f & {in: k20}).out
}

ok2: {
	f: {
		in:  number
		out: in
	}
	k00: 0
	k10: {(f & {in: k00}).out}
	k20: {(f & {in: k10}).out}
	k30: {(f & {in: k20}).out}
}

ok3: {
	f: {
		in:  number
		out: in
	}
	k00: 0
	k10: {close((f & {in: k00})).out}
	k20: {close((f & {in: k10})).out}
	k30: {close((f & {in: k20})).out}
}

ok4: {
	f: {
		in:  number
		out: in
	}
	k00: 0
	k10: {out: {(f & {in: k00}).out}}.out
	k20: {out: {(f & {in: k10}).out}}.out
	k30: {out: {(f & {in: k20}).out}}.out
}

// Issue #1708
issue1708: {
	#add10: {
		in: number
		a10: { i: in, o: i + 10 }
		out: a10.o
	}
	k00: 0
	k10: (#add10 & {in: k00}).out
	k20: (#add10 & {in: k10}).out
	k30: (#add10 & {in: k20}).out
}
-- issue3182.cue --
issue3182: {
	first: t1: {
		x: { a: x }.a
	}
	first: t2: {
		x: { a: b: x }.a
	}
	second: {
		{ t: x }.t.y
		x: y: x: y: a: 1
	}
	third: {
		{
			p: {
			  x: p
			  y: 1
			}
		}.p.x.y
	}
}
-- select.cue --
// The value of #Step should be consistent between these test cases.
select: direct: {
	#Step: (#Job & {opt: _}).opt
	#Job: matchN(1, [#NormalJob])
}
select: indirect: {
	#Step: #Job.opt
	#Job: matchN(1, [#NormalJob]) & {opt: _}
}
#NormalJob: {
	req!: int
	opt?: run?: string
}
-- out/evalalpha/stats --
Leaks:  225
Freed:  0
Reused: 0
Allocs: 225
Retain: 0

Unifications: 141
Conjuncts:    375
Disjuncts:    0

CloseIDElems: 14
NumCloseIDs: 178
-- out/evalalpha --
Errors:
issue3182.first.t2.x.b: structural cycle

Result:
(_|_){
  // [structural cycle]
  ok1: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  ok2: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  ok3: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  ok4: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  issue1708: (struct){
    #add10: (#struct){
      in: (number){ number }
      a10: (#struct){
        i: (number){ number }
        o: (_|_){
          // [incomplete] issue1708.#add10.a10.o: non-concrete value number in operand to +:
          //     ./in.cue:52:20
          //     ./in.cue:51:7
        }
      }
      out: (_|_){
        // [incomplete] issue1708.#add10.a10.o: non-concrete value number in operand to +:
        //     ./in.cue:52:20
        //     ./in.cue:51:7
      }
    }
    k00: (int){ 0 }
    k10: (int){ 10 }
    k20: (int){ 20 }
    k30: (_|_){
      // [incomplete] a10.i: undefined field: out:
      //     ./in.cue:56:28
    }
  }
  issue3182: (_|_){
    // [structural cycle]
    first: (_|_){
      // [structural cycle]
      t1: (struct){
        x: (_){ _ }
      }
      t2: (_|_){
        // [structural cycle]
        x: (_|_){
          // [structural cycle]
          b: (_|_){
            // [structural cycle] issue3182.first.t2.x.b: structural cycle
          }
        }
      }
    }
    second: (struct){
      x: (struct){
        y: (struct){
          x: (struct){
            y: (struct){
              a: (int){ 1 }
            }
          }
          a: (int){ 1 }
        }
      }
      a: (int){ 1 }
    }
    third: (int){ 1 }
  }
  select: (struct){
    direct: (struct){
      #Step: (_){ _ }
      #Job: (_){ matchN(1, (#list){
          0: (_|_){// 〈3;#NormalJob〉
          }
        }) }
    }
    indirect: (struct){
      #Step: (_){ _ }
      #Job: (_|_){
        // [incomplete] select.indirect.#Job: invalid value {opt:_} (does not satisfy matchN): 0 matched, expected 1:
        //     ./select.cue:8:8
        //     ./select.cue:8:15
        // select.indirect.#Job.req: field is required but not present:
        //     ./select.cue:8:8
        //     ./select.cue:11:2
        opt: (_){ _ }
      }
    }
  }
  #NormalJob: (#struct){
    req!: (int){ int }
    opt?: (#struct){
      run?: (string){ string }
    }
  }
}
-- diff/-out/evalalpha/stats<==>+out/eval/stats --
diff old new
--- old
+++ new
@@ -1,9 +1,12 @@
-Leaks:  309
-Freed:  437
-Reused: 429
-Allocs: 317
-Retain: 1074
-
-Unifications: 746
-Conjuncts:    2813
-Disjuncts:    1485
+Leaks:  225
+Freed:  0
+Reused: 0
+Allocs: 225
+Retain: 0
+
+Unifications: 141
+Conjuncts:    375
+Disjuncts:    0
+
+CloseIDElems: 14
+NumCloseIDs: 178
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -53,20 +53,21 @@
           // [incomplete] issue1708.#add10.a10.o: non-concrete value number in operand to +:
           //     ./in.cue:52:20
           //     ./in.cue:51:7
-          //     ./in.cue:52:13
         }
       }
       out: (_|_){
-        // [incomplete] issue1708.#add10.out: non-concrete value number in operand to +:
+        // [incomplete] issue1708.#add10.a10.o: non-concrete value number in operand to +:
         //     ./in.cue:52:20
         //     ./in.cue:51:7
-        //     ./in.cue:52:13
       }
     }
     k00: (int){ 0 }
     k10: (int){ 10 }
     k20: (int){ 20 }
-    k30: (int){ 30 }
+    k30: (_|_){
+      // [incomplete] a10.i: undefined field: out:
+      //     ./in.cue:56:28
+    }
   }
   issue3182: (_|_){
     // [structural cycle]
@@ -116,7 +117,6 @@
         //     ./select.cue:8:15
         // select.indirect.#Job.req: field is required but not present:
         //     ./select.cue:8:8
-        //     ./select.cue:8:19
         //     ./select.cue:11:2
         opt: (_){ _ }
       }
-- diff/todo/p2 --
issue1708.k30: no longer evaluates. Not the worst, but would ideally be fixed.
-- diff/todo/p3 --
Error positions.
Incorrect path due to structure sharing.
-- out/eval/stats --
Leaks:  309
Freed:  437
Reused: 429
Allocs: 317
Retain: 1074

Unifications: 746
Conjuncts:    2813
Disjuncts:    1485
-- out/eval --
Errors:
issue3182.first.t2.x.b: structural cycle

Result:
(_|_){
  // [structural cycle]
  ok1: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  ok2: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  ok3: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  ok4: (struct){
    f: (struct){
      in: (number){ number }
      out: (number){ number }
    }
    k00: (int){ 0 }
    k10: (int){ 0 }
    k20: (int){ 0 }
    k30: (int){ 0 }
  }
  issue1708: (struct){
    #add10: (#struct){
      in: (number){ number }
      a10: (#struct){
        i: (number){ number }
        o: (_|_){
          // [incomplete] issue1708.#add10.a10.o: non-concrete value number in operand to +:
          //     ./in.cue:52:20
          //     ./in.cue:51:7
          //     ./in.cue:52:13
        }
      }
      out: (_|_){
        // [incomplete] issue1708.#add10.out: non-concrete value number in operand to +:
        //     ./in.cue:52:20
        //     ./in.cue:51:7
        //     ./in.cue:52:13
      }
    }
    k00: (int){ 0 }
    k10: (int){ 10 }
    k20: (int){ 20 }
    k30: (int){ 30 }
  }
  issue3182: (_|_){
    // [structural cycle]
    first: (_|_){
      // [structural cycle]
      t1: (struct){
        x: (_){ _ }
      }
      t2: (_|_){
        // [structural cycle]
        x: (_|_){
          // [structural cycle]
          b: (_|_){
            // [structural cycle] issue3182.first.t2.x.b: structural cycle
          }
        }
      }
    }
    second: (struct){
      x: (struct){
        y: (struct){
          x: (struct){
            y: (struct){
              a: (int){ 1 }
            }
          }
          a: (int){ 1 }
        }
      }
      a: (int){ 1 }
    }
    third: (int){ 1 }
  }
  select: (struct){
    direct: (struct){
      #Step: (_){ _ }
      #Job: (_){ matchN(1, (#list){
          0: (_|_){// 〈3;#NormalJob〉
          }
        }) }
    }
    indirect: (struct){
      #Step: (_){ _ }
      #Job: (_|_){
        // [incomplete] select.indirect.#Job: invalid value {opt:_} (does not satisfy matchN): 0 matched, expected 1:
        //     ./select.cue:8:8
        //     ./select.cue:8:15
        // select.indirect.#Job.req: field is required but not present:
        //     ./select.cue:8:8
        //     ./select.cue:8:19
        //     ./select.cue:11:2
        opt: (_){ _ }
      }
    }
  }
  #NormalJob: (#struct){
    req!: (int){ int }
    opt?: (#struct){
      run?: (string){ string }
    }
  }
}
-- out/compile --
--- in.cue
{
  ok1: {
    f: {
      in: number
      out: 〈0;in〉
    }
    k00: 0
    k10: (〈0;f〉 & {
      in: 〈1;k00〉
    }).out
    k20: (〈0;f〉 & {
      in: 〈1;k10〉
    }).out
    k30: (〈0;f〉 & {
      in: 〈1;k20〉
    }).out
  }
  ok2: {
    f: {
      in: number
      out: 〈0;in〉
    }
    k00: 0
    k10: {
      (〈1;f〉 & {
        in: 〈2;k00〉
      }).out
    }
    k20: {
      (〈1;f〉 & {
        in: 〈2;k10〉
      }).out
    }
    k30: {
      (〈1;f〉 & {
        in: 〈2;k20〉
      }).out
    }
  }
  ok3: {
    f: {
      in: number
      out: 〈0;in〉
    }
    k00: 0
    k10: {
      close((〈1;f〉 & {
        in: 〈2;k00〉
      })).out
    }
    k20: {
      close((〈1;f〉 & {
        in: 〈2;k10〉
      })).out
    }
    k30: {
      close((〈1;f〉 & {
        in: 〈2;k20〉
      })).out
    }
  }
  ok4: {
    f: {
      in: number
      out: 〈0;in〉
    }
    k00: 0
    k10: {
      out: {
        (〈2;f〉 & {
          in: 〈3;k00〉
        }).out
      }
    }.out
    k20: {
      out: {
        (〈2;f〉 & {
          in: 〈3;k10〉
        }).out
      }
    }.out
    k30: {
      out: {
        (〈2;f〉 & {
          in: 〈3;k20〉
        }).out
      }
    }.out
  }
  issue1708: {
    #add10: {
      in: number
      a10: {
        i: 〈1;in〉
        o: (〈0;i〉 + 10)
      }
      out: 〈0;a10〉.o
    }
    k00: 0
    k10: (〈0;#add10〉 & {
      in: 〈1;k00〉
    }).out
    k20: (〈0;#add10〉 & {
      in: 〈1;k10〉
    }).out
    k30: (〈0;#add10〉 & {
      in: 〈1;k20〉
    }).out
  }
}
--- issue3182.cue
{
  issue3182: {
    first: {
      t1: {
        x: {
          a: 〈1;x〉
        }.a
      }
    }
    first: {
      t2: {
        x: {
          a: {
            b: 〈2;x〉
          }
        }.a
      }
    }
    second: {
      {
        t: 〈1;x〉
      }.t.y
      x: {
        y: {
          x: {
            y: {
              a: 1
            }
          }
        }
      }
    }
    third: {
      {
        p: {
          x: 〈1;p〉
          y: 1
        }
      }.p.x.y
    }
  }
}
--- select.cue
{
  select: {
    direct: {
      #Step: (〈0;#Job〉 & {
        opt: _
      }).opt
      #Job: matchN(1, [
        〈3;#NormalJob〉,
      ])
    }
  }
  select: {
    indirect: {
      #Step: 〈0;#Job〉.opt
      #Job: (matchN(1, [
        〈3;#NormalJob〉,
      ]) & {
        opt: _
      })
    }
  }
  #NormalJob: {
    req!: int
    opt?: {
      run?: string
    }
  }
}
