La Vita è Bella

Friday, September 04, 2020

Typed nil in Go

In Go, nil, one of the "magic" literals, could actually have types. Although in most cases this won't bite you, in rare cases it does bite and causes bugs. I was bitten by it for the second time (as far as I can remember) earlier this week.

This was the commit that introduced the bug and this was the commit that fixed it. The key issue is on these 2 lines:

41   var r intner = args.R
42   if r == nil {

What does this code do?

args.R is an optional argument to the function. The lines here are trying to do the fallback to the default implementation when it's absent.

Why does the old code not work?

On L42, when doing the comparison between r and nil, nil is actually a typed nil to match the type of r. Since r has the type of intner, this line actually implies:

if r == intner(nil) {

The problem is that args.R actually have a different type: *math/rand.Rand. When it's nil, that's actually typed nil of (*math/rand.Rand)(nil). When assigning it into r on L41, the type of the typed nil doesn't change, despite that r has a different type (the assignment is allowed because *math/rand.Rand is a concrete type that implements intner interface, so it's "assignable" in Go's type system). As a result, the comparison is actually:

if (*math/rand.Rand)(nil) == intner(nil) {

Since they are different types of typed nils, the comparison would never be true.

Why does the fix work?

In the fix, we changed to compare args.R against nil directly:

42   if args.R != nil {

So it always have the correct type for the typed nil.

tags: ,

09:32:40 by fishy - dev - Permanent Link

Revision: 1.1/1.1, last modified on 2020-12-31 @ 15:42.

Karma: 2 (50.06% out of 1762 were positive) [+/-]

You can subscribe to RSS 2.0 feed for comments and trackbacks

There are currently no trackbacks for this item.
Use this TrackBack url to ping this item (right-click, copy link target). If your blog does not support Trackbacks you can manually add your trackback by using this form.

No comments yet

Add Comment


May the Force be with you. RAmen