}
check.cleaners = nil
}
+
+// types2-specific support for recording type information in the syntax tree.
+func (check *Checker) recordTypeAndValueInSyntax(x syntax.Expr, mode operandMode, typ Type, val constant.Value) {
+ if check.StoreTypesInSyntax {
+ tv := TypeAndValue{mode, typ, val}
+ stv := syntax.TypeAndValue{Type: typ, Value: val}
+ if tv.IsVoid() {
+ stv.SetIsVoid()
+ }
+ if tv.IsType() {
+ stv.SetIsType()
+ }
+ if tv.IsBuiltin() {
+ stv.SetIsBuiltin()
+ }
+ if tv.IsValue() {
+ stv.SetIsValue()
+ }
+ if tv.IsNil() {
+ stv.SetIsNil()
+ }
+ if tv.Addressable() {
+ stv.SetAddressable()
+ }
+ if tv.Assignable() {
+ stv.SetAssignable()
+ }
+ if tv.HasOk() {
+ stv.SetHasOk()
+ }
+ x.SetTypeInfo(stv)
+ }
+}
+
+// types2-specific support for recording type information in the syntax tree.
+func (check *Checker) recordCommaOkTypesInSyntax(x syntax.Expr, t0, t1 Type) {
+ if check.StoreTypesInSyntax {
+ // Note: this loop is duplicated because the type of tv is different.
+ // Above it is types2.TypeAndValue, here it is syntax.TypeAndValue.
+ for {
+ tv := x.GetTypeInfo()
+ assert(tv.Type != nil) // should have been recorded already
+ pos := x.Pos()
+ tv.Type = NewTuple(
+ NewVar(pos, check.pkg, "", t0),
+ NewVar(pos, check.pkg, "", t1),
+ )
+ x.SetTypeInfo(tv)
+ p, _ := x.(*syntax.ParenExpr)
+ if p == nil {
+ break
+ }
+ x = p.X
+ }
+ }
+}
+
+// instantiatedIdent determines the identifier of the type instantiated in expr.
+// Helper function for recordInstance in recording.go.
+func instantiatedIdent(expr syntax.Expr) *syntax.Name {
+ var selOrIdent syntax.Expr
+ switch e := expr.(type) {
+ case *syntax.IndexExpr:
+ selOrIdent = e.X
+ case *syntax.SelectorExpr, *syntax.Name:
+ selOrIdent = e
+ }
+ switch x := selOrIdent.(type) {
+ case *syntax.Name:
+ return x
+ case *syntax.SelectorExpr:
+ return x.Sel
+ }
+
+ // extra debugging of go.dev/issue/63933
+ panic(sprintf(nil, true, "instantiated ident not found; please report: %s", expr))
+}
if m := check.Types; m != nil {
m[x] = TypeAndValue{mode, typ, val}
}
- if check.StoreTypesInSyntax {
- tv := TypeAndValue{mode, typ, val}
- stv := syntax.TypeAndValue{Type: typ, Value: val}
- if tv.IsVoid() {
- stv.SetIsVoid()
- }
- if tv.IsType() {
- stv.SetIsType()
- }
- if tv.IsBuiltin() {
- stv.SetIsBuiltin()
- }
- if tv.IsValue() {
- stv.SetIsValue()
- }
- if tv.IsNil() {
- stv.SetIsNil()
- }
- if tv.Addressable() {
- stv.SetAddressable()
- }
- if tv.Assignable() {
- stv.SetAssignable()
- }
- if tv.HasOk() {
- stv.SetHasOk()
- }
- x.SetTypeInfo(stv)
- }
+ check.recordTypeAndValueInSyntax(x, mode, typ, val)
}
func (check *Checker) recordBuiltinType(f syntax.Expr, sig *Signature) {
x = p.X
}
}
- if check.StoreTypesInSyntax {
- // Note: this loop is duplicated because the type of tv is different.
- // Above it is types2.TypeAndValue, here it is syntax.TypeAndValue.
- for {
- tv := x.GetTypeInfo()
- assert(tv.Type != nil) // should have been recorded already
- pos := x.Pos()
- tv.Type = NewTuple(
- NewVar(pos, check.pkg, "", t0),
- NewVar(pos, check.pkg, "", t1),
- )
- x.SetTypeInfo(tv)
- p, _ := x.(*syntax.ParenExpr)
- if p == nil {
- break
- }
- x = p.X
- }
- }
+ check.recordCommaOkTypesInSyntax(x, t0, t1)
}
// recordInstance records instantiation information into check.Info, if the
}
}
-func instantiatedIdent(expr syntax.Expr) *syntax.Name {
- var selOrIdent syntax.Expr
- switch e := expr.(type) {
- case *syntax.IndexExpr:
- selOrIdent = e.X
- case *syntax.SelectorExpr, *syntax.Name:
- selOrIdent = e
- }
- switch x := selOrIdent.(type) {
- case *syntax.Name:
- return x
- case *syntax.SelectorExpr:
- return x.Sel
- }
- panic("instantiated ident not found")
-}
-
func (check *Checker) recordDef(id *syntax.Name, obj Object) {
assert(id != nil)
if m := check.Defs; m != nil {
}
check.cleaners = nil
}
+
+// go/types doesn't support recording of types directly in the AST.
+// dummy function to match types2 code.
+func (check *Checker) recordTypeAndValueInSyntax(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
+ // nothing to do
+}
+
+// go/types doesn't support recording of types directly in the AST.
+// dummy function to match types2 code.
+func (check *Checker) recordCommaOkTypesInSyntax(x ast.Expr, t0, t1 Type) {
+ // nothing to do
+}
+
+// instantiatedIdent determines the identifier of the type instantiated in expr.
+// Helper function for recordInstance in recording.go.
+func instantiatedIdent(expr ast.Expr) *ast.Ident {
+ var selOrIdent ast.Expr
+ switch e := expr.(type) {
+ case *ast.IndexExpr:
+ selOrIdent = e.X
+ case *ast.IndexListExpr: // only exists in go/ast, not syntax
+ selOrIdent = e.X
+ case *ast.SelectorExpr, *ast.Ident:
+ selOrIdent = e
+ }
+ switch x := selOrIdent.(type) {
+ case *ast.Ident:
+ return x
+ case *ast.SelectorExpr:
+ return x.Sel
+ }
+
+ // extra debugging of go.dev/issue/63933
+ panic(sprintf(nil, nil, true, "instantiated ident not found; please report: %s", expr))
+}
import (
"go/ast"
"go/constant"
- "go/token"
- "strings"
)
func (check *Checker) record(x *operand) {
}
func (check *Checker) recordUntyped() {
- if !debug && check.Types == nil {
+ if !debug && !check.recordTypes() {
return // nothing to do
}
if m := check.Types; m != nil {
m[x] = TypeAndValue{mode, typ, val}
}
+ check.recordTypeAndValueInSyntax(x, mode, typ, val)
}
func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
x = p.X
}
}
+ check.recordCommaOkTypesInSyntax(x, t0, t1)
}
// recordInstance records instantiation information into check.Info, if the
}
}
-func instantiatedIdent(expr ast.Expr) *ast.Ident {
- var selOrIdent ast.Expr
- switch e := expr.(type) {
- case *ast.IndexExpr:
- selOrIdent = e.X
- case *ast.IndexListExpr:
- selOrIdent = e.X
- case *ast.SelectorExpr, *ast.Ident:
- selOrIdent = e
- }
- switch x := selOrIdent.(type) {
- case *ast.Ident:
- return x
- case *ast.SelectorExpr:
- return x.Sel
- }
-
- // extra debugging of #63933
- var buf strings.Builder
- buf.WriteString("instantiated ident not found; please report: ")
- ast.Fprint(&buf, token.NewFileSet(), expr, ast.NotNilFilter)
- panic(buf.String())
-}
-
func (check *Checker) recordDef(id *ast.Ident, obj Object) {
assert(id != nil)
if m := check.Defs; m != nil {