Flag names that stutter.
diff --git a/lint.go b/lint.go
index 5daef38..e22f747 100644
--- a/lint.go
+++ b/lint.go
@@ -236,12 +236,14 @@
 
 const docCommentsLink = styleGuideBase + "#Doc_Comments"
 
-// lintExported examines the doc comments of exported names.
+// lintExported examines the exported names.
 // It complains if any required doc comments are missing,
 // or if they are not of the right form. The exact rules are in
 // lintFuncDoc, lintTypeDoc and lintValueSpecDoc; this function
 // also tracks the GenDecl structure being traversed to permit
 // doc comments for constants to be on top of the const block.
+// It also complains if the names stutter when combined with
+// the package name.
 func (f *file) lintExported() {
 	if f.isTest() {
 		return
@@ -263,6 +265,11 @@
 			return true
 		case *ast.FuncDecl:
 			f.lintFuncDoc(v)
+			thing := "func"
+			if v.Recv != nil {
+				thing = "method"
+			}
+			f.checkStutter(v.Name, thing)
 			// Don't proceed inside funcs.
 			return false
 		case *ast.TypeSpec:
@@ -272,6 +279,7 @@
 				doc = lastGen.Doc
 			}
 			f.lintTypeDoc(v, doc)
+			f.checkStutter(v.Name, "type")
 			// Don't proceed inside types.
 			return false
 		case *ast.ValueSpec:
@@ -616,6 +624,31 @@
 	}
 }
 
+func (f *file) checkStutter(id *ast.Ident, thing string) {
+	pkg, name := f.f.Name.Name, id.Name
+	if !ast.IsExported(name) {
+		// unexported name
+		return
+	}
+	// A name stutters if the package name is a strict prefix
+	// and the next character of the name starts a new word.
+	if len(name) <= len(pkg) {
+		// name is too short to stutter.
+		// This permits the name to be the same as the package name.
+		return
+	}
+	if !strings.EqualFold(pkg, name[:len(pkg)]) {
+		return
+	}
+	// We can assume the name is well-formed UTF-8.
+	// If the next rune after the package name is uppercase or an underscore
+	// the it's starting a new word and thus this name stutters.
+	rem := name[len(pkg):]
+	if next, _ := utf8.DecodeRuneInString(rem); next == '_' || unicode.IsUpper(next) {
+		f.errorf(id, 0.8, category("naming"), "%s name will be used as %s.%s by other packages, and that stutters; consider calling this %s", thing, pkg, name, rem)
+	}
+}
+
 // zeroLiteral is a set of ast.BasicLit values that are zero values.
 // It is not exhaustive.
 var zeroLiteral = map[string]bool{
diff --git a/testdata/stutter.go b/testdata/stutter.go
new file mode 100644
index 0000000..997d4b8
--- /dev/null
+++ b/testdata/stutter.go
@@ -0,0 +1,20 @@
+// Test of stuttery names.
+
+// Package donut ...
+package donut
+
+// DonutMaker makes donuts.
+type DonutMaker struct{} // MATCH /donut\.DonutMaker.*stutter/
+
+// DonutRank computes the ranking of a donut.
+func DonutRank(d Donut) int { // MATCH /donut\.DonutRank.*stutter/
+	return 0
+}
+
+// Donut is a delicious treat.
+type Donut interface{} // ok because it is the whole name
+
+// Donuts are great, aren't they?
+type Donuts []Donut // ok because it didn't start a new word
+
+type donutGlaze int // ok because it is unexported