| 1065 | } |
| 1066 | |
| 1067 | func (r *reader) expr0() (res Value) { |
| 1068 | b := r.b |
| 1069 | e := r.exprTODO() |
| 1070 | tv := b.info.Types[e] |
| 1071 | |
| 1072 | switch e := e.(type) { |
| 1073 | case *BasicLit: |
| 1074 | panic("non-constant BasicLit") // unreachable |
| 1075 | |
| 1076 | case *FuncLit: |
| 1077 | obj := r.obj().(*Func) |
| 1078 | fn2 := &Function{ |
| 1079 | name: fmt.Sprintf("%s$%d", b.Fn.Name(), 1+len(b.Fn.AnonFuncs)), |
| 1080 | object: obj, |
| 1081 | Signature: obj.Type().(*Signature), |
| 1082 | parent: b.Fn, |
| 1083 | Pkg: b.Fn.Pkg, |
| 1084 | } |
| 1085 | b.Fn.AnonFuncs = append(b.Fn.AnonFuncs, fn2) |
| 1086 | b.Prog.buildFunction(b.info, fn2) |
| 1087 | if fn2.FreeVars == nil { |
| 1088 | return fn2 |
| 1089 | } |
| 1090 | v := &MakeClosure{Fn: fn2} |
| 1091 | v.setType(obj.Type()) |
| 1092 | for _, fv := range fn2.FreeVars { |
| 1093 | outer := b.lookup(fv.object, true) // escaping |
| 1094 | v.Bindings = append(v.Bindings, outer) |
| 1095 | } |
| 1096 | return b.emit(v) |
| 1097 | |
| 1098 | case *AssertExpr: |
| 1099 | x, pos, typ := r.expr(), r.pos(), r.typ() |
| 1100 | return b.emitTypeAssert(x, typ, pos) |
| 1101 | |
| 1102 | case *CallExpr: |
| 1103 | if r.bool() { |
| 1104 | // Explicit type conversion, e.g. string(x) or big.Int(x) |
| 1105 | typ := r.typ() |
| 1106 | pos := r.pos() |
| 1107 | x := r.expr() |
| 1108 | y := b.emitConv(x, typ) |
| 1109 | |
| 1110 | if y != x { |
| 1111 | switch y := y.(type) { |
| 1112 | default: |
| 1113 | panic(fmt.Errorf("%s: unexpected conversion: %T", e.Pos(), y)) |
| 1114 | case *SSAConst: |
| 1115 | // ok; doesn't track position |
| 1116 | case *Convert: |
| 1117 | y.pos = pos |
| 1118 | case *ChangeInterface: |
| 1119 | if !b.golden("x/tools/go/ssa is missing this case") { |
| 1120 | y.pos = pos |
| 1121 | } |
| 1122 | case *ChangeType: |
| 1123 | y.pos = pos |
| 1124 | case *MakeInterface: |