Skip to content

Commit 9593684

Browse files
griesemergopherbot
authored andcommitted
go/types, types: always record a type for inner composite literals
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 <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 5b0f859 commit 9593684

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

src/cmd/compile/internal/types2/issues_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,3 +1141,29 @@ type (
11411141
t.Errorf("got %s, want %s", got, want)
11421142
}
11431143
}
1144+
1145+
func TestIssue69092(t *testing.T) {
1146+
const src = `
1147+
package p
1148+
1149+
var _ = T{{x}}
1150+
`
1151+
1152+
file := mustParse(src)
1153+
conf := Config{Error: func(err error) {}} // ignore errors
1154+
info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
1155+
conf.Check("p", []*syntax.File{file}, &info)
1156+
1157+
// look for {x} expression
1158+
outer := file.DeclList[0].(*syntax.VarDecl).Values.(*syntax.CompositeLit) // T{{x}}
1159+
inner := outer.ElemList[0] // {x}
1160+
1161+
// type of {x} must have been recorded
1162+
tv, ok := info.Types[inner]
1163+
if !ok {
1164+
t.Fatal("no type found for {x}")
1165+
}
1166+
if tv.Type != Typ[Invalid] {
1167+
t.Fatalf("unexpected type for {x}: %s", tv.Type)
1168+
}
1169+
}

src/cmd/compile/internal/types2/literals.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type
137137
default:
138138
// TODO(gri) provide better error messages depending on context
139139
check.error(e, UntypedLit, "missing type in composite literal")
140-
x.mode = invalid
141-
return
140+
// continue with invalid type so that elements are "used" (go.dev/issue/69092)
141+
typ = Typ[Invalid]
142+
base = typ
142143
}
143144

144145
switch utyp := coreType(base).(type) {

src/go/types/issues_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,3 +1151,30 @@ type (
11511151
t.Errorf("got %s, want %s", got, want)
11521152
}
11531153
}
1154+
1155+
func TestIssue69092(t *testing.T) {
1156+
const src = `
1157+
package p
1158+
1159+
var _ = T{{x}}
1160+
`
1161+
1162+
fset := token.NewFileSet()
1163+
file := mustParse(fset, src)
1164+
conf := Config{Error: func(err error) {}} // ignore errors
1165+
info := Info{Types: make(map[ast.Expr]TypeAndValue)}
1166+
conf.Check("p", fset, []*ast.File{file}, &info)
1167+
1168+
// look for {x} expression
1169+
outer := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.CompositeLit) // T{{x}}
1170+
inner := outer.Elts[0] // {x}
1171+
1172+
// type of {x} must have been recorded
1173+
tv, ok := info.Types[inner]
1174+
if !ok {
1175+
t.Fatal("no type found for {x}")
1176+
}
1177+
if tv.Type != Typ[Invalid] {
1178+
t.Fatalf("unexpected type for {x}: %s", tv.Type)
1179+
}
1180+
}

src/go/types/literals.go

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)