cue/ast: fully remove support for old-style comprehensions

Change-Id: I845641df208d09b3b89119db986dcb73a2c293d6
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9562
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index a7c99a9..e564bc4 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -601,17 +601,6 @@
 	expr
 }
 
-// A ListComprehension node represents as list comprehension.
-type ListComprehension struct {
-	Lbrack  token.Pos // position of "["
-	Expr    Expr
-	Clauses []Clause  // Feed or Guard (TODO let)
-	Rbrack  token.Pos // position of "]"
-
-	comments
-	expr
-}
-
 // A ForClause node represents a for clause in a comprehension.
 type ForClause struct {
 	For token.Pos
@@ -770,34 +759,32 @@
 	return &x.Lbrace
 }
 
-func (x *ListLit) Pos() token.Pos            { return x.Lbrack }
-func (x *ListLit) pos() *token.Pos           { return &x.Lbrack }
-func (x *Ellipsis) Pos() token.Pos           { return x.Ellipsis }
-func (x *Ellipsis) pos() *token.Pos          { return &x.Ellipsis }
-func (x *ListComprehension) Pos() token.Pos  { return x.Lbrack }
-func (x *ListComprehension) pos() *token.Pos { return &x.Lbrack }
-func (x *LetClause) Pos() token.Pos          { return x.Let }
-func (x *LetClause) pos() *token.Pos         { return &x.Let }
-func (x *ForClause) Pos() token.Pos          { return x.For }
-func (x *ForClause) pos() *token.Pos         { return &x.For }
-func (x *IfClause) Pos() token.Pos           { return x.If }
-func (x *IfClause) pos() *token.Pos          { return &x.If }
-func (x *ParenExpr) Pos() token.Pos          { return x.Lparen }
-func (x *ParenExpr) pos() *token.Pos         { return &x.Lparen }
-func (x *SelectorExpr) Pos() token.Pos       { return x.X.Pos() }
-func (x *SelectorExpr) pos() *token.Pos      { return x.X.pos() }
-func (x *IndexExpr) Pos() token.Pos          { return x.X.Pos() }
-func (x *IndexExpr) pos() *token.Pos         { return x.X.pos() }
-func (x *SliceExpr) Pos() token.Pos          { return x.X.Pos() }
-func (x *SliceExpr) pos() *token.Pos         { return x.X.pos() }
-func (x *CallExpr) Pos() token.Pos           { return x.Fun.Pos() }
-func (x *CallExpr) pos() *token.Pos          { return x.Fun.pos() }
-func (x *UnaryExpr) Pos() token.Pos          { return x.OpPos }
-func (x *UnaryExpr) pos() *token.Pos         { return &x.OpPos }
-func (x *BinaryExpr) Pos() token.Pos         { return x.X.Pos() }
-func (x *BinaryExpr) pos() *token.Pos        { return x.X.pos() }
-func (x *BottomLit) Pos() token.Pos          { return x.Bottom }
-func (x *BottomLit) pos() *token.Pos         { return &x.Bottom }
+func (x *ListLit) Pos() token.Pos       { return x.Lbrack }
+func (x *ListLit) pos() *token.Pos      { return &x.Lbrack }
+func (x *Ellipsis) Pos() token.Pos      { return x.Ellipsis }
+func (x *Ellipsis) pos() *token.Pos     { return &x.Ellipsis }
+func (x *LetClause) Pos() token.Pos     { return x.Let }
+func (x *LetClause) pos() *token.Pos    { return &x.Let }
+func (x *ForClause) Pos() token.Pos     { return x.For }
+func (x *ForClause) pos() *token.Pos    { return &x.For }
+func (x *IfClause) Pos() token.Pos      { return x.If }
+func (x *IfClause) pos() *token.Pos     { return &x.If }
+func (x *ParenExpr) Pos() token.Pos     { return x.Lparen }
+func (x *ParenExpr) pos() *token.Pos    { return &x.Lparen }
+func (x *SelectorExpr) Pos() token.Pos  { return x.X.Pos() }
+func (x *SelectorExpr) pos() *token.Pos { return x.X.pos() }
+func (x *IndexExpr) Pos() token.Pos     { return x.X.Pos() }
+func (x *IndexExpr) pos() *token.Pos    { return x.X.pos() }
+func (x *SliceExpr) Pos() token.Pos     { return x.X.Pos() }
+func (x *SliceExpr) pos() *token.Pos    { return x.X.pos() }
+func (x *CallExpr) Pos() token.Pos      { return x.Fun.Pos() }
+func (x *CallExpr) pos() *token.Pos     { return x.Fun.pos() }
+func (x *UnaryExpr) Pos() token.Pos     { return x.OpPos }
+func (x *UnaryExpr) pos() *token.Pos    { return &x.OpPos }
+func (x *BinaryExpr) Pos() token.Pos    { return x.X.Pos() }
+func (x *BinaryExpr) pos() *token.Pos   { return x.X.pos() }
+func (x *BottomLit) Pos() token.Pos     { return x.Bottom }
+func (x *BottomLit) pos() *token.Pos    { return &x.Bottom }
 
 func (x *BadExpr) End() token.Pos { return x.To }
 func (x *Ident) End() token.Pos {
@@ -819,18 +806,17 @@
 	}
 	return x.Ellipsis.Add(3) // len("...")
 }
