gofmt: fix for gofmt rewrite feature

Fixes #643.

R=rsc
CC=golang-dev
https://golang.org/cl/576041
diff --git a/src/cmd/gofmt/doc.go b/src/cmd/gofmt/doc.go
index 4b4adba..2e4c40c 100644
--- a/src/cmd/gofmt/doc.go
+++ b/src/cmd/gofmt/doc.go
@@ -41,8 +41,8 @@
 	pattern -> replacement
 
 Both pattern and replacement must be valid Go expressions.
-In the pattern, single-character lowercase identifers serve as
-wildcards matching arbitrary subexpressions; those expressions
+In the pattern, single-character lowercase identifiers serve as
+wildcards matching arbitrary sub-expressions; those expressions
 will be substituted for the same identifiers in the replacement.
 
 
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index b2b2159..9c238fa 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -46,7 +46,7 @@
 }
 
 
-// rewriteFile applys the rewrite rule pattern -> replace to an entire file.
+// rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file.
 func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
 	m := make(map[string]reflect.Value)
 	pat := reflect.NewValue(pattern)
@@ -127,9 +127,19 @@
 		return false
 	}
 
-	// Token positions need not match.
-	if pattern.Type() == positionType {
+	// Special cases.
+	switch pattern.Type() {
+	case positionType:
+		// token positions don't need to match
 		return true
+	case identType:
+		// For identifiers, only the names need to match
+		// (and none of the other *ast.Object information).
+		// This is a common case, handle it all here instead
+		// of recursing down any further via reflection.
+		p := pattern.Interface().(*ast.Ident)
+		v := val.Interface().(*ast.Ident)
+		return p == nil && v == nil || p != nil && v != nil && p.Name() == v.Name()
 	}
 
 	p := reflect.Indirect(pattern)