1
0
mirror of https://github.com/golang/go synced 2024-09-28 21:24:29 -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) u.tracef("== untyped arguments: %v", untyped)
} }
// We need a poser/positioner for check.allowVersion below. // Some generic parameters with untyped arguments may have been given a type by now.
// We should really use pos (argument to infer) but currently // Collect all remaining parameters that don't have a type yet and determine the
// the generator that generates go/types/infer.go has trouble // maximum untyped type for each of those parameters, if possible.
// with that. For now, do a little dance to get a position if var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
// we need one. (If we don't have untyped arguments left, it for _, index := range untyped {
// doesn't matter which branch we take below.) tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
// TODO(gri) adjust infer signature or adjust the rewriter. if u.at(tpar) == nil {
var at syntax.Pos arg := args[index] // arg corresponding to tpar
if len(untyped) > 0 { if maxUntyped == nil {
at = params.At(untyped[0]).pos 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
if check.allowVersion(check.pkg, atPos(at), go1_21) { // which doesn't have a type yet. Set the respective default types.
// Some generic parameters with untyped arguments may have been given a type by now. for tpar, typ := range maxUntyped {
// Collect all remaining parameters that don't have a type yet and determine the d := Default(typ)
// maximum untyped type for each of those parameters, if possible. assert(isTyped(d))
var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it) u.set(tpar, d)
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
}
}
} }
// --- simplify --- // --- simplify ---

View File

@ -285,78 +285,37 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
u.tracef("== untyped arguments: %v", untyped) u.tracef("== untyped arguments: %v", untyped)
} }
// We need a poser/positioner for check.allowVersion below. // Some generic parameters with untyped arguments may have been given a type by now.
// We should really use pos (argument to infer) but currently // Collect all remaining parameters that don't have a type yet and determine the
// the generator that generates go/types/infer.go has trouble // maximum untyped type for each of those parameters, if possible.
// with that. For now, do a little dance to get a position if var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
// we need one. (If we don't have untyped arguments left, it for _, index := range untyped {
// doesn't matter which branch we take below.) tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
// TODO(gri) adjust infer signature or adjust the rewriter. if u.at(tpar) == nil {
var at token.Pos arg := args[index] // arg corresponding to tpar
if len(untyped) > 0 { if maxUntyped == nil {
at = params.At(untyped[0]).pos 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
if check.allowVersion(check.pkg, atPos(at), go1_21) { // which doesn't have a type yet. Set the respective default types.
// Some generic parameters with untyped arguments may have been given a type by now. for tpar, typ := range maxUntyped {
// Collect all remaining parameters that don't have a type yet and determine the d := Default(typ)
// maximum untyped type for each of those parameters, if possible. assert(isTyped(d))
var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it) u.set(tpar, d)
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
}
}
} }
// --- simplify --- // --- simplify ---

View File

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