// print symbol with Vargen number or not as desired
name := s.Name
if strings.Contains(name, ".") {
- panic("invalid symbol name: " + name)
+ Fatalf("invalid symbol name: %s", name)
}
// Functions that can be inlined use numbered parameters so we can distingish them
// but instead of emitting the information textually, emit the node tree in
// binary form.
+// TODO(gri) Improve tracing output. The current format is difficult to read.
+
// stmtList may emit more (or fewer) than len(list) nodes.
func (p *exporter) stmtList(list Nodes) {
if p.trace {
defer p.tracef(") ")
}
+ // from nodefmt (fmt.go)
+ //
+ // nodefmt reverts nodes back to their original - we don't need to do
+ // it because we are not bound to produce valid Go syntax when exporting
+ //
+ // if (fmtmode != FExp || n.Op != OLITERAL) && n.Orig != nil {
+ // n = n.Orig
+ // }
+
+ // from exprfmt (fmt.go)
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
n = n.Left
}
p.typ(n.Type)
}
- case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
- panic("unreachable") // should have been resolved by typechecking
+ // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
+ // should have been resolved by typechecking - handled by default case
// case OCLOSURE:
// unimplemented - handled by default case
// case OCOMPLIT:
- // unimplemented - handled by default case
+ // should have been resolved by typechecking - handled by default case
case OPTRLIT:
p.op(OPTRLIT)
case OSTRUCTLIT:
p.op(OSTRUCTLIT)
- if !p.bool(n.Implicit) {
- p.typ(n.Type)
- }
+ p.typ(n.Type)
p.elemList(n.List) // special handling of field names
case OARRAYLIT, OMAPLIT:
- p.op(op)
- if !p.bool(n.Implicit) {
- p.typ(n.Type)
- }
+ p.op(OCOMPLIT)
+ p.typ(n.Type)
p.exprList(n.List)
case OKEY:
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
p.op(OXDOT)
p.expr(n.Left)
- if n.Sym == nil {
- panic("unreachable") // can this happen during export?
- }
p.fieldSym(n.Sym, true)
case ODOTTYPE, ODOTTYPE2:
p.op(ODCLCONST)
default:
- Fatalf("exporter: CANNOT EXPORT: %s\nPlease notify gri@\n", n.Op)
+ Fatalf("cannot export %s (%d) node\n"+
+ "==> please file an issue and assign to gri@\n", n.Op, n.Op)
}
}
p.op(ORETURN)
p.exprList(n.List)
- case ORETJMP:
- // generated by compiler for trampolin routines - not exported
- panic("unreachable")
+ // case ORETJMP:
+ // unreachable - generated by compiler for trampolin routines
case OPROC, ODEFER:
p.op(op)
p.exprsOrNil(n.Left, nil)
case OEMPTY:
- // nothing to emit
+ // nothing to emit
case OLABEL:
p.op(OLABEL)
// an empty path denotes the package we are currently importing;
// it must be the first package we see
if (path == "") != (len(p.pkgList) == 0) {
- panic(fmt.Sprintf("package path %q for pkg index %d", path, len(p.pkgList)))
+ Fatalf("importer: package path %q for pkg index %d", path, len(p.pkgList))
}
pkg := importpkg
// case OCLOSURE:
// unimplemented
- // case OCOMPLIT:
- // unimplemented
-
case OPTRLIT:
n := p.expr()
- if !p.bool() /* !implicit, i.e. '&' operator*/ {
+ if !p.bool() /* !implicit, i.e. '&' operator */ {
if n.Op == OCOMPLIT {
// Special case for &T{...}: turn into (*T){...}.
n.Right = Nod(OIND, n.Right, nil)
return n
case OSTRUCTLIT:
- n := Nod(OCOMPLIT, nil, nil)
- if !p.bool() {
- n.Right = typenod(p.typ())
- }
- n.List.Set(p.elemList())
+ n := Nod(OCOMPLIT, nil, typenod(p.typ()))
+ n.List.Set(p.elemList()) // special handling of field names
return n
- case OARRAYLIT, OMAPLIT:
- n := Nod(OCOMPLIT, nil, nil)
- if !p.bool() {
- n.Right = typenod(p.typ())
- }
+ // case OARRAYLIT, OMAPLIT:
+ // unreachable - mapped to case OCOMPLIT below by exporter
+
+ case OCOMPLIT:
+ n := Nod(OCOMPLIT, nil, typenod(p.typ()))
n.List.Set(p.exprList())
return n
return nil
default:
- Fatalf("importer: %s (%d) node not yet supported", op, op)
+ Fatalf("cannot import %s (%d) node\n"+
+ "==> please file an issue and assign to gri@\n", op, op)
panic("unreachable") // satisfy compiler
}
}
--- /dev/null
+// Copyright 2016 The Go 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 a
+
+type T struct {
+}
+
+func F() []T {
+ return []T{T{}}
+}
+
+func Fi() []T {
+ return []T{{}} // element with implicit composite literal type
+}
+
+func Fp() []*T {
+ return []*T{&T{}}
+}
+
+func Fip() []*T {
+ return []*T{{}} // element with implicit composite literal type
+}
+
+func Gp() map[int]*T {
+ return map[int]*T{0: &T{}}
+}
+
+func Gip() map[int]*T {
+ return map[int]*T{0: {}} // element with implicit composite literal type
+}
+
+func Hp() map[*T]int {
+ return map[*T]int{&T{}: 0}
+}
+
+func Hip() map[*T]int {
+ return map[*T]int{{}: 0} // key with implicit composite literal type
+}
--- /dev/null
+// Copyright 2016 The Go 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 b
+
+import "./a"
+
+func F() {
+ a.F()
+ a.Fi()
+}
+
+func Fp() {
+ a.Fp()
+ a.Fip()
+}
+
+func Gp() {
+ a.Gp()
+ a.Gip()
+}
+
+func Hp() {
+ a.Hp()
+ a.Hip()
+}
--- /dev/null
+// compiledir
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that exporting composite literals with implicit
+// types doesn't crash the typechecker when running over
+// inlined function bodies containing such literals.
+
+package ignored