Prepare for vdltest package

Collection of small changes in preparation for the new vdltest
package.

MultiPart: 2/2
Change-Id: I7c40b69225532513b128a613773e2c76cf7660eb
diff --git a/cmd/sb/internal/demodb/demodb.vdl.go b/cmd/sb/internal/demodb/demodb.vdl.go
index bf1f25a..b7e7949 100644
--- a/cmd/sb/internal/demodb/demodb.vdl.go
+++ b/cmd/sb/internal/demodb/demodb.vdl.go
@@ -4810,7 +4810,7 @@
 			return err
 		}
 		enc.SetNextStartValueIsOptional()
-		if err := (*x.Maybe).VDLWrite(enc); err != nil {
+		if err := x.Maybe.VDLWrite(enc); err != nil {
 			return err
 		}
 	}
diff --git a/lib/vdl/build/build_test.go b/lib/vdl/build/build_test.go
index 33748f9..e7954bc 100644
--- a/lib/vdl/build/build_test.go
+++ b/lib/vdl/build/build_test.go
@@ -18,7 +18,7 @@
 	"v.io/v23/vdlroot/vdltool"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 	"v.io/x/ref/lib/vdl/testdata/base"
 	"v.io/x/ref/lib/vdl/vdlutil"
 )
@@ -83,7 +83,7 @@
 		name := fmt.Sprintf("%+v", test)
 		errs := vdlutil.NewErrors(-1)
 		got := build.SrcDirs(errs)
