nil interface values

A nil interface value holds neither a value nor a concrete type [1]. For example, the variable c of type Color is not assigned a concrete value.

// without specifications for simplicity
type Color interface {
	RGBA() (r, g, b, a uint32)
}

func main() {
	var c Color
	// @ assert c == nil
	client1(c)
}

func client1(c Color) {
	c.RGBA() // error
}

Go panics with a run-time error if a method is called on a nil interface value. Since it holds no concrete type, there is no way to look up which concrete RGBA method to call.

panic: runtime error: invalid memory address or nil pointer dereference

Gobra statically reports an error instead:

ERROR Precondition of call c.RGBA() might not hold. 

The receiver might be nil

Note that an interface variable holding a concrete type is non-nil, even when the concrete value is nil. In the following example, *SomeColor implements the interface Color. The first two assertions pass since c has the dynamic type *SomeColor. Hence, calling the method RGBA is legal. Since the receiver (s *SomeColor) might be nil, the last assertion fails:

func client2() {
	var c Color = (*SomeColor)(nil)
	// @ assert c != nil
	// @ assert typeOf(c) == type[*SomeColor]
	c.RGBA()
}

type SomeColor struct{ x int }

func (s *SomeColor) RGBA() (r, g, b, a uint32) {
	// @ assert s != nil // error
	a = uint32(s.x)
	return a, a, a, a
}

ERROR Assert might fail.

Assertion s != nil might not hold.

Full section example

Gobra is expected to find 2 errors.

package main

// without specifications for simplicity
type Color interface {
	RGBA() (r, g, b, a uint32)
}

func main() {
	var c Color
	// @ assert c == nil
	client1(c)
}

func client1(c Color) {
	c.RGBA() // error
}


func client2() {
	var c Color = (*SomeColor)(nil)
	// @ assert c != nil
	// @ assert typeOf(c) == type[*SomeColor]
	c.RGBA()
}

type SomeColor struct{ x int }

func (s *SomeColor) RGBA() (r, g, b, a uint32) {
	// @ assert s != nil // error
	a = uint32(s.x)
	return a, a, a, a
}