Skip to content

Commit f78483e

Browse files
griesemergopherbot
authored andcommitted
go/types, types2: add unifyMode to unifier, pass it through
Pass a mode parameter through all unifier calls but make no use of it. When unifying type elements (components of composite types), use emode, which currently is set to mode. Preparatory step to fix #60460. Factoring out this mechanical change will make the actual fix smaller and easier to review and understand. Because this change doesn't affect the behavior of the unifier, it is safe. For #60460. Change-Id: I5b67499d93025be2128c14cc00bcc3b8cc9f44b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/498955 Auto-Submit: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 8c5d1a4 commit f78483e

File tree

4 files changed

+68
-56
lines changed

4 files changed

+68
-56
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
155155
// Function parameters are always typed. Arguments may be untyped.
156156
// Collect the indices of untyped arguments and handle them later.
157157
if isTyped(arg.typ) {
158-
if !u.unify(par.typ, arg.typ) {
158+
if !u.unify(par.typ, arg.typ, 0) {
159159
errorf("type", par.typ, arg.typ, arg)
160160
return nil
161161
}
@@ -230,7 +230,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
230230
// core type.
231231
// 2) If the core type doesn't have a tilde, we also must unify tx
232232
// with the core type.
233-
if !u.unify(tx, core.typ) {
233+
if !u.unify(tx, core.typ, 0) {
234234
check.errorf(pos, CannotInferTypeArgs, "%s does not match %s", tpar, core.typ)
235235
return nil
236236
}
@@ -248,7 +248,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
248248
// the constraint.
249249
var cause string
250250
constraint := tpar.iface()
251-
if m, _ := check.missingMethod(tx, constraint, true, u.unify, &cause); m != nil {
251+
if m, _ := check.missingMethod(tx, constraint, true, func(x, y Type) bool { return u.unify(x, y, 0) }, &cause); m != nil {
252252
check.errorf(pos, CannotInferTypeArgs, "%s does not satisfy %s %s", tx, constraint, cause)
253253
return nil
254254
}
@@ -340,7 +340,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
340340
arg := args[i]
341341
typ := Default(arg.typ)
342342
assert(isTyped(typ))
343-
if !u.unify(tpar, typ) {
343+
if !u.unify(tpar, typ, 0) {
344344
errorf("default type", tpar, typ, arg)
345345
return nil
346346
}

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

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,13 @@ func newUnifier(tparams []*TypeParam, targs []Type) *unifier {
106106
return &unifier{handles, 0}
107107
}
108108

109+
// unifyMode controls the behavior of the unifier.
110+
type unifyMode uint
111+
109112
// unify attempts to unify x and y and reports whether it succeeded.
110113
// As a side-effect, types may be inferred for type parameters.
111-
func (u *unifier) unify(x, y Type) bool {
112-
return u.nify(x, y, nil)
114+
func (u *unifier) unify(x, y Type, mode unifyMode) bool {
115+
return u.nify(x, y, mode, nil)
113116
}
114117

115118
func (u *unifier) tracef(format string, args ...interface{}) {
@@ -241,10 +244,10 @@ func (u *unifier) inferred(tparams []*TypeParam) []Type {
241244
// adapted version of Checker.identical. For changes to that
242245
// code the corresponding changes should be made here.
243246
// Must not be called directly from outside the unifier.
244-
func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
247+
func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
245248
u.depth++
246249
if traceInference {
247-
u.tracef("%s ≡ %s", x, y)
250+
u.tracef("%s ≡ %s (mode %d)", x, y, mode)
248251
}
249252
defer func() {
250253
if traceInference && !result {
@@ -324,13 +327,13 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
324327
return true
325328
}
326329
// both x and y have an inferred type - they must match
327-
return u.nify(u.at(px), u.at(py), p)
330+
return u.nify(u.at(px), u.at(py), mode, p)
328331

329332
case px != nil:
330333
// x is a type parameter, y is not
331334
if x := u.at(px); x != nil {
332335
// x has an inferred type which must match y
333-
if u.nify(x, y, p) {
336+
if u.nify(x, y, mode, p) {
334337
// If we have a match, possibly through underlying types,
335338
// and y is a defined type, make sure we record that type
336339
// for type parameter x, which may have until now only
@@ -361,6 +364,9 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
361364
x, y = y, x
362365
}
363366

367+
// Type elements (array, slice, etc. elements) use emode for unification.
368+
emode := mode
369+
364370
// If EnableInterfaceInference is set and both types are interfaces, one
365371
// interface must have a subset of the methods of the other and corresponding
366372
// method signatures must unify.
@@ -427,7 +433,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
427433
}
428434
// All xmethods must exist in ymethods and corresponding signatures must unify.
429435
for _, xm := range xmethods {
430-
if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, p) {
436+
if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, emode, p) {
431437
return false
432438
}
433439
}
@@ -448,7 +454,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
448454
xmethods := xi.typeSet().methods
449455
for _, xm := range xmethods {
450456
obj, _, _ := LookupFieldOrMethod(y, false, xm.pkg, xm.name)
451-
if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, p) {
457+
if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, emode, p) {
452458
return false
453459
}
454460
}
@@ -474,13 +480,13 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
474480
if y, ok := y.(*Array); ok {
475481
// If one or both array lengths are unknown (< 0) due to some error,
476482
// assume they are the same to avoid spurious follow-on errors.
477-
return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, p)
483+
return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, emode, p)
478484
}
479485

480486
case *Slice:
481487
// Two slice types unify if their element types unify.
482488
if y, ok := y.(*Slice); ok {
483-
return u.nify(x.elem, y.elem, p)
489+
return u.nify(x.elem, y.elem, emode, p)
484490
}
485491

486492
case *Struct:
@@ -495,7 +501,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
495501
if f.embedded != g.embedded ||
496502
x.Tag(i) != y.Tag(i) ||
497503
!f.sameId(g.pkg, g.name) ||
498-
!u.nify(f.typ, g.typ, p) {
504+
!u.nify(f.typ, g.typ, emode, p) {
499505
return false
500506
}
501507
}
@@ -506,7 +512,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
506512
case *Pointer:
507513
// Two pointer types unify if their base types unify.
508514
if y, ok := y.(*Pointer); ok {
509-
return u.nify(x.base, y.base, p)
515+
return u.nify(x.base, y.base, emode, p)
510516
}
511517

512518
case *Tuple:
@@ -517,7 +523,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
517523
if x != nil {
518524
for i, v := range x.vars {
519525
w := y.vars[i]
520-
if !u.nify(v.typ, w.typ, p) {
526+
if !u.nify(v.typ, w.typ, mode, p) {
521527
return false
522528
}
523529
}
@@ -534,8 +540,8 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
534540
// TODO(gri) handle type parameters or document why we can ignore them.
535541
if y, ok := y.(*Signature); ok {
536542
return x.variadic == y.variadic &&
537-
u.nify(x.params, y.params, p) &&
538-
u.nify(x.results, y.results, p)
543+
u.nify(x.params, y.params, emode, p) &&
544+
u.nify(x.results, y.results, emode, p)
539545
}
540546

541547
case *Interface:
@@ -592,7 +598,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
592598
}
593599
for i, f := range a {
594600
g := b[i]
595-
if f.Id() != g.Id() || !u.nify(f.typ, g.typ, q) {
601+
if f.Id() != g.Id() || !u.nify(f.typ, g.typ, emode, q) {
596602
return false
597603
}
598604
}
@@ -603,13 +609,13 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
603609
case *Map:
604610
// Two map types unify if their key and value types unify.
605611
if y, ok := y.(*Map); ok {
606-
return u.nify(x.key, y.key, p) && u.nify(x.elem, y.elem, p)
612+
return u.nify(x.key, y.key, emode, p) && u.nify(x.elem, y.elem, emode, p)
607613
}
608614

609615
case *Chan:
610616
// Two channel types unify if their value types unify.
611617
if y, ok := y.(*Chan); ok {
612-
return u.nify(x.elem, y.elem, p)
618+
return u.nify(x.elem, y.elem, emode, p)
613619
}
614620

615621
case *Named:
@@ -625,11 +631,11 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
625631
// If one or both of x and y are interfaces, use interface unification.
626632
switch {
627633
case xi != nil && yi != nil:
628-
return u.nify(xi, yi, p)
634+
return u.nify(xi, yi, mode, p)
629635
case xi != nil:
630-
return u.nify(xi, y, p)
636+
return u.nify(xi, y, mode, p)
631637
case yi != nil:
632-
return u.nify(x, yi, p)
638+
return u.nify(x, yi, mode, p)
633639
}
634640
// In all other cases, the type arguments and origins must match.
635641
}
@@ -643,7 +649,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
643649
return false
644650
}
645651
for i, xarg := range xargs {
646-
if !u.nify(xarg, yargs[i], p) {
652+
if !u.nify(xarg, yargs[i], mode, p) {
647653
return false
648654
}
649655
}
@@ -678,7 +684,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
678684
if traceInference {
679685
u.tracef("core %s ≡ %s", x, y)
680686
}
681-
return u.nify(cx, y, p)
687+
return u.nify(cx, y, mode, p)
682688
}
683689
}
684690
// x != y and there's nothing to do
@@ -687,7 +693,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
687693
// avoid a crash in case of nil type
688694

689695
default:
690-
panic(sprintf(nil, true, "u.nify(%s, %s)", x, y))
696+
panic(sprintf(nil, true, "u.nify(%s, %s, %d)", x, y, mode))
691697
}
692698

693699
return false

src/go/types/infer.go

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

0 commit comments

Comments
 (0)