Half of your question depends on whether your value is addressable or not:
For an operand x of type T, the address operation &x generates a
pointer of type *T to x. The operand must be addressable, that is,
either:
- a variable,
- pointer indirection, or
- slice indexing operation; or
- a field selector of an addressable struct operand; or
- an array indexing operation of an addressable array.
As an exception to the addressability requirement, x may also be a
(possibly parenthesized) composite literal.
— Address operators
Bar{} is a composite literal, thus it is not addressable. You may type &Bar{} to create an object of type *Bar, but that is listed as "an exception to the addressability requirement", reinforcing the idea that Bar{} is not addressable in itself.
Variable b of type Bar can invoke b.foo() despite Bar.foo() requiring a pointer receiver for a good reason:
A method call x.m() is valid if the method set of (the type of) x
contains m and the argument list can be assigned to the parameter
list of m. If x is addressable and &x's method set contains m,
x.m() is shorthand for (&x).m()
— Calls
However, that does not mean Bar.foo() is in the method set of b. This is because b has type Bar while Bar.foo() receives a value of type *Bar:
A type may have a method set associated with it. The method set of an
interface type is its interface. The method set of any other type T
consists of all methods declared with receiver type T. The method
set of the corresponding pointer type *T is the set of all methods
declared with receiver *T or T (that is, it also contains the
method set of T).
— from Method sets
Because the method sets of b and the Foo interface differ, you cannot use var foo Foo = b, despite b.foo() being converted to (&b).foo() by the compiler. Otherwise, var foo Foo = Bar{} would work. You may, however, use either of the following since Bar.foo() receives a *Bar:
var foo Foo = &b
var foo Foo = &Bar{}