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 reflect.TypeOf(lhs) != reflect.TypeOf(rhs) { 41 continue // short-circuit the heavy-weight gofmt check 42 } 43 le := f.gofmt(lhs) 44 re := f.gofmt(rhs) 45 if le == re { 46 f.Badf(stmt.Pos(), "self-assignment of %s to %s", re, le) 47 } 48 } 49 } 50