-		vdltest.ExpectResult(t, errs, name, test.ErrRE)
+		vdltestutil.ExpectResult(t, errs, name, test.ErrRE)
 		// Every result will have our valid VDLPATH srcdir.
 		var want []string
 		if test.Want != "" {
@@ -139,7 +139,7 @@
 		if test.Want == nil {
 			errRE = "No src dirs; set VDLPATH to a valid value"
 		}
-		vdltest.ExpectResult(t, errs, name, errRE)
+		vdltestutil.ExpectResult(t, errs, name, errRE)
 		// Every result will have our valid VDLROOT srcdir.
 		want := append([]string{abs(defaultVDLRoot)}, test.Want...)
 		if !reflect.DeepEqual(got, want) {
@@ -383,7 +383,7 @@
 			name := fmt.Sprintf("%v %v", mode, test.InPaths)
 			errs := vdlutil.NewErrors(-1)
 			pkgs := build.TransitivePackages(test.InPaths, mode, build.Opts{}, errs)
-			vdltest.ExpectResult(t, errs, name, "")
+			vdltestutil.ExpectResult(t, errs, name, "")
 			var paths []string
 			for _, pkg := range pkgs {
 				paths = append(paths, pkg.Path)
@@ -484,7 +484,7 @@
 				// Ignore mode returns success, while error mode returns error.
 				errRE = ""
 			}
-			vdltest.ExpectResult(t, errs, name, errRE)
+			vdltestutil.ExpectResult(t, errs, name, errRE)
 			if pkgs != nil {
 				t.Errorf("%v got unexpected packages %v", name, pkgs)
 			}
@@ -511,7 +511,7 @@
 		name := path.Base(test.Path)
 		env := compile.NewEnv(-1)
 		deps := build.TransitivePackages([]string{test.Path}, build.UnknownPathIsError, build.Opts{}, env.Errors)
-		vdltest.ExpectResult(t, env.Errors, name, "")
+		vdltestutil.ExpectResult(t, env.Errors, name, "")
 		if len(deps) != 1 {
 			t.Fatalf("TransitivePackages(%q) got %v, want 1 dep", name, deps)
 		}
@@ -554,7 +554,7 @@
 		for _, dep := range deps {
 			build.BuildPackage(dep, env)
 		}
-		vdltest.ExpectResult(t, env.Errors, test.Src, "")
+		vdltestutil.ExpectResult(t, env.Errors, test.Src, "")
 		// Test BuildConfig
 		wantV := vdl.ZeroValue(vdl.TypeOf(test.Value))
 		if err := vdl.Convert(wantV, test.Value); err != nil {
@@ -564,14 +564,14 @@
 		if !vdl.EqualValue(gotV, wantV) {
 			t.Errorf("BuildConfig(%v) got %v, want %v", test.Src, gotV, wantV)
 		}
-		vdltest.ExpectResult(t, env.Errors, test.Src, "")
+		vdltestutil.ExpectResult(t, env.Errors, test.Src, "")
 		// TestBuildConfigValue
 		gotRV := reflect.New(reflect.TypeOf(test.Value))
 		build.BuildConfigValue("file", strings.NewReader(test.Src), nil, env, gotRV.Interface())
 		if got, want := gotRV.Elem().Interface(), test.Value; !reflect.DeepEqual(got, want) {
 			t.Errorf("BuildConfigValue(%v) got %v, want %v", test.Src, got, want)
 		}
-		vdltest.ExpectResult(t, env.Errors, test.Src, "")
+		vdltestutil.ExpectResult(t, env.Errors, test.Src, "")
 	}
 }
 
@@ -624,7 +624,7 @@
 	for _, test := range tests {
 		env := compile.NewEnv(-1)
 		values := build.BuildExprs(test.Data, test.Types, env)
-		vdltest.ExpectResult(t, env.Errors, test.Data, test.Err)
+		vdltestutil.ExpectResult(t, env.Errors, test.Data, test.Err)
 		if got, want := len(values), len(test.Want); got != want {
 			t.Errorf("%s got len %d, want %d", test.Data, got, want)
 		}
diff --git a/lib/vdl/build/internal/builtin_vdlroot/builtin_vdlroot.go b/lib/vdl/build/internal/builtin_vdlroot/builtin_vdlroot.go
index f4b30df..c55670a 100644
--- a/lib/vdl/build/internal/builtin_vdlroot/builtin_vdlroot.go
+++ b/lib/vdl/build/internal/builtin_vdlroot/builtin_vdlroot.go
@@ -77,7 +77,7 @@
 	return nil
 }
 
-var _mathMathVdl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\xce\xc1\x4a\x03\x31\x10\xc6\xf1\x7b\x9e\xe2\x7b\x01\xb7\x76\x2d\x8b\xd7\x5a\x7b\x28\x88\x07\xab\xde\xa7\xc9\xec\x26\x98\x4d\x96\x64\x52\x5c\xa4\xef\x6e\xdc\x83\xa0\xd0\xb9\xcd\x9f\xf9\xc1\xac\x56\xd8\xc5\x69\x4e\x6e\xb0\x82\xf6\x76\xdd\xe1\xd5\x32\xde\x29\x90\x71\x65\xc4\xb6\x88\x8d\x29\x37\xd8\x7a\x8f\xe5\x28\x23\x71\xe6\x74\x66\xd3\xa8\x8a\xdf\x32\x23\xf6\x10\xeb\x32\x72\x2c\x49\x33\x74\x34\x8c\xba\x0e\xf1\xcc\x29\xb0\xc1\x69\x06\xe1\xe1\xf8\x78\x93\x65\xf6\xfc\xa3\xbc\xd3\x1c\xaa\x14\x4b\x02\x4d\x01\x27\x46\x1f\x4b\x30\x70\xa1\x46\xc6\xd3\x61\xb7\x7f\x3e\xee\xd1\x3b\xcf\x8d\x52\x13\xe9\x0f\x1a\x18\x23\x89\x55\x4a\xe6\x89\xeb\xd7\xe3\xe4\xf9\xb3\xdb\x20\x4b\x2a\x5a\xf0\xa5\x50\xe7\x85\xc9\xa3\xf7\x91\xe4\xae\x5d\xc2\x61\xa4\xe1\x37\x5c\xfe\xe2\x75\x7b\x7f\x4d\x77\x9b\x7f\xba\x86\xcb\x77\x00\x00\x00\xff\xff\x17\xc2\xba\xec\x2d\x01\x00\x00")
+var _mathMathVdl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x8e\xb1\x4e\xc3\x30\x14\x45\xe7\xfa\x2b\xee\x0f\x34\xa5\x69\x15\xb1\x96\xd2\xa1\x12\x62\xa0\xc0\xfe\x92\xbc\x24\x16\x8e\x1d\xd9\xcf\x15\x11\xea\xbf\xe3\x64\x40\x19\x90\x10\xe3\xb1\x7c\xde\x3d\x9b\x0d\x8e\x6e\x18\xbd\x6e\x3b\x41\x7e\xb7\x2d\xf0\xda\x31\xde\xc9\x52\xad\x63\x8f\x43\x94\xce\xf9\x90\xe1\x60\x0c\xe6\x4f\x01\x9e\x03\xfb\x2b\xd7\x99\x4a\xf2\x5b\x60\xb8\x06\xd2\xe9\x80\xe0\xa2\xaf\x18\x95\xab\x19\x09\x5b\x77\x65\x6f\xb9\x46\x39\x82\xf0\x70\x79\x5c\x07\x19\x0d\x4f\x96\xd1\x15\xdb\x64\x4a\x47\x82\x8a\x2c\x4a\x46\xe3\xa2\xad\xa1\x6d\x7a\x64\x3c\x9d\x8f\xa7\xe7\xcb\x09\x8d\x36\x9c\x29\x35\x50\xf5\x41\x2d\xa3\x27\xe9\x94\x9a\x9b\xfb\xc1\xf0\x67\xb1\x9f\x86\x28\x4d\xce\x08\x1b\xfb\x92\xfd\x8c\x2e\xa4\xe5\x54\xb6\xcb\xd7\xa5\x96\x14\x4d\x06\x34\x0d\xf4\xd4\x6a\x4b\x7e\xc4\x40\x5e\x42\xa6\x64\x1c\x78\x71\x2f\x88\x8f\x95\xe0\x4b\xad\x5e\x26\xa5\x31\x8e\x64\x97\xab\xd5\x39\x79\x3f\x74\x5b\x46\x6c\xf3\xfb\x3f\x2b\x8a\xfd\x3f\x2a\xa6\x83\xbf\x65\x14\xfb\x65\x46\xa2\x9b\xfa\x0e\x00\x00\xff\xff\xce\xca\xd1\x3a\xbf\x01\x00\x00")
 
 func mathMathVdlBytes() ([]byte, error) {
 	return bindataRead(
@@ -97,7 +97,7 @@
 	return a, nil
 }
 
-var _mathVdlConfig = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x64\x8d\xcd\x6a\xc3\x30\x10\x84\xcf\xf6\x53\x0c\x3e\x07\x87\x96\x52\x4a\xa0\xa7\x1c\x4a\x2f\x3d\x19\x7a\x16\xd2\xda\x11\x95\xb5\x42\xd9\x84\x96\x92\x77\xef\x4a\x4e\xe9\x8f\x17\xb4\x82\x99\xd9\x6f\xb6\x5b\x0c\x07\xc2\xd9\x85\xde\x72\x1c\xfd\x84\xd1\x07\xc2\xc8\x19\xa2\xfa\x51\x4c\x74\x26\x3b\x88\x9f\x09\xc9\xd8\x37\x33\x11\x96\xe4\x29\xd3\x11\xde\x79\x9e\x8d\x78\x8b\xa8\xfb\x4c\xad\x02\xe5\x23\x15\x27\x82\x8c\x3d\x60\xa2\x48\xd9\x08\x39\x04\x13\xa7\x93\xde\xf7\xed\xb5\xea\xb1\xf4\x0a\x73\xe8\xf7\x55\xf8\x6c\x9b\x27\xde\x41\xbf\xe6\xd5\x67\x1a\xf8\xa5\x32\x87\xc2\x5b\xe4\xa6\xdb\xf3\x9c\x02\xbd\xdf\xdc\x3e\x74\x57\xa9\x29\xfe\x0e\x3a\x9d\xfd\x31\x37\xd5\x7a\x9e\x13\x67\x29\xc7\x97\x2a\x2c\xfb\x1b\x72\x7f\x57\x19\xf8\x37\x2b\x9e\xe6\x36\xab\xd4\x1f\xf4\x6f\xa3\x76\x94\xa5\xef\xd2\x7e\x05\x00\x00\xff\xff\x3b\xea\x99\x41\x61\x01\x00\x00")
+var _mathVdlConfig = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x8d\xc1\x6a\x85\x30\x10\x45\xd7\xe6\x2b\x2e\xae\x8b\xd2\x52\x4a\x11\xba\x72\xd1\x5d\x57\x42\xd7\x21\x8e\x31\x34\x66\x24\x46\x69\x11\xff\xbd\x13\x2d\xe5\xf1\x16\x99\xc0\x99\x33\xf7\xd6\x35\xba\x91\xb0\xf5\xbe\x32\x1c\x06\x67\x31\x38\x4f\x18\x38\x22\x09\x9f\x74\x1a\x31\x6b\xf3\xa5\x2d\xe1\x12\xd6\x48\x0b\x5c\xef\x58\x76\xce\x20\xc8\xdc\x08\xe9\x67\xa6\x45\x49\x9a\x0b\x20\x6d\x46\x58\x0a\x14\x75\xa2\x1e\x5e\x07\xbb\xca\x7d\xa5\xfe\x1a\xde\x72\x5d\x62\xf6\x55\x7b\x82\x5d\x15\xef\xdc\x40\xbe\xe2\xd3\x45\xea\xf8\xe3\xcc\xec\x72\xe4\x85\x8b\xb2\xe5\x69\xf6\xf4\xfd\xf2\x5c\x36\xc0\x9e\x57\x0d\x4a\xf3\x0f\x8f\x87\x5b\xeb\xf1\xe9\x55\xb4\x3b\x2b\xc3\x53\xcb\x43\xde\xa1\x7e\x03\x00\x00\xff\xff\x5f\x2c\xdb\x37\xfc\x00\x00\x00")
 
 func mathVdlConfigBytes() ([]byte, error) {
 	return bindataRead(
diff --git a/lib/vdl/codegen/golang/arg.go b/lib/vdl/codegen/golang/arg.go
new file mode 100644
index 0000000..ed76042
--- /dev/null
+++ b/lib/vdl/codegen/golang/arg.go
@@ -0,0 +1,58 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package golang
+
+import (
+	"v.io/v23/vdl"
+)
+
+func typedArg(name string, tt *vdl.Type) namedArg {
+	return namedArg{name, tt.Kind() == vdl.Optional}
+}
+
+// namedArg represents a named argument, with methods to conveniently return the
+// pointer or non-pointer form of the argument.
+type namedArg struct {
+	Name  string // variable name
+	IsPtr bool   // is the variable a pointer type
+}
+
+func (arg namedArg) IsValid() bool {
+	return arg.Name != ""
+}
+
+func (arg namedArg) Ptr() string {
+	if arg.IsPtr {
+		return arg.Name
+	}
+	return "&" + arg.Name
+}
+
+func (arg namedArg) Ref() string {
+	if arg.IsPtr {
+		return "*" + arg.Name
+	}
+	return arg.Name
+}
+
+func (arg namedArg) SafeRef() string {
+	if arg.IsPtr {
+		return "(*" + arg.Name + ")"
+	}
+	return arg.Name
+}
+
+func (arg namedArg) Field(field vdl.Field) namedArg {
+	return typedArg(arg.Name+"."+field.Name, field.Type)
+}
+
+func (arg namedArg) Index(index string, tt *vdl.Type) namedArg {
+	return typedArg(arg.SafeRef()+"["+index+"]", tt)
+}
+
+func (arg namedArg) ArrayIndex(index string, tt *vdl.Type) namedArg {
+	// Go has a special-case: pointers to arrays can be indexed without the star.
+	return typedArg(arg.Name+"["+index+"]", tt)
+}
diff --git a/lib/vdl/codegen/golang/gen.go b/lib/vdl/codegen/golang/gen.go
index 14293b5..f35bfe5 100644
--- a/lib/vdl/codegen/golang/gen.go
+++ b/lib/vdl/codegen/golang/gen.go
@@ -172,7 +172,6 @@
 	"time": true,
 	"v.io/x/ref/lib/vdl/testdata/nativetest": true,
 	"v.io/v23/security":                      true,
-	"v.io/vdlroot/math":                      true,
 }
 
 func validateGoConfig(pkg *compile.Package, env *compile.Env) {
diff --git a/lib/vdl/codegen/golang/gen_dec.go b/lib/vdl/codegen/golang/gen_dec.go
index 0241214..a4a1ae0 100644
--- a/lib/vdl/codegen/golang/gen_dec.go
+++ b/lib/vdl/codegen/golang/gen_dec.go
@@ -495,7 +495,7 @@
 func genTargetDef(data *goData, t *vdl.Type) string {
 	if !data.createdTargets[t] {
 		data.createdTargets[t] = true
-		if t.IsBytes() {
+		if t.IsBytes() && t.Elem() == vdl.ByteType {
 			return genBytesDef(data, t)
 		}
 		switch t.Kind() {
diff --git a/lib/vdl/codegen/golang/gen_enc.go b/lib/vdl/codegen/golang/gen_enc.go
index 9cf5e06..8f18bff 100644
--- a/lib/vdl/codegen/golang/gen_enc.go
+++ b/lib/vdl/codegen/golang/gen_enc.go
@@ -68,7 +68,11 @@
 		}
 
 	case vdl.Array, vdl.List:
-		if t.Elem().Kind() == vdl.Byte {
+		// Check for special-cases []byte and [N]byte, which can use FromBytes.
+		// Note that []X and [N]X cannot use this special-case, since Go doesn't
+		// allow conversion from []X to []byte, even if the underlying type of X is
+		// byte.
+		if t.Elem() == vdl.ByteType {
 			var arrayModifier string
 			if t.Kind() == vdl.Array {
 				arrayModifier = "[:]"
diff --git a/lib/vdl/codegen/golang/reader.go b/lib/vdl/codegen/golang/reader.go
index a6b1209..56f8305 100644
--- a/lib/vdl/codegen/golang/reader.go
+++ b/lib/vdl/codegen/golang/reader.go
@@ -130,7 +130,7 @@
 		// Appears before bytes, so that we use the defined method rather than
 		// re-generating extra code.
 		return g.bodyCallVDLRead(tt, arg)
-	case tt.IsBytes():
+	case tt.IsBytes() && tt.Elem() == vdl.ByteType:
 		// Bytes use the special Decoder.DecodeBytes method.  Appears before
 		// anonymous types, to avoid processing bytes as a list or array.
 		return sta + g.bodyBytes(tt, arg) + fin
@@ -148,11 +148,11 @@
 	case vdl.String:
 		return sta + g.bodyScalar(tt, vdl.StringType, arg, "String") + fin
 	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
-		return sta + g.bodyScalar(tt, vdl.Uint64Type, arg, "Uint", bitlen(kind)) + fin
+		return sta + g.bodyScalar(tt, vdl.Uint64Type, arg, "Uint", kind.BitLen()) + fin
 	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
-		return sta + g.bodyScalar(tt, vdl.Int64Type, arg, "Int", bitlen(kind)) + fin
+		return sta + g.bodyScalar(tt, vdl.Int64Type, arg, "Int", kind.BitLen()) + fin
 	case vdl.Float32, vdl.Float64:
-		return sta + g.bodyScalar(tt, vdl.Float64Type, arg, "Float", bitlen(kind)) + fin
+		return sta + g.bodyScalar(tt, vdl.Float64Type, arg, "Float", kind.BitLen()) + fin
 	case vdl.TypeObject:
 		return sta + g.bodyScalar(tt, vdl.TypeObjectType, arg, "TypeObject") + fin
 	case vdl.Enum:
@@ -180,11 +180,13 @@
 }
 
 func (g *genRead) bodyNative(tt *vdl.Type, arg namedArg) string {
+	wireArg := typedArg("wire", tt)
+	wireBody := g.bodyCallVDLRead(tt, wireArg)
 	return fmt.Sprintf(`
-	var wire %[1]s%[2]s
-	if err := %[1]sToNative(wire, %[3]s); err != nil {
+	var %[1]s %[2]s%[3]s
+	if err := %[2]sToNative(%[1]s, %[4]s); err != nil {
 		return err
-	}`, typeGoWire(g.goData, tt), g.bodyCallVDLRead(tt, typedArg("wire", tt)), arg.Ptr())
+	}`, wireArg.Name, typeGoWire(g.goData, tt), wireBody, arg.Ptr())
 }
 
 func (g *genRead) bodyCallVDLRead(tt *vdl.Type, arg namedArg) string {
@@ -292,7 +294,7 @@
 	return s
 }
 
-func (g *genRead) checkCompat(kind vdl.Kind, varName string) string {
+func (g *genRead) checkCompatible(kind vdl.Kind, varName string) string {
 	return fmt.Sprintf(`
 	if (dec.StackDepth() == 1 || dec.IsAny()) && !%[1]sCompatible(%[1]sTypeOf(%[4]s), dec.Type()) {
 		return %[2]sErrorf("incompatible %[3]s %%T, from %%v", %[4]s, dec.Type())
@@ -300,28 +302,29 @@
 }
 
 func (g *genRead) bodyArray(tt *vdl.Type, arg namedArg) string {
-	s := g.checkCompat(tt.Kind(), arg.Ref())
-	s += fmt.Sprintf(`
+	s := g.checkCompatible(tt.Kind(), arg.Ref())
+	elemArg := arg.ArrayIndex("index", tt.Elem())
+	elemBody := g.body(tt.Elem(), elemArg, false)
+	return s + fmt.Sprintf(`
 	index := 0
 	for {
 		switch done, err := dec.NextEntry(); {
 		case err != nil:
 			return err
-		case done != (index >= len(*x)):
+		case done != (index >= len(%[2]s)):
 			return %[1]sErrorf("array len mismatch, got %%d, want %%T", index, %[2]s)
 		case done:
 			return dec.FinishValue()
-		}`, g.Pkg("fmt"), arg.Ref())
-	elem := fmt.Sprintf(`%[1]s[index]`, arg.Name)
-	s += g.body(tt.Elem(), typedArg(elem, tt.Elem()), false)
-	return s + `
+		}%[3]s
 		index++
-	}`
+	}`, g.Pkg("fmt"), arg.Ref(), elemBody)
 }
 
 func (g *genRead) bodyList(tt *vdl.Type, arg namedArg) string {
-	s := g.checkCompat(tt.Kind(), arg.Ref())
-	s += fmt.Sprintf(`
+	s := g.checkCompatible(tt.Kind(), arg.Ref())
+	elemArg := typedArg("elem", tt.Elem())
+	elemBody := g.body(tt.Elem(), elemArg, false)
+	return s + fmt.Sprintf(`
 	switch len := dec.LenHint(); {
 	case len > 0:
 		%[1]s = make(%[2]s, 0, len)
@@ -335,51 +338,51 @@
 		case done:
 			return dec.FinishValue()
 		}
-		var elem %[3]s`, arg.Ref(), typeGo(g.goData, tt), typeGo(g.goData, tt.Elem()))
-	s += g.body(tt.Elem(), typedArg("elem", tt.Elem()), false)
-	return s + fmt.Sprintf(`
+		var elem %[3]s%[4]s
 		%[1]s = append(%[1]s, elem)
-	}`, arg.Ref())
+	}`, arg.Ref(), typeGo(g.goData, tt), typeGo(g.goData, tt.Elem()), elemBody)
 }
 
 func (g *genRead) bodySetMap(tt *vdl.Type, arg namedArg) string {
-	s := g.checkCompat(tt.Kind(), arg.Ref())
+	s := g.checkCompatible(tt.Kind(), arg.Ref())
+	keyArg := typedArg("key", tt.Key())
+	keyBody := g.body(tt.Key(), keyArg, false)
 	s += fmt.Sprintf(`
-	var tmpMap %[2]s
+	var tmpMap %[1]s
 	if len := dec.LenHint(); len > 0 {
-		tmpMap = make(%[2]s, len)
+		tmpMap = make(%[1]s, len)
   }
 	for {
 		switch done, err := dec.NextEntry(); {
 		case err != nil:
 			return err
 		case done:
-			%[1]s = tmpMap
+			%[2]s = tmpMap
 			return dec.FinishValue()
 		}
 		var key %[3]s
-		{`, arg.Ref(), typeGo(g.goData, tt), typeGo(g.goData, tt.Key()))
-	s += g.body(tt.Key(), typedArg("key", tt.Key()), false) + `
-		}`
-	elemVar := "struct{}{}"
+		{%[4]s
+		}`, typeGo(g.goData, tt), arg.Ref(), typeGo(g.goData, tt.Key()), keyBody)
+	elemValue := "struct{}{}"
 	if tt.Kind() == vdl.Map {
-		elemVar = "elem"
+		elemValue = "elem"
+		elemArg := typedArg("elem", tt.Elem())
+		elemBody := g.body(tt.Elem(), elemArg, false)
 		s += fmt.Sprintf(`
 		var elem %[1]s
-		{`, typeGo(g.goData, tt.Elem()))
-		s += g.body(tt.Elem(), typedArg("elem", tt.Elem()), false) + `
-		}`
+		{%[2]s
+		}`, typeGo(g.goData, tt.Elem()), elemBody)
 	}
 	return s + fmt.Sprintf(`
 		if tmpMap == nil {
 			tmpMap = make(%[1]s)
 		}
 		tmpMap[key] = %[2]s
-	}`, typeGo(g.goData, tt), elemVar)
+	}`, typeGo(g.goData, tt), elemValue)
 }
 
 func (g *genRead) bodyStruct(tt *vdl.Type, arg namedArg) string {
-	s := g.checkCompat(tt.Kind(), arg.Ref()) + `
+	s := g.checkCompatible(tt.Kind(), arg.Ref()) + `
 	for {
 		f, err := dec.NextField()
 		if err != nil {
@@ -390,9 +393,9 @@
 			return dec.FinishValue()`
 	for f := 0; f < tt.NumField(); f++ {
 		field := tt.Field(f)
+		fieldBody := g.body(field.Type, arg.Field(field), false)
 		s += fmt.Sprintf(`
-		case %[1]q:`, field.Name)
-		s += g.body(field.Type, arg.Field(field), false)
+		case %[1]q:%[2]s`, field.Name, fieldBody)
 	}
 	return s + `
 		default:
@@ -404,7 +407,7 @@
 }
 
 func (g *genRead) bodyUnion(tt *vdl.Type, arg namedArg) string {
-	s := g.checkCompat(tt.Kind(), arg.Ptr()) + `
+	s := g.checkCompatible(tt.Kind(), arg.Ptr()) + `
 	f, err := dec.NextField()
 	if err != nil {
 		return err
@@ -414,12 +417,12 @@
 		// TODO(toddw): Change to using pointers to the union field structs, to
 		// resolve https://v.io/i/455
 		field := tt.Field(f)
+		fieldArg := typedArg("field.Value", field.Type)
+		fieldBody := g.body(field.Type, fieldArg, false)
 		s += fmt.Sprintf(`
 	case %[1]q:
-		var field %[2]s%[1]s`, field.Name, typeGoWire(g.goData, tt))
-		s += g.body(field.Type, typedArg("field.Value", field.Type), false)
-		s += fmt.Sprintf(`
-		%[1]s = field`, arg.Ref())
+		var field %[2]s%[1]s%[3]s
+		%[4]s = field`, field.Name, typeGoWire(g.goData, tt), fieldBody, arg.Ref())
 	}
 	return s + fmt.Sprintf(`
 	case "":
@@ -437,19 +440,18 @@
 
 func (g *genRead) bodyOptional(tt *vdl.Type, arg namedArg) string {
 	// NOTE: arg.IsPtr is always true here, since tt is optional.
-	s := `
-	if dec.IsNil() {`
-	s += g.checkCompat(tt.Kind(), arg.Name)
-	s += fmt.Sprintf(`
-		%[1]s = nil
+	compat := g.checkCompatible(tt.Kind(), arg.Name)
+	body := g.body(tt.Elem(), arg, false)
+	return fmt.Sprintf(`
+	if dec.IsNil() {%[1]s
+		%[2]s = nil
 		if err := dec.FinishValue(); err != nil {
 			return err
 		}
 	} else {
-		%[1]s = new(%[2]s)
-		dec.IgnoreNextStartValue()`, arg.Name, typeGo(g.goData, tt.Elem()))
-	return s + g.body(tt.Elem(), arg, false) + `
-	}`
+		%[2]s = new(%[3]s)
+		dec.IgnoreNextStartValue()%[4]s
+	}`, compat, arg.Name, typeGo(g.goData, tt.Elem()), body)
 }
 
 func (g *genRead) bodyAny(tt *vdl.Type, arg namedArg) string {
@@ -470,61 +472,3 @@
 	}
 	return s + g.bodyCallVDLRead(tt, arg)
 }
-
-// namedArg represents a named argument, with methods to conveniently return the
-// pointer or non-pointer form of the argument.
-type namedArg struct {
-	Name  string // variable name
-	IsPtr bool   // is the variable a pointer type
-}
-
-func (arg namedArg) IsValid() bool {
-	return arg.Name != ""
-}
-
-func (arg namedArg) Ptr() string {
-	if arg.IsPtr {
-		return arg.Name
-	}
-	return "&" + arg.Name
-}
-
-func (arg namedArg) Ref() string {
-	if arg.IsPtr {
-		return "*" + arg.Name
-	}
-	return arg.Name
-}
-
-func (arg namedArg) SafeRef() string {
-	if arg.IsPtr {
-		return "(*" + arg.Name + ")"
-	}
-	return arg.Name
-}
-
-func (arg namedArg) Field(field vdl.Field) namedArg {
-	return typedArg(arg.Name+"."+field.Name, field.Type)
-}
-
-func (arg namedArg) Index(index string, tt *vdl.Type) namedArg {
-	return typedArg(arg.SafeRef()+"["+index+"]", tt)
-}
-
-func typedArg(name string, tt *vdl.Type) namedArg {
-	return namedArg{name, tt.Kind() == vdl.Optional}
-}
-
-func bitlen(k vdl.Kind) int {
-	switch k {
-	case vdl.Byte, vdl.Int8:
-		return 8
-	case vdl.Uint16, vdl.Int16:
-		return 16
-	case vdl.Uint32, vdl.Int32, vdl.Float32:
-		return 32
-	case vdl.Uint64, vdl.Int64, vdl.Float64:
-		return 64
-	}
-	panic(fmt.Errorf("bitlen kind %v not handled", k))
-}
diff --git a/lib/vdl/codegen/golang/writer.go b/lib/vdl/codegen/golang/writer.go
index db30ae2..0aaede6 100644
--- a/lib/vdl/codegen/golang/writer.go
+++ b/lib/vdl/codegen/golang/writer.go
@@ -122,7 +122,7 @@
 		// Appears before bytes, so that we use the defined method rather than
 		// re-generating extra code.
 		return g.bodyCallVDLWrite(tt, arg, skipNilCheck)
-	case tt.IsBytes():
+	case tt.IsBytes() && tt.Elem() == vdl.ByteType:
 		// Bytes use the special Encoder.EncodeBytes method.  Appears before
 		// anonymous types, to avoid processing bytes as a list or array.
 		return sta + g.bodyBytes(tt, arg) + fin
@@ -185,15 +185,14 @@
 	if err := %[1]sFromNative(&wire, %[2]s); err != nil {
 		return err
 	}`, typeGoWire(g.goData, tt), arg.Ref())
-	s += g.bodyCallVDLWrite(tt, typedArg("wire", tt), skipNilCheck)
-	return s
+	return s + g.bodyCallVDLWrite(tt, typedArg("wire", tt), skipNilCheck)
 }
 
 func (g *genWrite) bodyCallVDLWrite(tt *vdl.Type, arg namedArg, skipNilCheck bool) string {
 	s := fmt.Sprintf(`
 	if err := %[1]s.VDLWrite(enc); err != nil {
 		return err
-	}`, arg.SafeRef())
+	}`, arg.Name)
 	// Handle cases where a nil arg would cause the VDLWrite call to panic.  Here
 	// are the potential cases:
 	//   Optional:       Never happens; optional types already handled.
@@ -234,9 +233,9 @@
 	}`, g.anonWriterName(tt), arg.Ref())
 }
 
-func (g *genWrite) bodyScalar(tt *vdl.Type, exact *vdl.Type, arg namedArg, method string) string {
+func (g *genWrite) bodyScalar(tt, exact *vdl.Type, arg namedArg, method string) string {
 	param := arg.Ref()
-	if exact != tt {
+	if tt != exact {
 		param = typeGo(g.goData, exact) + "(" + arg.Ref() + ")"
 	}
 	return fmt.Sprintf(`
@@ -249,7 +248,7 @@
 
 func (g *genWrite) bodyBytes(tt *vdl.Type, arg namedArg) string {
 	if tt.Kind() == vdl.Array {
-		arg = arg.Index(":", ttBytes)
+		arg = arg.ArrayIndex(":", ttBytes)
 	}
 	return g.bodyScalar(tt, ttBytes, arg, "Bytes")
 }
@@ -258,7 +257,7 @@
 	return fmt.Sprintf(`
 	if err := enc.EncodeString(%[1]s.String()); err != nil {
 		return err
-	}`, arg.SafeRef())
+	}`, arg.Name)
 }
 
 const (
@@ -277,23 +276,25 @@
 )
 
 func (g *genWrite) bodyArray(tt *vdl.Type, arg namedArg) string {
+	elemArg := arg.ArrayIndex("i", tt.Elem())
 	s := fmt.Sprintf(`
 	for i := 0; i < %[1]d; i++ {`, tt.Len())
 	s += encNextEntry
-	s += g.body(tt.Elem(), arg.Index("i", tt.Elem()), namedArg{}, false, false)
+	s += g.body(tt.Elem(), elemArg, namedArg{}, false, false)
 	s += `
 	}` + encNextEntryDone
 	return s
 }
 
 func (g *genWrite) bodyList(tt *vdl.Type, arg namedArg) string {
+	elemArg := arg.Index("i", tt.Elem())
 	s := fmt.Sprintf(`
-	if err := enc.SetLenHint(len(%[1]v)); err != nil {
+	if err := enc.SetLenHint(len(%[1]s)); err != nil {
 		return err
 	}
-	for i := 0; i < len(%[1]v); i++ {`, arg.Ref())
+	for i := 0; i < len(%[1]s); i++ {`, arg.Ref())
 	s += encNextEntry
-	s += g.body(tt.Elem(), arg.Index("i", tt.Elem()), namedArg{}, false, false)
+	s += g.body(tt.Elem(), elemArg, namedArg{}, false, false)
 	s += `
 	}` + encNextEntryDone
 	return s
@@ -302,10 +303,10 @@
 func (g *genWrite) bodySet(tt *vdl.Type, arg namedArg) string {
 	keyArg := typedArg("key", tt.Key())
 	s := fmt.Sprintf(`
-	if err := enc.SetLenHint(len(%[2]v)); err != nil {
+	if err := enc.SetLenHint(len(%[1]s)); err != nil {
 		return err
 	}
-	for %[1]v := range %[2]v {`, keyArg.Ref(), arg.Ref())
+	for key := range %[1]s {`, arg.Ref())
 	s += encNextEntry
 	s += g.body(tt.Key(), keyArg, namedArg{}, false, false)
 	s += `
@@ -316,10 +317,10 @@
 func (g *genWrite) bodyMap(tt *vdl.Type, arg namedArg) string {
 	keyArg, elemArg := typedArg("key", tt.Key()), typedArg("elem", tt.Elem())
 	s := fmt.Sprintf(`
-	if err := enc.SetLenHint(len(%[3]v)); err != nil {
+	if err := enc.SetLenHint(len(%[1]s)); err != nil {
 		return err
 	}
-	for %[1]v, %[2]v := range %[3]v {`, keyArg.Ref(), elemArg.Ref(), arg.Ref())
+	for key, elem := range %[1]s {`, arg.Ref())
 	s += encNextEntry
 	s += g.body(tt.Key(), keyArg, namedArg{}, false, false)
 	s += g.body(tt.Elem(), elemArg, namedArg{}, false, false)
@@ -335,30 +336,30 @@
 		fieldArg := arg.Field(field)
 		zero := genIsZero{g.goData}
 		setup, expr, wireArg := zero.Expr(neZero, field.Type, fieldArg, field.Name, false)
-		s += fmt.Sprintf(`%[1]s
-	if %[2]s {
-		if err := enc.NextField(%[3]q); err != nil {
-			return err
-		}`, setup, expr, field.Name)
 		// The wireArg is valid iff the zero expression above already performed the
 		// native-to-wire conversion.  We use it to avoid performing another
 		// conversion when writing the field.  The true parameter after that
 		// indicates that nil checks can be skipped, since we've already ensured the
 		// field isn't zero here.
-		s += g.body(field.Type, fieldArg, wireArg, true, false)
-		s += `
-	}`
+		fieldBody := g.body(field.Type, fieldArg, wireArg, true, false)
+		s += fmt.Sprintf(`%[1]s
+	if %[2]s {
+		if err := enc.NextField(%[3]q); err != nil {
+			return err
+		}%[4]s
+	}`, setup, expr, field.Name, fieldBody)
 	}
 	s += encNextFieldDone
 	return s
 }
 
 func (g *genWrite) bodyUnion(field vdl.Field, arg namedArg) string {
+	fieldArg := typedArg(arg.Name+".Value", field.Type)
 	s := fmt.Sprintf(`
 	if err := enc.NextField(%[1]q); err != nil {
 			return err
 	}`, field.Name)
-	s += g.body(field.Type, typedArg(arg.Name+".Value", field.Type), namedArg{}, false, false)
+	s += g.body(field.Type, fieldArg, namedArg{}, false, false)
 	s += encNextFieldDone
 	return s
 }
@@ -402,6 +403,6 @@
 		if err := %[1]s.VDLWrite(enc); err != nil {
 			return err
 		}
-	}`, arg.SafeRef(), selector)
+	}`, arg.Name, selector)
 	return s
 }
diff --git a/lib/vdl/codegen/swift/util_namespace_test.go b/lib/vdl/codegen/swift/util_namespace_test.go
index 7066451..4cea37d 100644
--- a/lib/vdl/codegen/swift/util_namespace_test.go
+++ b/lib/vdl/codegen/swift/util_namespace_test.go
@@ -15,7 +15,7 @@
 	"v.io/x/lib/gosh"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 )
 
 const (
@@ -122,7 +122,7 @@
 	env := compile.NewEnv(-1)
 	genPathToDir := map[string]string{}
 	for _, pkg := range pkgs {
-		buildPkg := vdltest.FakeBuildPackage(pkg.Name, pkg.Path, pkg.Files)
+		buildPkg := vdltestutil.FakeBuildPackage(pkg.Name, pkg.Path, pkg.Files)
 		built[i] = build.BuildPackage(buildPkg, env)
 		built[i].GenPath = built[i].Path
 		genPathToDir[built[i].GenPath] = filepath.Join(vdlPath, pkg.Path)
diff --git a/lib/vdl/compile/compile_test.go b/lib/vdl/compile/compile_test.go
index f7e24a4..14a41c9 100644
--- a/lib/vdl/compile/compile_test.go
+++ b/lib/vdl/compile/compile_test.go
@@ -12,7 +12,7 @@
 	"v.io/v23/vdl"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 )
 
 type f map[string]string
@@ -29,10 +29,10 @@
 	}
 	for _, test := range tests {
 		path := path.Join("a/b", test.name)
-		buildPkg := vdltest.FakeBuildPackage(test.name, path, test.files)
+		buildPkg := vdltestutil.FakeBuildPackage(test.name, path, test.files)
 		env := compile.NewEnv(-1)
 		pkg := build.BuildPackage(buildPkg, env)
-		vdltest.ExpectResult(t, env.Errors, test.name, test.errRE)
+		vdltestutil.ExpectResult(t, env.Errors, test.name, test.errRE)
 		if pkg == nil {
 			continue
 		}
@@ -49,7 +49,7 @@
 func TestParseAndCompileExprs(t *testing.T) {
 	env := compile.NewEnv(-1)
 	path := path.Join("a/b/test1")
-	buildPkg := vdltest.FakeBuildPackage("test1", path, f{"1.vdl": pkg1file1, "2.vdl": pkg1file2})
+	buildPkg := vdltestutil.FakeBuildPackage("test1", path, f{"1.vdl": pkg1file1, "2.vdl": pkg1file2})
 	pkg := build.BuildPackage(buildPkg, env)
 	if pkg == nil {
 		t.Fatal("failed to build package")
diff --git a/lib/vdl/compile/const.go b/lib/vdl/compile/const.go
index dcfa7a5..89fda55 100644
--- a/lib/vdl/compile/const.go
+++ b/lib/vdl/compile/const.go
@@ -196,7 +196,10 @@
 	if !c.IsValid() {
 		return nil
 	}
-	if implicit != nil && c.Type() == nil {
+	if implicit != nil &&
+		(c.Type() == nil ||
+			(implicit.CanBeOptional() && vdl.OptionalType(implicit) == c.Type()) ||
+			(c.Type().CanBeOptional() && vdl.OptionalType(c.Type()) == implicit)) {
 		// Convert untyped const into the implicit type.
 		conv, err := c.Convert(implicit)
 		if err != nil {
diff --git a/lib/vdl/compile/const_test.go b/lib/vdl/compile/const_test.go
index 05d002c..f6ff947 100644
--- a/lib/vdl/compile/const_test.go
+++ b/lib/vdl/compile/const_test.go
@@ -12,7 +12,7 @@
 	"v.io/v23/vdl"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 )
 
 func testConstPackage(t *testing.T, name string, tpkg constPkg, env *compile.Env) *compile.Package {
@@ -22,9 +22,9 @@
 		tpkg.Name + ".vdl": "package " + tpkg.Name + "\n" + tpkg.Data,
 	}
 	pkgPath := "p.kg/" + tpkg.Name // use dots in pkgpath to test tricky cases
-	buildPkg := vdltest.FakeBuildPackage(tpkg.Name, pkgPath, files)
+	buildPkg := vdltestutil.FakeBuildPackage(tpkg.Name, pkgPath, files)
 	pkg := build.BuildPackage(buildPkg, env)
-	vdltest.ExpectResult(t, env.Errors, name, tpkg.ErrRE)
+	vdltestutil.ExpectResult(t, env.Errors, name, tpkg.ErrRE)
 	if pkg == nil || tpkg.ErrRE != "" {
 		return nil
 	}
@@ -55,7 +55,7 @@
 	fname := tpkg.Name + ".config"
 	data := "config = Res\n" + tpkg.Data
 	config := build.BuildConfig(fname, strings.NewReader(data), nil, nil, env)
-	vdltest.ExpectResult(t, env.Errors, name, tpkg.ErrRE)
+	vdltestutil.ExpectResult(t, env.Errors, name, tpkg.ErrRE)
 	if config == nil || tpkg.ErrRE != "" {
 		return
 	}
@@ -524,11 +524,11 @@
 		"OptionalCyclicExplicitType",
 		cp{{"a", `type A struct{X string;Z ?A}; const Res = A{"a",?A{"b",?A{"c",nil}}}`, makeCyclicStruct("a", makeCyclicStruct("b", makeCyclicStruct("c", nil))), ""}}},
 	{
+		"OptionalCyclicExplicitTypeAssignable",
+		cp{{"a", `type A struct{X string;Z ?A}; const Res = A{"a",A{}}`, makeCyclicStruct("a", makeCyclicStruct("", nil)), ""}}},
+	{
 		"OptionalCyclicTypeMismatch",
 		cp{{"a", `type A struct{X string;Z ?A}; const Res = A{"a","b"}`, nil, `can't convert "b" to \?p.kg/a.A`}}},
-	{
-		"OptionalCyclicExplicitTypeMismatch",
-		cp{{"a", `type A struct{X string;Z ?A}; const Res = A{"a",A{}}`, nil, `not assignable from p.kg/a.A`}}},
 
 	// Test enums.
 	{
diff --git a/lib/vdl/compile/error_test.go b/lib/vdl/compile/error_test.go
index 8aa9ea3..1dde86b 100644
--- a/lib/vdl/compile/error_test.go
+++ b/lib/vdl/compile/error_test.go
@@ -12,7 +12,7 @@
 	"v.io/v23/vdl"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 	"v.io/x/ref/lib/vdl/parse"
 )
 
@@ -30,9 +30,9 @@
 		files := map[string]string{
 			epkg.Name + ".vdl": "package " + epkg.Name + "\n" + epkg.Data,
 		}
-		buildPkg := vdltest.FakeBuildPackage(epkg.Name, epkg.Name, files)
+		buildPkg := vdltestutil.FakeBuildPackage(epkg.Name, epkg.Name, files)
 		pkg := build.BuildPackage(buildPkg, env)
-		vdltest.ExpectResult(t, env.Errors, test.Name, epkg.ErrRE)
+		vdltestutil.ExpectResult(t, env.Errors, test.Name, epkg.ErrRE)
 		if pkg == nil || epkg.ErrRE != "" {
 			continue
 		}
diff --git a/lib/vdl/compile/ident_test.go b/lib/vdl/compile/ident_test.go
index 4a61fe4..2ed55d0 100644
--- a/lib/vdl/compile/ident_test.go
+++ b/lib/vdl/compile/ident_test.go
@@ -9,7 +9,7 @@
 
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 )
 
 func TestIdentConflict(t *testing.T) {
@@ -50,10 +50,10 @@
 		files := map[string]string{
 			test.Name + ".vdl": "package a\n" + test.Data,
 		}
-		buildPkg := vdltest.FakeBuildPackage(test.Name, test.Name, files)
+		buildPkg := vdltestutil.FakeBuildPackage(test.Name, test.Name, files)
 		if pkg := build.BuildPackage(buildPkg, env); pkg != nil {
 			t.Errorf("%s got package, want nil", test.Name)
 		}
-		vdltest.ExpectResult(t, env.Errors, test.Name, "name conflict")
+		vdltestutil.ExpectResult(t, env.Errors, test.Name, "name conflict")
 	}
 }
diff --git a/lib/vdl/compile/interface_test.go b/lib/vdl/compile/interface_test.go
index 39be3a9..20753e5 100644
--- a/lib/vdl/compile/interface_test.go
+++ b/lib/vdl/compile/interface_test.go
@@ -11,7 +11,7 @@
 	"v.io/v23/vdl"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 	"v.io/x/ref/lib/vdl/parse"
 )
 
@@ -25,9 +25,9 @@
 				tpkg.Name + ".vdl": "package " + tpkg.Name + "\n" + tpkg.Data,
 			}
 			pkgPath := "p.kg/" + tpkg.Name // use dots in pkgpath to test tricky cases
-			buildPkg := vdltest.FakeBuildPackage(tpkg.Name, pkgPath, files)
+			buildPkg := vdltestutil.FakeBuildPackage(tpkg.Name, pkgPath, files)
 			pkg := build.BuildPackage(buildPkg, env)
-			vdltest.ExpectResult(t, env.Errors, test.Name, tpkg.ErrRE)
+			vdltestutil.ExpectResult(t, env.Errors, test.Name, tpkg.ErrRE)
 			if pkg == nil || tpkg.ErrRE != "" {
 				continue
 			}
diff --git a/lib/vdl/compile/type_test.go b/lib/vdl/compile/type_test.go
index e0e85f9..a0b17c9 100644
--- a/lib/vdl/compile/type_test.go
+++ b/lib/vdl/compile/type_test.go
@@ -10,7 +10,7 @@
 	"v.io/v23/vdl"
 	"v.io/x/ref/lib/vdl/build"
 	"v.io/x/ref/lib/vdl/compile"
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 )
 
 const qual = "package path qualified identifier"
@@ -28,7 +28,7 @@
 			tpkg.Name + ".vdl": "package " + tpkg.Name + "\n" + tpkg.Data,
 		}
 		pkgPath := "p.kg/" + tpkg.Name // use dots in pkgpath to test tricky cases