-func (x *ListComprehension) End() token.Pos { return x.Rbrack }
-func (x *LetClause) End() token.Pos         { return x.Expr.End() }
-func (x *ForClause) End() token.Pos         { return x.Source.End() }
-func (x *IfClause) End() token.Pos          { return x.Condition.End() }
-func (x *ParenExpr) End() token.Pos         { return x.Rparen.Add(1) }
-func (x *SelectorExpr) End() token.Pos      { return x.Sel.End() }
-func (x *IndexExpr) End() token.Pos         { return x.Rbrack.Add(1) }
-func (x *SliceExpr) End() token.Pos         { return x.Rbrack.Add(1) }
-func (x *CallExpr) End() token.Pos          { return x.Rparen.Add(1) }
-func (x *UnaryExpr) End() token.Pos         { return x.X.End() }
-func (x *BinaryExpr) End() token.Pos        { return x.Y.End() }
-func (x *BottomLit) End() token.Pos         { return x.Bottom.Add(1) }
+func (x *LetClause) End() token.Pos    { return x.Expr.End() }
+func (x *ForClause) End() token.Pos    { return x.Source.End() }
+func (x *IfClause) End() token.Pos     { return x.Condition.End() }
+func (x *ParenExpr) End() token.Pos    { return x.Rparen.Add(1) }
+func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
+func (x *IndexExpr) End() token.Pos    { return x.Rbrack.Add(1) }
+func (x *SliceExpr) End() token.Pos    { return x.Rbrack.Add(1) }
+func (x *CallExpr) End() token.Pos     { return x.Rparen.Add(1) }
+func (x *UnaryExpr) End() token.Pos    { return x.X.End() }
+func (x *BinaryExpr) End() token.Pos   { return x.Y.End() }
+func (x *BottomLit) End() token.Pos    { return x.Bottom.Add(1) }
 
 // ----------------------------------------------------------------------------
 // Convenience functions for Idents
diff --git a/cue/ast/astutil/apply.go b/cue/ast/astutil/apply.go
index 58e0fce..22d12c6 100644
--- a/cue/ast/astutil/apply.go
+++ b/cue/ast/astutil/apply.go
@@ -432,13 +432,6 @@
 	case *ast.Package:
 		apply(v, c, &n.Name)
 
