cue/ast: allow use of Embed in NewStruct

Eventually &ast.EmbedDecl may go. Using Embed
allows for a smooth transition, rather than supporting
EmbedDecl directly. It is also more convenient.

Change-Id: Iec869ff00bf7e11acbce3ed07a41a6fee2934423
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6562
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index bfe8589..e7aec5e 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -520,6 +520,9 @@
 		case *LetClause:
 			s.Elts = append(s.Elts, x)
 			continue
+		case *embedding:
+			s.Elts = append(s.Elts, (*EmbedDecl)(x))
+			continue
 		case Label:
 			label = x
 		case string:
@@ -561,6 +564,13 @@
 	return s
 }
 
+// Embed can be used in conjunction with NewStruct to embed values.
+func Embed(x Expr) *embedding {
+	return (*embedding)(&EmbedDecl{Expr: x})
+}
+
+type embedding EmbedDecl
+
 // A ListLit node represents a literal list.
 type ListLit struct {
 	Lbrack token.Pos // position of "["
diff --git a/cue/ast/astutil/sanitize.go b/cue/ast/astutil/sanitize.go
index 2980be7..193dae8 100644
--- a/cue/ast/astutil/sanitize.go
+++ b/cue/ast/astutil/sanitize.go
@@ -136,7 +136,7 @@
 		case *ast.StructLit:
 			decls = &x.Elts
 		default:
-			panic("impossible scope")
+			panic(fmt.Sprintf("impossible scope type %T", parent))
 		}
 
 		i := 0