func (n *ConstExpr) rawCopy() Node                 { c := *n; return &c }
 func (n *ConstExpr) Sym() *types.Sym               { return n.orig.Sym() }
 func (n *ConstExpr) Orig() Node                    { return n.orig }
-func (n *ConstExpr) SetOrig(orig Node)             { n.orig = orig }
+func (n *ConstExpr) SetOrig(orig Node)             { panic(n.no("SetOrig")) }
 func (n *ConstExpr) Val() constant.Value           { return n.val }
 
 // A ConvExpr is a conversion Type(X).
 func (n *ConvExpr) String() string                { return fmt.Sprint(n) }
 func (n *ConvExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
 func (n *ConvExpr) rawCopy() Node                 { c := *n; return &c }
-func (n *ConvExpr) Orig() Node                    { return n.orig }
-func (n *ConvExpr) SetOrig(x Node)                { n.orig = x }
 func (n *ConvExpr) Left() Node                    { return n.X }
 func (n *ConvExpr) SetLeft(x Node)                { n.X = x }
 
 
        OCALL:          8,
        OCAP:           8,
        OCLOSE:         8,
+       OCOMPLIT:       8,
        OCONVIFACE:     8,
        OCONVNOP:       8,
        OCONV:          8,
 }
 
 func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
-       for n != nil && n.Implicit() && (n.Op() == ODEREF || n.Op() == OADDR) {
-               n = n.Left()
-       }
+       for {
+               if n == nil {
+                       fmt.Fprint(s, "<N>")
+                       return
+               }
 
-       if n == nil {
-               fmt.Fprint(s, "<N>")
-               return
+               // We always want the original, if any.
+               if o := Orig(n); o != n {
+                       n = o
+                       continue
+               }
+
+               // Skip implicit operations introduced during typechecking.
+               switch n.Op() {
+               case OADDR, ODEREF, OCONV, OCONVNOP, OCONVIFACE:
+                       if n.Implicit() {
+                               n = n.Left()
+                               continue
+                       }
+               }
+
+               break
        }
 
        nprec := OpPrec[n.Op()]
                fmt.Fprint(s, "nil")
 
        case OLITERAL: // this is a bit of a mess
-               if mode == FErr {
-                       if orig := Orig(n); orig != nil && orig != n {
-                               exprFmt(orig, s, prec, mode)
-                               return
-                       }
-                       if n.Sym() != nil {
-                               fmt.Fprint(s, smodeString(n.Sym(), mode))
-                               return
-                       }
+               if mode == FErr && n.Sym() != nil {
+                       fmt.Fprint(s, smodeString(n.Sym(), mode))
+                       return
                }
 
                needUnparen := false
 
 func nodeFmt(n Node, s fmt.State, flag FmtFlag, mode FmtMode) {
        t := n.Type()
-
-       // We almost always want the original.
-       // TODO(gri) Why the special case for OLITERAL?
-       if n.Op() != OLITERAL && Orig(n) != nil {
-               n = Orig(n)
-       }
-
        if flag&FmtLong != 0 && t != nil {
                if t.Kind() == types.TNIL {
                        fmt.Fprint(s, "nil")
 
 func (n *Name) Name() *Name                   { return n }
 func (n *Name) Sym() *types.Sym               { return n.sym }
 func (n *Name) SetSym(x *types.Sym)           { n.sym = x }
-func (n *Name) Orig() Node                    { return n.orig }
-func (n *Name) SetOrig(x Node)                { n.orig = x }
 func (n *Name) SubOp() Op                     { return n.subOp }
 func (n *Name) SetSubOp(x Op)                 { n.subOp = x }
 func (n *Name) Class() Class                  { return n.class }