Skip to content

Commit

Permalink
go/types, types2: exclude untyped nil arguments early in type inference
Browse files Browse the repository at this point in the history
An untyped nil argument cannot be used to infer any type information.
We don't need to include it in the untyped arguments.

Change-Id: Ied44738ff1b135e65a3acfa19223cd3889b7fa7d
Reviewed-on: https://go-review.googlesource.com/c/go/+/492695
Reviewed-by: Robert Griesemer <[email protected]>
Run-TryBot: Robert Griesemer <[email protected]>
Auto-Submit: Robert Griesemer <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Robert Findley <[email protected]>
  • Loading branch information
griesemer authored and gopherbot committed May 5, 2023
1 parent 695a536 commit a535055
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 17 deletions.
12 changes: 6 additions & 6 deletions src/cmd/compile/internal/types2/infer.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,13 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
errorf("type", par.typ, arg.typ, arg)
return nil
}
} else if _, ok := par.typ.(*TypeParam); ok {
} else if _, ok := par.typ.(*TypeParam); ok && !arg.isNil() {
// Since default types are all basic (i.e., non-composite) types, an
// untyped argument will never match a composite parameter type; the
// only parameter type it can possibly match against is a *TypeParam.
// Thus, for untyped arguments we only need to look at parameter types
// that are single type parameters.
// Also, untyped nils don't have a default type and can be ignored.
untyped = append(untyped, i)
}
}
Expand Down Expand Up @@ -290,15 +291,14 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
j++
}
}
// untyped[:j] are the indices of parameters without a type yet
// 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)
// The default type for an untyped nil is untyped nil which must
// not be inferred as type parameter type. Ignore them by making
// sure all default types are typed.
if isTyped(typ) && !u.unify(tpar, typ) {
assert(isTyped(typ))
if !u.unify(tpar, typ) {
errorf("default type", tpar, typ, arg)
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/types2/operand.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (x *operand) setConst(k syntax.LitKind, lit string) {
x.val = val
}

// isNil reports whether x is a typed or the untyped nil value.
// isNil reports whether x is the (untyped) nil value.
func (x *operand) isNil() bool { return x.mode == nilvalue }

// assignableTo reports whether x is assignable to a variable of type T. If the
Expand Down
12 changes: 6 additions & 6 deletions src/go/types/infer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions src/go/types/operand.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,8 @@ func (x *operand) setConst(tok token.Token, lit string) {
x.val = val
}

// isNil reports whether x is the nil value.
func (x *operand) isNil() bool {
return x.mode == value && x.typ == Typ[UntypedNil]
}
// isNil reports whether x is the (untyped) nil value.
func (x *operand) isNil() bool { return x.mode == value && x.typ == Typ[UntypedNil] }

// assignableTo reports whether x is assignable to a variable of type T. If the
// result is false and a non-nil cause is provided, it may be set to a more
Expand Down

0 comments on commit a535055

Please sign in to comment.