-		buildPkg := vdltest.FakeBuildPackage(tpkg.Name, pkgPath, files)
+		buildPkg := vdltestutil.FakeBuildPackage(tpkg.Name, pkgPath, files)
 		pkg := build.BuildPackage(buildPkg, env)
 		if tpkg.ErrRE == qual {
 			if qualifiedPaths {
@@ -37,7 +37,7 @@
 				tpkg.ExpectBase = nil // otherwise the test should fail
 			}
 		}
-		vdltest.ExpectResult(t, env.Errors, test.Name, tpkg.ErrRE)
+		vdltestutil.ExpectResult(t, env.Errors, test.Name, tpkg.ErrRE)
 		if pkg == nil || tpkg.ErrRE != "" {
 			continue
 		}
diff --git a/lib/vdl/internal/vdltest/vdltest.go b/lib/vdl/internal/vdltestutil/util.go
similarity index 95%
rename from lib/vdl/internal/vdltest/vdltest.go
rename to lib/vdl/internal/vdltestutil/util.go
index d190b29..2d40607 100644
--- a/lib/vdl/internal/vdltest/vdltest.go
+++ b/lib/vdl/internal/vdltestutil/util.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package vdltest provides testing utilities for v.io/x/ref/lib/vdl/...
-package vdltest
+// Package vdltestutil provides testing utilities for v.io/x/ref/lib/vdl/...
+package vdltestutil
 
 import (
 	"io"
diff --git a/lib/vdl/opconst/const.go b/lib/vdl/opconst/const.go
index d159a7a..7c045bf 100644
--- a/lib/vdl/opconst/const.go
+++ b/lib/vdl/opconst/const.go
@@ -23,7 +23,7 @@
 	bigRatAbsMax32 = new(big.Rat).SetFloat64(math.MaxFloat32)
 	bigRatAbsMin64 = new(big.Rat).SetFloat64(math.SmallestNonzeroFloat64)
 	bigRatAbsMax64 = new(big.Rat).SetFloat64(math.MaxFloat64)
-	maxShiftSize   = big.NewInt(463) // use the same max as Go
+	maxShiftSize   = big.NewInt(2000) // arbitrary large value
 
 	errInvalidConst = errors.New("invalid const")
 	errConvertNil   = errors.New("invalid conversion to untyped const")
diff --git a/lib/vdl/opconst/op.go b/lib/vdl/opconst/op.go
index bb55c41..35bdb8e 100644
--- a/lib/vdl/opconst/op.go
+++ b/lib/vdl/opconst/op.go
@@ -13,7 +13,7 @@
 const (
 	InvalidUnaryOp UnaryOp = iota
 	LogicNot               //  ! logical not
-	Pos                    //  + positive
+	Pos                    //  + positive (nop)
 	Neg                    //  - negate
 	BitNot                 //  ^ bitwise not
 )
diff --git a/lib/vdl/parse/parse_test.go b/lib/vdl/parse/parse_test.go
index eb2c844..3e9b503 100644
--- a/lib/vdl/parse/parse_test.go
+++ b/lib/vdl/parse/parse_test.go
@@ -10,7 +10,7 @@
 	"strings"
 	"testing"
 
-	"v.io/x/ref/lib/vdl/internal/vdltest"
+	"v.io/x/ref/lib/vdl/internal/vdltestutil"
 	"v.io/x/ref/lib/vdl/parse"
 	"v.io/x/ref/lib/vdl/vdlutil"
 )
