mirror of
https://github.com/golang/go
synced 2024-09-04 15:34:21 +00:00
[dev.typeparams] cmd/compile: fix small -G=3 issues for tests disabled in run.go
- set correct position for closure capture variable in (*irgen).use() (issue20250.go) Also, evaluate rhs, lhs in that order in assignment statements to match noder1 (affects ordering of closure variables). - make sure to set Assign flag properly in (*irgen).forStmt() for range variables which are map accesses (issue9691.go) - make sure CheckSize() is call on the base type for top-level types converted by (*irgen).typ() that are pointer types (issue20174.go and issue37837.go) - deal with parentheses properly in validation function (*irgen).validate() (issue17270.go) - avoid HasNil call on type TTYPEPARAM - types2 typechecker will have already checked validity of the typeparam having nil value (new test issue39755.go) Change-Id: Ie68004d964698aea047e19e7dcd79b297e9d47ca Reviewed-on: https://go-review.googlesource.com/c/go/+/334733 Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
3d8453e00e
commit
ed9e109dc9
|
@ -29,7 +29,7 @@ func (g *irgen) use(name *syntax.Name) *ir.Name {
|
||||||
if !ok {
|
if !ok {
|
||||||
base.FatalfAt(g.pos(name), "unknown name %v", name)
|
base.FatalfAt(g.pos(name), "unknown name %v", name)
|
||||||
}
|
}
|
||||||
obj := ir.CaptureName(g.pos(obj2), ir.CurFunc, g.obj(obj2))
|
obj := ir.CaptureName(g.pos(name), ir.CurFunc, g.obj(obj2))
|
||||||
if obj.Defn != nil && obj.Defn.Op() == ir.ONAME {
|
if obj.Defn != nil && obj.Defn.Op() == ir.ONAME {
|
||||||
// If CaptureName created a closure variable, then transfer the
|
// If CaptureName created a closure variable, then transfer the
|
||||||
// type of the captured name to the new closure variable.
|
// type of the captured name to the new closure variable.
|
||||||
|
|
|
@ -57,7 +57,10 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
|
||||||
if stmt.Rhs == nil {
|
if stmt.Rhs == nil {
|
||||||
n = IncDec(g.pos(stmt), op, g.expr(stmt.Lhs))
|
n = IncDec(g.pos(stmt), op, g.expr(stmt.Lhs))
|
||||||
} else {
|
} else {
|
||||||
n = ir.NewAssignOpStmt(g.pos(stmt), op, g.expr(stmt.Lhs), g.expr(stmt.Rhs))
|
// Eval rhs before lhs, for compatibility with noder1
|
||||||
|
rhs := g.expr(stmt.Rhs)
|
||||||
|
lhs := g.expr(stmt.Lhs)
|
||||||
|
n = ir.NewAssignOpStmt(g.pos(stmt), op, lhs, rhs)
|
||||||
}
|
}
|
||||||
if n.X.Typecheck() == 3 {
|
if n.X.Typecheck() == 3 {
|
||||||
n.SetTypecheck(3)
|
n.SetTypecheck(3)
|
||||||
|
@ -68,8 +71,9 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
names, lhs := g.assignList(stmt.Lhs, stmt.Op == syntax.Def)
|
// Eval rhs before lhs, for compatibility with noder1
|
||||||
rhs := g.exprList(stmt.Rhs)
|
rhs := g.exprList(stmt.Rhs)
|
||||||
|
names, lhs := g.assignList(stmt.Lhs, stmt.Op == syntax.Def)
|
||||||
|
|
||||||
// We must delay transforming the assign statement if any of the
|
// We must delay transforming the assign statement if any of the
|
||||||
// lhs or rhs nodes are also delayed, since transformAssign needs
|
// lhs or rhs nodes are also delayed, since transformAssign needs
|
||||||
|
@ -262,6 +266,12 @@ func (g *irgen) forStmt(stmt *syntax.ForStmt) ir.Node {
|
||||||
key, value := unpackTwo(lhs)
|
key, value := unpackTwo(lhs)
|
||||||
n := ir.NewRangeStmt(g.pos(r), key, value, g.expr(r.X), g.blockStmt(stmt.Body))
|
n := ir.NewRangeStmt(g.pos(r), key, value, g.expr(r.X), g.blockStmt(stmt.Body))
|
||||||
n.Def = initDefn(n, names)
|
n.Def = initDefn(n, names)
|
||||||
|
if key != nil {
|
||||||
|
transformCheckAssign(n, key)
|
||||||
|
}
|
||||||
|
if value != nil {
|
||||||
|
transformCheckAssign(n, value)
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,11 @@ func (g *irgen) typ(typ types2.Type) *types.Type {
|
||||||
// recursive types have been fully constructed before we call CheckSize.
|
// recursive types have been fully constructed before we call CheckSize.
|
||||||
if res != nil && !res.IsUntyped() && !res.IsFuncArgStruct() && !res.HasTParam() {
|
if res != nil && !res.IsUntyped() && !res.IsFuncArgStruct() && !res.HasTParam() {
|
||||||
types.CheckSize(res)
|
types.CheckSize(res)
|
||||||
|
if res.IsPtr() {
|
||||||
|
// Pointers always have their size set, even though their element
|
||||||
|
// may not have its size set.
|
||||||
|
types.CheckSize(res.Elem())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,15 @@ func (g *irgen) validate(n syntax.Node) {
|
||||||
case *syntax.CallExpr:
|
case *syntax.CallExpr:
|
||||||
tv := g.info.Types[n.Fun]
|
tv := g.info.Types[n.Fun]
|
||||||
if tv.IsBuiltin() {
|
if tv.IsBuiltin() {
|
||||||
switch builtin := n.Fun.(type) {
|
fun := n.Fun
|
||||||
|
for {
|
||||||
|
builtin, ok := fun.(*syntax.ParenExpr)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fun = builtin.X
|
||||||
|
}
|
||||||
|
switch builtin := fun.(type) {
|
||||||
case *syntax.Name:
|
case *syntax.Name:
|
||||||
g.validateBuiltin(builtin.Value, n)
|
g.validateBuiltin(builtin.Value, n)
|
||||||
case *syntax.SelectorExpr:
|
case *syntax.SelectorExpr:
|
||||||
|
|
|
@ -1636,7 +1636,9 @@ func (w *exportWriter) expr(n ir.Node) {
|
||||||
// (somewhat closely following the structure of exprfmt in fmt.go)
|
// (somewhat closely following the structure of exprfmt in fmt.go)
|
||||||
case ir.ONIL:
|
case ir.ONIL:
|
||||||
n := n.(*ir.NilExpr)
|
n := n.(*ir.NilExpr)
|
||||||
if !n.Type().HasNil() {
|
// If n is a typeparam, it will have already been checked
|
||||||
|
// for proper use by the types2 typechecker.
|
||||||
|
if !n.Type().IsTypeParam() && !n.Type().HasNil() {
|
||||||
base.Fatalf("unexpected type for nil: %v", n.Type())
|
base.Fatalf("unexpected type for nil: %v", n.Type())
|
||||||
}
|
}
|
||||||
w.op(ir.ONIL)
|
w.op(ir.ONIL)
|
||||||
|
|
|
@ -2167,12 +2167,7 @@ var types2Failures32Bit = setOf(
|
||||||
)
|
)
|
||||||
|
|
||||||
var g3Failures = setOf(
|
var g3Failures = setOf(
|
||||||
"writebarrier.go", // correct diagnostics, but different lines (probably irgen's fault)
|
"writebarrier.go", // correct diagnostics, but different lines (probably irgen's fault)
|
||||||
"fixedbugs/issue17270.go", // ICE in irgen
|
|
||||||
"fixedbugs/issue20174.go", // ICE due to width not calculated (probably irgen's fault)
|
|
||||||
"fixedbugs/issue20250.go", // correct diagnostics, but different lines (probably irgen's fault)
|
|
||||||
"fixedbugs/issue37837.go", // ICE due to width not calculated
|
|
||||||
"fixedbugs/issue9691.go", // "cannot assign to int(.autotmp_4)" (probably irgen's fault)
|
|
||||||
|
|
||||||
"typeparam/nested.go", // -G=3 doesn't support function-local types with generics
|
"typeparam/nested.go", // -G=3 doesn't support function-local types with generics
|
||||||
|
|
||||||
|
|
27
test/typeparam/issue39755.go
Normal file
27
test/typeparam/issue39755.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// compile -G=3
|
||||||
|
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// copied from cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
func _[T interface{~map[string]int}](x T) {
|
||||||
|
_ = x == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// simplified test case from issue
|
||||||
|
|
||||||
|
type PathParamsConstraint interface {
|
||||||
|
~map[string]string | ~[]struct{key, value string}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PathParams[T PathParamsConstraint] struct {
|
||||||
|
t T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *PathParams[T]) IsNil() bool {
|
||||||
|
return pp.t == nil // this must succeed
|
||||||
|
}
|
Loading…
Reference in a new issue