github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/cmd/vet/assign.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6  This file contains the code to check for useless assignments.
     7  */
     8  
     9  package main
    10  
    11  import (
    12  	"go/ast"
    13  	"go/token"
    14  	"reflect"
    15  )
    16  
    17  func init() {
    18  	register("assign",
    19  		"check for useless assignments",
    20  		checkAssignStmt,
    21  		assignStmt)
    22  }
    23  
    24  // TODO: should also check for assignments to struct fields inside methods
    25  // that are on T instead of *T.
    26  
    27  // checkAssignStmt checks for assignments of the form "<expr> = <expr>".
    28  // These are almost always useless, and even when they aren't they are usually a mistake.
    29  func checkAssignStmt(f *File, node ast.Node) {
    30  	stmt := node.(*ast.AssignStmt)
    31  	if stmt.Tok != token.ASSIGN {
    32  		return // ignore :=
    33  	}
    34  	if len(stmt.Lhs) != len(stmt.Rhs) {
    35  		// If LHS and RHS have different cardinality, they can't be the same.
    36  		return
    37  	}
    38  	for i, lhs := range stmt.Lhs {
    39  		rhs := stmt.Rhs[i]
    40  		if hasSideEffects(lhs) || hasSideEffects(rhs) {
    41  			continue // expressions may not be equal
    42  		}
    43  		if reflect.TypeOf(lhs) != reflect.TypeOf(rhs) {
    44  			continue // short-circuit the heavy-weight gofmt check
    45  		}
    46  		le := f.gofmt(lhs)
    47  		re := f.gofmt(rhs)
    48  		if le == re {
    49  			f.Badf(stmt.Pos(), "self-assignment of %s to %s", re, le)
    50  		}
    51  	}
    52  }