// Note: the corresponding code gen test covers this as well as verifying that code gen
// does what is expected, so it is more important to add new cases to that test.
:: { X:i8*, Y:i8**, Q:i8?*, N:i8 }

"*** Good function uses"
Pipe(Range(10))
Pipe(X)
Pipe(Q)
Pipe(Y)
Pipe(X->ForEach(it * 2))
Pipe(X->ForEach([if] it mod 3 = 1, it * 2))
Pipe(X->ForEach([while] it mod 3 = 1, it * 2))
Pipe(X->ForEachIf(it mod 3 = 1, it * 2))
Pipe(X->ForEachWhile(it mod 3 = 1, it * 2))
Pipe(X->ForEach([if] it mod 3 = 1, it * 2))
Pipe(X->CrossJoin(as a, Y as b, a = b->Count(), (a, b)))
Pipe(X->KeyJoin(as a, Y as b, a, b->TakeOne(), (a, b)))
Pipe(X->Distinct())
Pipe(X->Sort())
Pipe(Y->Sort(it->Sum(), it->TakeOne()))
Pipe(Chain(X, X->Take([if] it mod 2 = 0), X))
Pipe(X ++ X->Take([if] it mod 2 = 0) ++ X)
Pipe(Y->ChainMap())
Pipe(X->ChainMap(Range(it)))
Pipe(X->DropOne())
Pipe(X->DropOne(it < 7))
Pipe(X->Take(5))
Pipe(Y->Take(5))
Pipe(X->Drop(5))
Pipe(Y->Drop(5))
Pipe(X->Take(5, [if] it < 7))
Pipe(Y->Take(5, [if] it->Count() < 7))
Pipe(X->Drop(5, [if] it < 7))
Pipe(Y->Drop(5, [if] it->Count() < 7))
Pipe(X->Take(5, [while] it < 7))
Pipe(Y->Take(5, [while] it->Count() < 7))
Pipe(X->Drop(5, [while] it < 7))
Pipe(Y->Drop(5, [while] it->Count() < 7))
Pipe(X->Take([if] it < 7))
Pipe(Y->Take([if] it->Count() < 7))
Pipe(X->Drop([if] it < 7))
Pipe(Y->Drop([if] it->Count() < 7))
Pipe(X->Take([while] it < 7))
Pipe(Y->Take([while] it->Count() < 7))
Pipe(X->Drop([while] it < 7))
Pipe(Y->Drop([while] it->Count() < 7))
Pipe(X->TakeIf(it < 7))
Pipe(Y->TakeIf(it->Count() < 7))
Pipe(X->DropIf(it < 7))
Pipe(Y->DropIf(it->Count() < 7))
Pipe(X->TakeWhile(it < 7))
Pipe(Y->TakeWhile(it->Count() < 7))
Pipe(X->DropWhile(it < 7))
Pipe(Y->DropWhile(it->Count() < 7))
Pipe(Repeat(X, N))
Pipe(Y->ForEach(it->ForEach(it > 3)->Any()))
Pipe(Y->ForEach(it->Any(it > 3)))
Pipe(Y->ForEach(it->ForEach(it > 3)->All()))
Pipe(Y->ForEach(it->All(it > 3)))
Pipe(Fold(x:Range(10), s:X, s ++ [x]))
Pipe(ScanZ(x:X, s:0, s + x))
Pipe(ScanX(x:X, s:0, s + x))
Pipe(Generate(n:N, X->Take(n)))
Pipe(Generate(n:N, cur:X, cur ++ [n]))
Pipe(With(a:X, a))
Pipe(With(a:X ++ X, b:a ++ a, c:b ++ b, c ++ c))
Pipe(WithMap(a:X, a * 2))
Pipe(GuardMap(a:Q, a * 2))
Pipe(If(N > 3, X, Q))
Pipe(X->{A: it}->SetFields(B: A * A))
Pipe(X->{A: it}->AddFields(B: A * A))
Pipe({A: X}->SetFields(B: A * A).B)
Pipe(X->GroupBy(it))
Pipe(X->GroupBy([key] A: it, [item] B: it*2, [group] C: group->Take(5)))
Pipe(X->GroupBy([key] A: it, [item] B: it*2, [group] C: group->Count()))
Pipe(Y->ForEach(it->Sum()))
Pipe(X->GetType().Len->Range())
Pipe(X->GetBindInfo().Len->Range())
Pipe(X->{ A: it, B: it^2, C: it < 7 })
Pipe({ A: X }+>{ B: A->Take(3) }.B)
Pipe(Y->ToText()->ForEach(it->Concat(",")))

"*** Bad function uses"
Pipe(X->First() ?? 3 | Range(_))
Pipe(Y->First())
Pipe(X->TakeAt(3)->Range())
Pipe(Y->TakeAt(3))
Pipe(X->TakeOne()->Range())
Pipe(Y->TakeOne())
Pipe(X->TakeOne(it < 7)->Range())
Pipe(Y->TakeOne(it->Count() < 7))
Pipe(Repeat(X, X->Count()))
Pipe(X->Count()->Range())
Pipe(X if X->ForEach(it > 3)->Any() else X ++ X)
Pipe(X if X->Any(it > 3) else X ++ X)
Pipe(X if X->ForEach(it > 3)->All() else X ++ X)
Pipe(X if X->All(it > 3) else X ++ X)
Pipe(X->MakePairs())
Pipe(Fold(x:X, s:0, s + x)->Range())
Pipe(Guard(X, Y))
Pipe(Q if IsNull(X) else X)
Pipe(Q if IsEmpty(X) else X)
Pipe(X->ToText()->Concat(",").Len->Range())
Pipe({A: X}->SetFields(B: A * A->Count()).B)
Pipe(X->Sum()->Range())
Pipe(X->Tensor.From().Shape[0]->Range())
Pipe({ A: X }+>{ B: A->Count() }.B->Range())
Pipe(X ++ X->Count()->Range())
Pipe(X->Count()->Range() ++ X)
Pipe(X, X->Count()->Range())
Pipe(X->Count()->Range(), X)

"*** These could be safe but are errors"
Pipe(Y->{ A: it }+>{ B: A->Count() })
Pipe(X->ForEach(X->Count())) // Hoisting makes this "bad"!
Pipe(With(temp: X->Count(), X->ForEach(temp))) // Result of hoisting the previous one.
Pipe(X->ForEach(as a, X->Count(it < a)))
