1
0
mirror of https://github.com/golang/go synced 2024-09-28 19:34:28 -06:00

go/types, types2: remove version check for more lenient constant handling in inference

For #58671.
Fixes #60566.

Change-Id: I746f99cdfd44b204dc90350fcfb3867e9b8b1da8
Reviewed-on: https://go-review.googlesource.com/c/go/+/499997
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Robert Griesemer 2023-06-01 16:31:15 -07:00 committed by Gopher Robot
parent 0cd9064cd7
commit 2e4fe8bbf0
3 changed files with 62 additions and 144 deletions

View File

@ -283,78 +283,37 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
u.tracef("== untyped arguments: %v", untyped)
}
// We need a poser/positioner for check.allowVersion below.
// We should really use pos (argument to infer) but currently
// the generator that generates go/types/infer.go has trouble
// with that. For now, do a little dance to get a position if
// we need one. (If we don't have untyped arguments left, it
// doesn't matter which branch we take below.)
// TODO(gri) adjust infer signature or adjust the rewriter.
var at syntax.Pos
if len(untyped) > 0 {
at = params.At(untyped[0]).pos
// Some generic parameters with untyped arguments may have been given a type by now.
// Collect all remaining parameters that don't have a type yet and determine the
// maximum untyped type for each of those parameters, if possible.
var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
for _, index := range untyped {
tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
if u.at(tpar) == nil {
arg := args[index] // arg corresponding to tpar
if maxUntyped == nil {
maxUntyped = make(map[*TypeParam]Type)
}
max := maxUntyped[tpar]
if max == nil {
max = arg.typ
} else {
m := maxType(max, arg.typ)
if m == nil {
check.errorf(arg, CannotInferTypeArgs, "mismatched types %s and %s (cannot infer %s)", max, arg.typ, tpar)
return nil
}
max = m
}
maxUntyped[tpar] = max
}
}
if check.allowVersion(check.pkg, atPos(at), go1_21) {
// Some generic parameters with untyped arguments may have been given a type by now.
// Collect all remaining parameters that don't have a type yet and determine the
// maximum untyped type for each of those parameters, if possible.
var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
for _, index := range untyped {
tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
if u.at(tpar) == nil {
arg := args[index] // arg corresponding to tpar
if maxUntyped == nil {
maxUntyped = make(map[*TypeParam]Type)
}
max := maxUntyped[tpar]
if max == nil {
max = arg.typ
} else {
m := maxType(max, arg.typ)
if m == nil {
check.errorf(arg, CannotInferTypeArgs, "mismatched types %s and %s (cannot infer %s)", max, arg.typ, tpar)
return nil
}
max = m
}
maxUntyped[tpar] = max
}
}
// maxUntyped contains the maximum untyped type for each type parameter
// which doesn't have a type yet. Set the respective default types.
for tpar, typ := range maxUntyped {
d := Default(typ)
assert(isTyped(d))
u.set(tpar, d)
}
} else {
// Some generic parameters with untyped arguments may have been given a type by now.
// Collect all remaining parameters that don't have a type yet and unify them with
// the default types of the untyped arguments.
// We need to collect them all before unifying them with their untyped arguments;
// otherwise a parameter type that appears multiple times will have a type after
// the first unification and will be skipped later on, leading to incorrect results.
j := 0
for _, i := range untyped {
tpar := params.At(i).typ.(*TypeParam) // is type parameter by construction of untyped
if u.at(tpar) == nil {
untyped[j] = i
j++
}
}
// untyped[:j] are the indices of parameters without a type yet.
// The respective default types are typed (not untyped) by construction.
for _, i := range untyped[:j] {
tpar := params.At(i).typ.(*TypeParam)
arg := args[i]
typ := Default(arg.typ)
assert(isTyped(typ))
if !u.unify(tpar, typ, assign) {
errorf("default type", tpar, typ, arg)
return nil
}
}
// maxUntyped contains the maximum untyped type for each type parameter
// which doesn't have a type yet. Set the respective default types.
for tpar, typ := range maxUntyped {
d := Default(typ)
assert(isTyped(d))
u.set(tpar, d)
}
// --- simplify ---

View File

@ -285,78 +285,37 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
u.tracef("== untyped arguments: %v", untyped)
}
// We need a poser/positioner for check.allowVersion below.
// We should really use pos (argument to infer) but currently
// the generator that generates go/types/infer.go has trouble
// with that. For now, do a little dance to get a position if
// we need one. (If we don't have untyped arguments left, it
// doesn't matter which branch we take below.)
// TODO(gri) adjust infer signature or adjust the rewriter.
var at token.Pos
if len(untyped) > 0 {
at = params.At(untyped[0]).pos
// Some generic parameters with untyped arguments may have been given a type by now.
// Collect all remaining parameters that don't have a type yet and determine the
// maximum untyped type for each of those parameters, if possible.
var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
for _, index := range untyped {
tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
if u.at(tpar) == nil {
arg := args[index] // arg corresponding to tpar
if maxUntyped == nil {
maxUntyped = make(map[*TypeParam]Type)
}
max := maxUntyped[tpar]
if max == nil {
max = arg.typ
} else {
m := maxType(max, arg.typ)
if m == nil {
check.errorf(arg, CannotInferTypeArgs, "mismatched types %s and %s (cannot infer %s)", max, arg.typ, tpar)
return nil
}
max = m
}
maxUntyped[tpar] = max
}
}
if check.allowVersion(check.pkg, atPos(at), go1_21) {
// Some generic parameters with untyped arguments may have been given a type by now.
// Collect all remaining parameters that don't have a type yet and determine the
// maximum untyped type for each of those parameters, if possible.
var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
for _, index := range untyped {
tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
if u.at(tpar) == nil {
arg := args[index] // arg corresponding to tpar
if maxUntyped == nil {
maxUntyped = make(map[*TypeParam]Type)
}
max := maxUntyped[tpar]
if max == nil {
max = arg.typ
} else {
m := maxType(max, arg.typ)
if m == nil {
check.errorf(arg, CannotInferTypeArgs, "mismatched types %s and %s (cannot infer %s)", max, arg.typ, tpar)
return nil
}
max = m
}
maxUntyped[tpar] = max
}
}
// maxUntyped contains the maximum untyped type for each type parameter
// which doesn't have a type yet. Set the respective default types.
for tpar, typ := range maxUntyped {
d := Default(typ)
assert(isTyped(d))
u.set(tpar, d)
}
} else {
// Some generic parameters with untyped arguments may have been given a type by now.
// Collect all remaining parameters that don't have a type yet and unify them with
// the default types of the untyped arguments.
// We need to collect them all before unifying them with their untyped arguments;
// otherwise a parameter type that appears multiple times will have a type after
// the first unification and will be skipped later on, leading to incorrect results.
j := 0
for _, i := range untyped {
tpar := params.At(i).typ.(*TypeParam) // is type parameter by construction of untyped
if u.at(tpar) == nil {
untyped[j] = i
j++
}
}
// untyped[:j] are the indices of parameters without a type yet.
// The respective default types are typed (not untyped) by construction.
for _, i := range untyped[:j] {
tpar := params.At(i).typ.(*TypeParam)
arg := args[i]
typ := Default(arg.typ)
assert(isTyped(typ))
if !u.unify(tpar, typ, assign) {
errorf("default type", tpar, typ, arg)
return nil
}
}
// maxUntyped contains the maximum untyped type for each type parameter
// which doesn't have a type yet. Set the respective default types.
for tpar, typ := range maxUntyped {
d := Default(typ)
assert(isTyped(d))
u.set(tpar, d)
}
// --- simplify ---

View File

@ -26,13 +26,13 @@ func _() {
_ = min(x, 1)
_ = min(x, 1.0)
_ = min(1, 2)
_ = min(1, 2.3 /* ERRORx `default type float64 .* does not match` */)
_ = min(1, 2.3)
var y float64
_ = min(1, y)
_ = min(1.2, y)
_ = min(1.2, 3.4)
_ = min(1.2, 3 /* ERRORx `default type int .* does not match` */)
_ = min(1.2, 3)
var s string
_ = min(s, "foo")