Add new lint: unnecessary_final.
diff --git a/example/all.yaml b/example/all.yaml
index 193d350..509fb7f 100644
--- a/example/all.yaml
+++ b/example/all.yaml
@@ -136,6 +136,7 @@
     - unnecessary_await_in_return
     - unnecessary_brace_in_string_interps
     - unnecessary_const
+    - unnecessary_final
     - unnecessary_getters_setters
     - unnecessary_lambdas
     - unnecessary_new
diff --git a/lib/src/rules.dart b/lib/src/rules.dart
index 574723b..c523f20 100644
--- a/lib/src/rules.dart
+++ b/lib/src/rules.dart
@@ -139,6 +139,7 @@
 import 'rules/unnecessary_await_in_return.dart';
 import 'rules/unnecessary_brace_in_string_interps.dart';
 import 'rules/unnecessary_const.dart';
+import 'rules/unnecessary_final.dart';
 import 'rules/unnecessary_getters_setters.dart';
 import 'rules/unnecessary_lambdas.dart';
 import 'rules/unnecessary_new.dart';
@@ -298,6 +299,7 @@
     ..register(UnnecessaryAwaitInReturn())
     ..register(UnnecessaryBraceInStringInterps())
     ..register(UnnecessaryConst())
+    ..register(UnnecessaryFinal())
     ..register(UnnecessaryNew())
     ..register(UnnecessaryNullAwareAssignments())
     ..register(UnnecessaryNullInIfNullOperators())
diff --git a/lib/src/rules/unnecessary_final.dart b/lib/src/rules/unnecessary_final.dart
new file mode 100644
index 0000000..d6f29f8
--- /dev/null
+++ b/lib/src/rules/unnecessary_final.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+
+import '../analyzer.dart';
+
+const _desc = "Don't use `final` for local variables.";
+
+const _details = r'''
+**DON'T** use `final` for local variables.
+
+`var` is shorter, and `final` does not change the meaning of the code.
+
+**BAD:**
+```
+void badMethod() {
+  final label = 'Final or var?';
+  for (final char in ['v', 'a', 'r']) {
+    print(char);
+  }
+}
+```
+
+**GOOD:**
+```
+void goodMethod() {
+  var label = 'Final or var?';
+  for (var char in ['v', 'a', 'r']) {
+    print(char);
+  }
+}
+```
+''';
+
+class UnnecessaryFinal extends LintRule implements NodeLintRule {
+  UnnecessaryFinal()
+      : super(
+            name: 'unnecessary_final',
+            description: _desc,
+            details: _details,
+            group: Group.style);
+
+  @override
+  void registerNodeProcessors(
+      NodeLintRegistry registry, LinterContext context) {
+    final visitor = _Visitor(this);
+    registry
+      ..addFormalParameterList(this, visitor)
+      ..addForStatement(this, visitor)
+      ..addVariableDeclaration(this, visitor);
+  }
+}
+
+class _Visitor extends SimpleAstVisitor<void> {
+  final LintRule rule;
+
+  _Visitor(this.rule);
+
+  @override
+  void visitFormalParameterList(FormalParameterList parameterList) {
+    for (var node in parameterList.parameters) {
+      if (node.isFinal) {
+        rule.reportLint(node);
+      }
+    }
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    var forLoopParts = node.forLoopParts;
+    // If the following `if` test fails, then either the statement is not a
+    // for-each loop, or it is something like `for(a in b) { ... }`.  In the
+    // second case, notice `a` is not actually declared from within the
+    // loop. `a` is a variable declared outside the loop.
+    if (forLoopParts is ForEachPartsWithDeclaration) {
+      final loopVariable = forLoopParts.loopVariable;
+
+      if (loopVariable.isFinal) {
+        rule.reportLint(loopVariable.identifier);
+      }
+    }
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    if (node.isFinal) {
+      rule.reportLint(node.name);
+    }
+  }
+}
diff --git a/test/rules/unnecessary_final.dart b/test/rules/unnecessary_final.dart
new file mode 100644
index 0000000..3bb25cd
--- /dev/null
+++ b/test/rules/unnecessary_final.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// test w/ `pub run test -N unnecessary_final`
+
+void badMethod(final int x) { // LINT
+  final label = 'Final or var?'; // LINT
+  print(label);
+  for (final char in ['v', 'a', 'r']) { // LINT
+    print(((final String char) => char.length)(char)); // LINT
+  }
+}
+
+void goodMethod(int x) {
+  var label = 'Final or var?'; // OK
+  print(label);
+  for (var char in ['v', 'a', 'r']) { // OK
+    print(((String char) => char.length)(char)); // OK
+  }
+}