-	case *ast.ListComprehension:
-		apply(v, c, &n.Expr)
-		clauses := n.Clauses
-		for i := range clauses {
-			apply(v, c, &clauses[i])
-		}
-
 	case *ast.ForClause:
 		if n.Key != nil {
 			apply(v, c, &n.Key)
diff --git a/cue/ast/astutil/resolve.go b/cue/ast/astutil/resolve.go
index b1081b0..2db1570 100644
--- a/cue/ast/astutil/resolve.go
+++ b/cue/ast/astutil/resolve.go
@@ -278,9 +278,6 @@
 	case *ast.Comprehension:
 		s = scopeClauses(s, x.Clauses)
 
-	case *ast.ListComprehension:
-		s = scopeClauses(s, x.Clauses)
-
 	case *ast.Field:
 		var n ast.Node = x.Label
 		alias, ok := x.Label.(*ast.Alias)
diff --git a/cue/ast/astutil/walk.go b/cue/ast/astutil/walk.go
index a3e0249..2de73d6 100644
--- a/cue/ast/astutil/walk.go
+++ b/cue/ast/astutil/walk.go
@@ -174,12 +174,6 @@
 	case *ast.Package:
 		// The package identifier isn't really an identifier. Skip it.
 
-	case *ast.ListComprehension:
-		walk(v, n.Expr)
-		for _, c := range n.Clauses {
-			walk(v, c)
-		}
-
 	case *ast.LetClause:
 		walk(v, n.Ident)
 		walk(v, n.Expr)
diff --git a/cue/ast/walk.go b/cue/ast/walk.go
index a0f81fd..a23fce4 100644
--- a/cue/ast/walk.go
+++ b/cue/ast/walk.go
@@ -183,12 +183,6 @@
 	case *Package:
 		walk(v, n.Name)
 
-	case *ListComprehension:
-		walk(v, n.Expr)
-		for _, c := range n.Clauses {
-			walk(v, c)
-		}
-
 	case *ForClause:
 		if n.Key != nil {
 			walk(v, n.Key)
diff --git a/cue/format/node.go b/cue/format/node.go
index 697d538..6d06ae4 100644
--- a/cue/format/node.go
+++ b/cue/format/node.go
@@ -312,7 +312,7 @@
 
 		if n.Value != nil {
 			switch n.Value.(type) {
-			case *ast.ListComprehension, *ast.ListLit, *ast.StructLit:
+			case *ast.ListLit, *ast.StructLit:
 				f.expr(n.Value)
 			default:
 				f.print(indent)
@@ -670,20 +670,6 @@
 	case *ast.Ellipsis:
 		f.ellipsis(x)
 
-	case *ast.ListComprehension:
-		f.print(x.Lbrack, token.LBRACK, blank, indent)
-		f.print(blank)
-		f.walkClauseList(x.Clauses, blank)
-		f.print(blank, nooverride)
-		if _, ok := x.Expr.(*ast.StructLit); ok {
-			f.expr(x.Expr)
-		} else {
-			f.print(token.LBRACE, blank)
-			f.expr(x.Expr)
-			f.print(blank, token.RBRACE)
-		}
-		f.print(unindent, f.wsOverride(blank), x.Rbrack, token.RBRACK)
-
 	default:
 		panic(fmt.Sprintf("unimplemented type %T", x))
 	}
diff --git a/cue/format/testdata/expressions.golden b/cue/format/testdata/expressions.golden
index 4ead811..20554e6 100644
--- a/cue/format/testdata/expressions.golden
+++ b/cue/format/testdata/expressions.golden
@@ -143,15 +143,13 @@
 	e: [ for x in someObject if x > 9 {
 		x
 	}]
-	e: [ for x in someObject if x > 9 { x } ]
+	e: [ for x in someObject if x > 9 {x}]
 	e: [
 		for x in someObject
-		if x > 9 { x } ]
+		if x > 9 {x}]
 	e: [
 		for x in someObject
-		if x > 9 { x // TODO(deprecated): remove!
-		}
-	]
+		if x > 9 {x}]
 
 	e: [
 		if x > 1 {},
diff --git a/cue/format/testdata/expressions.input b/cue/format/testdata/expressions.input
index a99d791..a0595d7 100644
--- a/cue/format/testdata/expressions.input
+++ b/cue/format/testdata/expressions.input
@@ -141,14 +141,14 @@
     e: [ for x in someObject if x > 9 {
         x
     }]
-    e: [ x for x in someObject if x > 9 ]
-    e: [ x
+    e: [ for x in someObject if x > 9 {x}]
+    e: [
     for x in someObject
-    if x > 9 ]
-   e: [ x // TODO(deprecated): remove!
+    if x > 9 {x}]
+   e: [
     for x in someObject
     if x > 9
-    ]
+    {x}]
 
     e: [
         if x > 1 {},
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index abf4d91..48d21be 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -1180,25 +1180,6 @@
 
 	elts := p.parseListElements()
 
-	if clauses, _ := p.parseComprehensionClauses(false); clauses != nil {
-		var expr ast.Expr
-		p.assertV0(p.pos, 1, 3, "old-style list comprehensions")
-		if len(elts) != 1 {
-			p.errf(lbrack.Add(1), "list comprehension must have exactly one element")
-		}
-		if len(elts) > 0 {
-			expr = elts[0]
-		}
-		rbrack := p.expectClosing(token.RBRACK, "list comprehension")
-
-		return &ast.ListComprehension{
-			Lbrack:  lbrack,
-			Expr:    expr,
-			Clauses: clauses,
-			Rbrack:  rbrack,
-		}
-	}
-
 	if p.tok == token.ELLIPSIS {
 		ellipsis := &ast.Ellipsis{
 			Ellipsis: p.pos,
@@ -1326,7 +1307,6 @@
 	case *ast.Interpolation:
 	case *ast.StructLit:
 	case *ast.ListLit:
-	case *ast.ListComprehension:
 	case *ast.ParenExpr:
 		panic("unreachable")
 	case *ast.SelectorExpr:
diff --git a/internal/astinternal/debugstr.go b/internal/astinternal/debugstr.go
index b305969..0121b45 100644
--- a/internal/astinternal/debugstr.go
+++ b/internal/astinternal/debugstr.go
@@ -108,14 +108,6 @@
 		}
 		return out
 
-	case *ast.ListComprehension:
-		out := "["
-		out += DebugStr(v.Expr)
-		out += " "
-		out += DebugStr(v.Clauses)
-		out += "]"
-		return out
-
 	case *ast.ForClause:
 		out := "for "
 		if v.Key != nil {
diff --git a/internal/core/compile/compile.go b/internal/core/compile/compile.go
index f2c8f12..d169b97 100644
--- a/internal/core/compile/compile.go
+++ b/internal/core/compile/compile.go
@@ -519,7 +519,7 @@
 		c.insertAlias(x.Ident, a)
 
 	case *ast.Alias:
-		c.errf(x, "old-style alias no longer supported: use let clause.\nuse cue fix to update.")
+		c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.")
 	}
 }
 
@@ -626,7 +626,7 @@
 
 	// Handled in addLetDecl.
 	case *ast.LetClause:
-	// case: *ast.Alias: // TODO(value aliases)
+	// case: *ast.Alias: // TODO(value alias)
 
 	case *ast.CommentGroup:
 		// Nothing to do for a free-floating comment group.
@@ -665,7 +665,7 @@
 		c.updateAlias(x.Ident, expr)
 
 	case *ast.Alias:
-		c.errf(x, "old-style alias no longer supported: use let clause.\nuse cue fix to update.")
+		c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.")
 	}
 }
 
diff --git a/internal/encoding/encoding.go b/internal/encoding/encoding.go
index fada360..79e2fe5 100644
--- a/internal/encoding/encoding.go
+++ b/internal/encoding/encoding.go
@@ -444,8 +444,7 @@
 		}
 
 	case *ast.BinaryExpr, *ast.ParenExpr, *ast.IndexExpr, *ast.SliceExpr,
