_linters/src/honnef.co/go/tools/ssa/builder.go
func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf) {
	// Can we initialize it in place?
	if e, ok := unparen(e).(*ast.CompositeLit); ok {
		// A CompositeLit never evaluates to a pointer,
		// so if the type of the location is a pointer,
		// an &-operation is implied.
		if _, ok := loc.(blank); !ok { // avoid calling blank.typ()
			if isPointer(loc.typ()) {
				ptr := b.addr(fn, e, true).address(fn)
				// copy address
				if sb != nil {
					sb.store(loc, ptr)
				} else {
					loc.store(fn, ptr)
				}
				return
			}
		}

		if _, ok := loc.(*address); ok {
			if isInterface(loc.typ()) {
				// e.g. var x interface{} = T{...}
				// Can't in-place initialize an interface value.
				// Fall back to copying.
			} else {
				// x = T{...} or x := T{...}
				addr := loc.address(fn)
				if sb != nil {
					b.compLit(fn, addr, e, isZero, sb)
				} else {
					var sb storebuf
					b.compLit(fn, addr, e, isZero, &sb)
					sb.emit(fn)
				}

				// Subtle: emit debug ref for aggregate types only;
				// slice and map are handled by store ops in compLit.
				switch loc.typ().Underlying().(type) {
				case *types.Struct, *types.Array:
					emitDebugRef(fn, e, addr, true)
				}

				return
			}
		}
	}

	// simple case: just copy
	rhs := b.expr(fn, e)
	if sb != nil {
		sb.store(loc, rhs)
	} else {
		loc.store(fn, rhs)
	}
}
func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf) {
	// Can we initialize it in place?
	if e, ok := unparen(e).(*ast.CompositeLit); ok {
		// A CompositeLit never evaluates to a pointer,
		// so if the type of the location is a pointer,
		// an &-operation is implied.
		if _, ok := loc.(blank); !ok { // avoid calling blank.typ()
			if isPointer(loc.typ()) {
				ptr := b.addr(fn, e, true).address(fn)
				// copy address
				if sb != nil {
					sb.store(loc, ptr)
				} else {
					loc.store(fn, ptr)
				}
				return
			}
		}

		if _, ok := loc.(*address); ok {
			if isInterface(loc.typ()) {
				// e.g. var x interface{} = T{...}
				// Can't in-place initialize an interface value.
				// Fall back to copying.
			} else {
				// x = T{...} or x := T{...}
				addr := loc.address(fn)
				if sb != nil {
					b.compLit(fn, addr, e, isZero, sb)
				} else {
					var sb storebuf
					b.compLit(fn, addr, e, isZero, &sb)
					sb.emit(fn)
				}

				// Subtle: emit debug ref for aggregate types only;
				// slice and map are handled by store ops in compLit.
				switch loc.typ().Underlying().(type) {
				case *types.Struct, *types.Array:
					emitDebugRef(fn, e, addr, true)
				}

				return
			}
		}
	}

	// simple case: just copy
	rhs := b.expr(fn, e)
	if sb != nil {
		sb.store(loc, rhs)
	} else {
		loc.store(fn, rhs)
	}
}
func ( b * builder ) assign ( fn * Function , loc lvalue , e ast . Expr , isZero bool , sb * storebuf ) { // Can we initialize it in place? if e , ok := unparen ( e ) . ( * ast . CompositeLit ) ; ok { // A CompositeLit never evaluates to a pointer, // so if the type of the location is a pointer, // an &-operation is implied. if _ , ok := loc . ( blank ) ; ! ok { // avoid calling blank.typ() if isPointer ( loc . typ ( ) ) { ptr := b . addr ( fn , e , true ) . address ( fn ) // copy address if sb != nil { sb . store ( loc , ptr ) } else { loc . store ( fn , ptr ) } return } } if _ , ok := loc . ( * address ) ; ok { if isInterface ( loc . typ ( ) ) { // e.g. var x interface{} = T{...} // Can't in-place initialize an interface value. // Fall back to copying. } else { // x = T{...} or x := T{...} addr := loc . address ( fn ) if sb != nil { b . compLit ( fn , addr , e , isZero , sb ) } else { var sb storebuf b . compLit ( fn , addr , e , isZero , & sb ) sb . emit ( fn ) } // Subtle: emit debug ref for aggregate types only; // slice and map are handled by store ops in compLit. switch loc . typ ( ) . Underlying ( ) . ( type ) { case * types . Struct , * types . Array : emitDebugRef ( fn , e , addr , true ) } return } } } // simple case: just copy rhs := b . expr ( fn , e ) if sb != nil { sb . store ( loc , rhs ) } else { loc . store ( fn , rhs ) } }
// assign emits to fn code to initialize the lvalue loc with the value
// of expression e.  If isZero is true, assign assumes that loc holds
// the zero value for its type.
//
// This is equivalent to loc.store(fn, b.expr(fn, e)), but may generate
// better code in some cases, e.g., for composite literals in an
// addressable location.
//
// If sb is not nil, assign generates code to evaluate expression e, but
// not to update loc.  Instead, the necessary stores are appended to the
// storebuf sb so that they can be executed later.  This allows correct
// in-place update of existing variables when the RHS is a composite
// literal that may reference parts of the LHS.
//
assign emits to fn code to initialize the lvalue loc with the value of expression e . If isZero is true assign assumes that loc holds the zero value for its type . This is equivalent to loc . store ( fn b . expr ( fn e )) but may generate better code in some cases e . g . for composite literals in an addressable location . If sb is not nil assign generates code to evaluate expression e but not to update loc . Instead the necessary stores are appended to the storebuf sb so that they can be executed later . This allows correct in - place update of existing variables when the RHS is a composite literal that may reference parts of the LHS .