Add a lint check for functions which return errors but the error type isn't the last type in the return list.

Signed-off-by: David Symonds <dsymonds@golang.org>
diff --git a/lint.go b/lint.go
index eb27062..77188e0 100644
--- a/lint.go
+++ b/lint.go
@@ -88,6 +88,7 @@
 	f.lintReceiverNames()
 	f.lintIncDec()
 	f.lintMake()
+	f.lintErrorReturn()
 
 	return f.problems
 }
@@ -937,6 +938,30 @@
 	})
 }
 
+// lintErrorReturn examines function declarations that return an error.
+// It complains if the error isn't the last parameter.
+func (f *file) lintErrorReturn() {
+	f.walk(func(n ast.Node) bool {
+		fn, ok := n.(*ast.FuncDecl)
+		if !ok || fn.Type.Results == nil {
+			return true
+		}
+		ret := fn.Type.Results.List
+		if len(ret) <= 1 {
+			return true
+		}
+		// An error return parameter should be the last parameter.
+		// Flag any error parameters found before the last.
+		for _, r := range ret[:len(ret)-1] {
+			if isIdent(r.Type, "error") {
+				f.errorf(fn, 0.9, "", "error should be the last type when returning multiple items")
+				break // only flag one
+			}
+		}
+		return true
+	})
+}
+
 func receiverType(fn *ast.FuncDecl) string {
 	switch e := fn.Recv.List[0].Type.(type) {
 	case *ast.Ident:
diff --git a/testdata/error-return.go b/testdata/error-return.go
new file mode 100644
index 0000000..bc8bf00
--- /dev/null
+++ b/testdata/error-return.go
@@ -0,0 +1,43 @@
+// Test for returning errors.
+
+// Package foo ...
+package foo
+
+// Returns nothing
+func f() { // ok
+}
+
+// Check for a single error return
+func g() error { // ok
+	return nil
+}
+
+// Check for a single other return type
+func h() int { // ok
+	return 0
+}
+
+// Check for multiple return but error at end.
+func i() (int, error) { // ok
+	return 0, nil
+}
+
+// Check for multiple return but error at end with named variables.
+func i() (x int, err error) { // ok
+	return 0, nil
+}
+
+// Check for error in the wrong location on 2 types
+func j() (error, int) { // MATCH /error should be the last type/
+	return nil, 0
+}
+
+// Check for error in the wrong location for > 2 types
+func k() (int, error, int) { // MATCH /error should be the last type/
+	return 0, nil, 0
+}
+
+// Check for error in the wrong location with named variables.
+func l() (x int, err error, y int) { // MATCH /error should be the last type/
+	return 0, nil, 0
+}