diff --git a/compiler/expressions.go b/compiler/expressions.go index 1d86174ce..fa71a4912 100644 --- a/compiler/expressions.go +++ b/compiler/expressions.go @@ -768,6 +768,9 @@ func (fc *funcContext) translateExpr(expr ast.Expr) *expression { if typesutil.IsJsObject(exprType) { return fc.formatExpr("null") } + if typesutil.IsGeneric(exprType) { + return fc.formatExpr("%s.zero()", fc.typeName(exprType)) + } switch t := exprType.Underlying().(type) { case *types.Basic: if t.Kind() != types.UnsafePointer { diff --git a/compiler/package.go b/compiler/package.go index 7838e8eb3..af72e9c86 100644 --- a/compiler/package.go +++ b/compiler/package.go @@ -531,7 +531,7 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor d.DeclCode = funcCtx.CatchOutput(0, func() { typeName := funcCtx.objectName(o) lhs := typeName - if typeVarLevel(o) == varPackage { + if getVarLevel(o) == varPackage { lhs += " = $pkg." + encodeIdent(o.Name()) } size := int64(0) diff --git a/compiler/utils.go b/compiler/utils.go index 51cd85773..fd724b0f8 100644 --- a/compiler/utils.go +++ b/compiler/utils.go @@ -368,8 +368,17 @@ func isVarOrConst(o types.Object) bool { return false } -func typeVarLevel(o types.Object) varLevel { - if _, ok := o.Type().(*types.TypeParam); ok { +func isTypeParameterName(o types.Object) bool { + _, isTypeName := o.(*types.TypeName) + _, isTypeParam := o.Type().(*types.TypeParam) + return isTypeName && isTypeParam +} + +// getVarLevel returns at which level a JavaScript variable for the given object +// should be defined. The object can represent any named Go object: variable, +// type, function, etc. +func getVarLevel(o types.Object) varLevel { + if isTypeParameterName(o) { return varGenericFactory } if o.Parent() != nil && o.Parent().Parent() == types.Universe { @@ -381,7 +390,7 @@ func typeVarLevel(o types.Object) varLevel { // objectName returns a JS identifier corresponding to the given types.Object. // Repeated calls for the same object will return the same name. func (fc *funcContext) objectName(o types.Object) string { - if typeVarLevel(o) == varPackage { + if getVarLevel(o) == varPackage { fc.pkgCtx.dependencies[o] = true if o.Pkg() != fc.pkgCtx.Pkg || (isVarOrConst(o) && o.Exported()) { @@ -391,7 +400,7 @@ func (fc *funcContext) objectName(o types.Object) string { name, ok := fc.pkgCtx.objectNames[o] if !ok { - name = fc.newVariable(o.Name(), typeVarLevel(o)) + name = fc.newVariable(o.Name(), getVarLevel(o)) fc.pkgCtx.objectNames[o] = name } @@ -402,13 +411,13 @@ func (fc *funcContext) objectName(o types.Object) string { } func (fc *funcContext) varPtrName(o *types.Var) string { - if typeVarLevel(o) == varPackage && o.Exported() { + if getVarLevel(o) == varPackage && o.Exported() { return fc.pkgVar(o.Pkg()) + "." + o.Name() + "$ptr" } name, ok := fc.pkgCtx.varPtrNames[o] if !ok { - name = fc.newVariable(o.Name()+"$ptr", typeVarLevel(o)) + name = fc.newVariable(o.Name()+"$ptr", getVarLevel(o)) fc.pkgCtx.varPtrNames[o] = name } return name diff --git a/tests/gorepo/run.go b/tests/gorepo/run.go index 3308ea5df..1ead4216e 100644 --- a/tests/gorepo/run.go +++ b/tests/gorepo/run.go @@ -700,7 +700,7 @@ func (t *test) run() { supportedArgs := []string{} for _, a := range args { switch a { - case "-gcflags=-G=3": + case "-gcflags=-G=3", `-gcflags="-G=3"`: continue default: supportedArgs = append(supportedArgs, a)