-		*ast.CallExpr, *ast.Comprehension, *ast.ListComprehension,
-		*ast.Interpolation:
+		*ast.CallExpr, *ast.Comprehension, *ast.Interpolation:
 		check(n, constraints, "expressions", true)
 
 	case *ast.Ellipsis:
diff --git a/internal/encoding/yaml/encode_test.go b/internal/encoding/yaml/encode_test.go
index b90447c..e196151 100644
--- a/internal/encoding/yaml/encode_test.go
+++ b/internal/encoding/yaml/encode_test.go
@@ -170,9 +170,9 @@
 				a: 1
 				b: 3
 			}
-			c: [1, [ x for x in m ]]
+			c: [1, [ for x in m {x}]]
 			`,
-		out: "yaml: unsupported node [x for x in m ] (*ast.ListComprehension)",
+		out: "yaml: unsupported node for x in m {x} (*ast.Comprehension)",
 	}, {
 		name: "disallowMultipleEmbeddings",
 		in: `
diff --git a/tools/fix/fix_test.go b/tools/fix/fix_test.go
index 3f251ac..6cdb2b7 100644
--- a/tools/fix/fix_test.go
+++ b/tools/fix/fix_test.go
@@ -73,14 +73,6 @@
 `,
 	}, {
 		in: `
-		y: [1, 2, 3, 4]
-		a: [ x for x in y ]
-		`,
-		out: `y: [1, 2, 3, 4]
-a: [ for x in y { x } ]
-`,
-	}, {
-		in: `
 		y = foo
 		`,
 		out: `