From: Robert Griesemer Date: Wed, 31 Jul 2024 16:59:28 +0000 (-0700) Subject: go/types, types2: factor out typechecker-specific code from recording.go X-Git-Tag: go1.24rc1~1314 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1b6bb779ef92de489a51b177035362795636624b;p=gostls13.git go/types, types2: factor out typechecker-specific code from recording.go With this CL, the go/types and types2 recording.go files are mostly identical except for the use of different syntax trees. Preparation for generating go/types/recording.go from types2 sources. Change-Id: Iea85f8554ee04f1e1f7da63f8019725ac8f6caf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/602117 Reviewed-by: Tim King Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/compile/internal/types2/check.go b/src/cmd/compile/internal/types2/check.go index f344142011..cd1b2d513c 100644 --- a/src/cmd/compile/internal/types2/check.go +++ b/src/cmd/compile/internal/types2/check.go @@ -514,3 +514,80 @@ func (check *Checker) cleanup() { } 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)) +} diff --git a/src/cmd/compile/internal/types2/recording.go b/src/cmd/compile/internal/types2/recording.go index cdd38ddb11..7badd022b1 100644 --- a/src/cmd/compile/internal/types2/recording.go +++ b/src/cmd/compile/internal/types2/recording.go @@ -68,35 +68,7 @@ func (check *Checker) recordTypeAndValue(x syntax.Expr, mode operandMode, typ Ty 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) { @@ -145,25 +117,7 @@ func (check *Checker) recordCommaOkTypes(x syntax.Expr, a []*operand) { 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 @@ -181,23 +135,6 @@ func (check *Checker) recordInstance(expr syntax.Expr, targs []Type, typ Type) { } } -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 { diff --git a/src/go/types/check.go b/src/go/types/check.go index a31e049c71..2d56b0f75c 100644 --- a/src/go/types/check.go +++ b/src/go/types/check.go @@ -535,3 +535,38 @@ func (check *Checker) cleanup() { } 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)) +} diff --git a/src/go/types/recording.go b/src/go/types/recording.go index aae2b20d27..fa73835983 100644 --- a/src/go/types/recording.go +++ b/src/go/types/recording.go @@ -10,8 +10,6 @@ package types import ( "go/ast" "go/constant" - "go/token" - "strings" ) func (check *Checker) record(x *operand) { @@ -42,7 +40,7 @@ func (check *Checker) record(x *operand) { } func (check *Checker) recordUntyped() { - if !debug && check.Types == nil { + if !debug && !check.recordTypes() { return // nothing to do } @@ -70,6 +68,7 @@ func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, 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) { @@ -118,6 +117,7 @@ func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) { x = p.X } } + check.recordCommaOkTypesInSyntax(x, t0, t1) } // recordInstance records instantiation information into check.Info, if the @@ -135,30 +135,6 @@ func (check *Checker) recordInstance(expr ast.Expr, targs []Type, typ Type) { } } -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 {