Skip to content

Commit

Permalink
go/types, types: always record a type for inner composite literals
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
griesemer authored and gopherbot committed Oct 2, 2024
1 parent 5b0f859 commit 9593684
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
26 changes: 26 additions & 0 deletions src/cmd/compile/internal/types2/issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
5 changes: 3 additions & 2 deletions src/cmd/compile/internal/types2/literals.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
27 changes: 27 additions & 0 deletions src/go/types/issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
5 changes: 3 additions & 2 deletions src/go/types/literals.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9593684

Please sign in to comment.