]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types: always record a type for inner composite literals
authorRobert Griesemer <gri@golang.org>
Wed, 2 Oct 2024 00:04:51 +0000 (17:04 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 2 Oct 2024 20:14:11 +0000 (20:14 +0000)
Ensure that inner composite literals get a (possibly invalid) type
if something goes wrong with the enclosing composite literal.

Fixes #69092.

Change-Id: Ib1d2d529c4683ea3ab1799a818b43538e152ae8e
Reviewed-on: https://go-review.googlesource.com/c/go/+/616616
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
src/cmd/compile/internal/types2/issues_test.go
src/cmd/compile/internal/types2/literals.go
src/go/types/issues_test.go
src/go/types/literals.go

index b339def7354e28b319c70452516492e6d938c78f..86b0a24e5195e8b7ea8a70a61d6f35bbe856b38c 100644 (file)
@@ -1141,3 +1141,29 @@ type (
                t.Errorf("got %s, want %s", got, want)
        }
 }
+
+func TestIssue69092(t *testing.T) {
+       const src = `
+package p
+
+var _ = T{{x}}
+`
+
+       file := mustParse(src)
+       conf := Config{Error: func(err error) {}} // ignore errors
+       info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
+       conf.Check("p", []*syntax.File{file}, &info)
+
+       // look for {x} expression
+       outer := file.DeclList[0].(*syntax.VarDecl).Values.(*syntax.CompositeLit) // T{{x}}
+       inner := outer.ElemList[0]                                                // {x}
+
+       // type of {x} must have been recorded
+       tv, ok := info.Types[inner]
+       if !ok {
+               t.Fatal("no type found for {x}")
+       }
+       if tv.Type != Typ[Invalid] {
+               t.Fatalf("unexpected type for {x}: %s", tv.Type)
+       }
+}
index b4fa9d9ee791ff02af73a200be4bea5723f391b6..b81d51564ca00b4bd211695849d8a17aebfaf23a 100644 (file)
@@ -137,8 +137,9 @@ func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type
        default:
                // TODO(gri) provide better error messages depending on context
                check.error(e, UntypedLit, "missing type in composite literal")
-               x.mode = invalid
-               return
+               // continue with invalid type so that elements are "used" (go.dev/issue/69092)
+               typ = Typ[Invalid]
+               base = typ
        }
 
        switch utyp := coreType(base).(type) {
index da0c0c1255b63ef4b084f6bb69d8970784f6b48c..9fc650df7cdd259a3de81329b71a22aad0d23e44 100644 (file)
@@ -1151,3 +1151,30 @@ type (
                t.Errorf("got %s, want %s", got, want)
        }
 }
+
+func TestIssue69092(t *testing.T) {
+       const src = `
+package p
+
+var _ = T{{x}}
+`
+
+       fset := token.NewFileSet()
+       file := mustParse(fset, src)
+       conf := Config{Error: func(err error) {}} // ignore errors
+       info := Info{Types: make(map[ast.Expr]TypeAndValue)}
+       conf.Check("p", fset, []*ast.File{file}, &info)
+
+       // look for {x} expression
+       outer := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.CompositeLit) // T{{x}}
+       inner := outer.Elts[0]                                                                        // {x}
+
+       // type of {x} must have been recorded
+       tv, ok := info.Types[inner]
+       if !ok {
+               t.Fatal("no type found for {x}")
+       }
+       if tv.Type != Typ[Invalid] {
+               t.Fatalf("unexpected type for {x}: %s", tv.Type)
+       }
+}
index 4019c094d59d1c80e4d34cd880c9b237fd238ed9..d3102d4f911eb6298e33d02f3077b4f455c5b352 100644 (file)
@@ -141,8 +141,9 @@ func (check *Checker) compositeLit(x *operand, e *ast.CompositeLit, hint Type) {
        default:
                // TODO(gri) provide better error messages depending on context
                check.error(e, UntypedLit, "missing type in composite literal")
-               x.mode = invalid
-               return
+               // continue with invalid type so that elements are "used" (go.dev/issue/69092)
+               typ = Typ[Invalid]
+               base = typ
        }
 
        switch utyp := coreType(base).(type) {