@@ -49,17 +49,17 @@
 }
 
 // Tests of vdl imports and file parsing.
-type vdlTest struct {
+type vdlParseTest struct {
 	name   string
 	src    string
 	expect *parse.File
 	errors []string
 }
 
-func testParseVDL(t *testing.T, test vdlTest, opts parse.Opts) {
+func testParseVDL(t *testing.T, test vdlParseTest, opts parse.Opts) {
 	errs := vdlutil.NewErrors(-1)
 	actual := parse.ParseFile("testfile", strings.NewReader(test.src), opts, errs)
-	vdltest.ExpectResult(t, errs, test.name, test.errors...)
+	vdltestutil.ExpectResult(t, errs, test.name, test.errors...)
 	if !reflect.DeepEqual(test.expect, actual) {
 		t.Errorf("%v\nEXPECT %+v\nACTUAL %+v", test.name, test.expect, actual)
 	}
@@ -76,7 +76,7 @@
 		//
 		// The imports-only parser isn't supposed to fill in fields after the
 		// imports, so we clear them from the expected result.  We must copy the
-		// file to ensure the actual vdlTests isn't overwritten since the
+		// file to ensure the actual vdlFileTests isn't overwritten since the
 		// full-parser tests needs the full expectations.  The test itself doesn't
 		// need to be copied, since it's already copied in the range-for.
 		if test.expect != nil {
@@ -108,7 +108,7 @@
 func testParseConfig(t *testing.T, test configTest, opts parse.Opts) {
 	errs := vdlutil.NewErrors(-1)
 	actual := parse.ParseConfig("testfile", strings.NewReader(test.src), opts, errs)
-	vdltest.ExpectResult(t, errs, test.name, test.errors...)
+	vdltestutil.ExpectResult(t, errs, test.name, test.errors...)
 	if !reflect.DeepEqual(test.expect, actual) {
 		t.Errorf("%v\nEXPECT %+v\nACTUAL %+v", test.name, test.expect, actual)
 	}
@@ -142,7 +142,7 @@
 }
 
 // vdlImportsTests contains tests of stuff up to and including the imports.
-var vdlImportsTests = []vdlTest{
+var vdlImportsTests = []vdlParseTest{
 	// Empty file isn't allowed (need at least a package clause).
 	{
 		"FAILEmptyFile",
@@ -278,7 +278,7 @@
 }
 
 // vdlFileTests contains tests of stuff after the imports.
-var vdlFileTests = []vdlTest{
+var vdlFileTests = []vdlParseTest{
 	// Data type tests.
 	{
 		"TypeNamed",
@@ -1497,7 +1497,7 @@
 	for _, test := range tests {
 		errs := vdlutil.NewErrors(-1)
 		exprs := parse.ParseExprs(test.Data, errs)
-		vdltest.ExpectResult(t, errs, test.Data, test.Err)
+		vdltestutil.ExpectResult(t, errs, test.Data, test.Err)
 		if got, want := exprs, test.Exprs; !reflect.DeepEqual(got, want) {
 			t.Errorf("%s got %v, want %v", test.Data, got, want)
 		}
diff --git a/services/syncbase/server/server.vdl.go b/services/syncbase/server/server.vdl.go
index 0abaf1d..59283e0 100644
--- a/services/syncbase/server/server.vdl.go
+++ b/services/syncbase/server/server.vdl.go
@@ -725,7 +725,7 @@
 			return err
 		}
 		enc.SetNextStartValueIsOptional()
-		if err := (*x.SchemaMetadata).VDLWrite(enc); err != nil {
+		if err := x.SchemaMetadata.VDLWrite(enc); err != nil {
 			return err
 		}
 	}
diff --git a/services/syncbase/vsync/testdata/blobtestsvdl.vdl.go b/services/syncbase/vsync/testdata/blobtestsvdl.vdl.go
index e345052..39d3cf3 100644
--- a/services/syncbase/vsync/testdata/blobtestsvdl.vdl.go
+++ b/services/syncbase/vsync/testdata/blobtestsvdl.vdl.go
@@ -1545,7 +1545,7 @@
 			return err
 		}
 		enc.SetNextStartValueIsOptional()
-		if err := (*x.Bo).VDLWrite(enc); err != nil {
+		if err := x.Bo.VDLWrite(enc); err != nil {
 			return err
 		}
 	}