diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index ba3be49..bd04b6a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/inheritance_override.dart';
@@ -407,11 +408,17 @@
         _context.typeSystem, _inheritance, errorReporter);
     inheritanceOverrideVerifier.verifyUnit(unit);
 
+    FlowAnalysisResult flowAnalysisResult;
+    if (unit.featureSet.isEnabled(Feature.non_nullable)) {
+      flowAnalysisResult = performFlowAnalysis(_context.typeSystem, unit);
+    }
+
     //
     // Use the ErrorVerifier to compute errors.
     //
     ErrorVerifier errorVerifier = new ErrorVerifier(
-        errorReporter, _libraryElement, _typeProvider, _inheritance, false);
+        errorReporter, _libraryElement, _typeProvider, _inheritance, false,
+        flowAnalysisResult: flowAnalysisResult);
     unit.accept(errorVerifier);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
index b711bcb..838ae88 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
@@ -2,15 +2,17 @@
 // 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.
 
-/// Sets of variables that are potentially assigned in a statement.
+/// Sets of local variables that are potentially assigned in a statement.
+///
+/// These statements are loops, `switch`, and `try` statements.
 class AssignedVariables<Statement, Element> {
   final emptySet = Set<Element>();
 
-  /// Mapping from a [Statement] representing a loop to the set of variables
-  /// that are potentially assigned in that loop.
+  /// Mapping from a [Statement] to the set of local variables that are
+  /// potentially assigned in that statement.
   final Map<Statement, Set<Element>> _map = {};
 
-  /// The stack of nested nodes.
+  /// The stack of nested statements.
   final List<Set<Element>> _stack = [];
 
   AssignedVariables();
@@ -21,12 +23,12 @@
     return _map[statement] ?? emptySet;
   }
 
-  void beginLoop() {
+  void beginStatement() {
     var set = Set<Element>.identity();
     _stack.add(set);
   }
 
-  void endLoop(Statement node) {
+  void endStatement(Statement node) {
     _map[node] = _stack.removeLast();
   }
 
@@ -126,6 +128,17 @@
     _current = _current.add(variable, assigned: assigned);
   }
 
+  void booleanLiteral(Expression expression, bool value) {
+    _condition = expression;
+    if (value) {
+      _conditionTrue = _current;
+      _conditionFalse = _identity;
+    } else {
+      _conditionTrue = _identity;
+      _conditionFalse = _current;
+    }
+  }
+
   void conditional_elseBegin(Expression conditionalExpression,
       Expression thenExpression, bool isBool) {
     var afterThen = _current;
@@ -223,12 +236,6 @@
     _current = _join(falseCondition, breakState);
   }
 
-  void falseLiteral(Expression expression) {
-    _condition = expression;
-    _conditionTrue = _identity;
-    _conditionFalse = _current;
-  }
-
   void forEachStatement_bodyBegin(Set<Element> loopAssigned) {
     _stack.add(_current);
     _current = _current.removePromotedAll(loopAssigned);
@@ -494,12 +501,6 @@
     _stack.add(_current); // afterExpression
   }
 
-  void trueLiteral(Expression expression) {
-    _condition = expression;
-    _conditionTrue = _current;
-    _conditionFalse = _identity;
-  }
-
   void tryCatchStatement_bodyBegin() {
     _stack.add(_current);
     // Tail of the stack: beforeBody
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
new file mode 100644
index 0000000..a95f526
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -0,0 +1,750 @@
+// 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/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+
+/// Perform flow analysis for the given [unit].
+FlowAnalysisResult performFlowAnalysis(
+  TypeSystem typeSystem,
+  CompilationUnit unit,
+) {
+  var assignedVariables = AssignedVariables<Statement, VariableElement>();
+  unit.accept(AssignedVariablesVisitor(assignedVariables));
+
+  var readBeforeWritten = <LocalVariableElement>[];
+
+  unit.accept(FlowAnalysisVisitor(
+    typeSystem,
+    assignedVariables,
+    {},
+    readBeforeWritten,
+    [],
+    [],
+    [],
+    [],
+  ));
+
+  return FlowAnalysisResult(
+    readBeforeWritten,
+  );
+}
+
+/// The visitor that gathers local variables that are potentially assigned
+/// in corresponding statements, such as loops, `switch` and `try`.
+///
+/// TODO(scheglov) Change other tests to use [performFlowAnalysis],
+/// and make this class private.
+class AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
+  final AssignedVariables assignedVariables;
+
+  AssignedVariablesVisitor(this.assignedVariables);
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var left = node.leftHandSide;
+
+    super.visitAssignmentExpression(node);
+
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is VariableElement) {
+        assignedVariables.write(element);
+      }
+    }
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    assignedVariables.beginStatement();
+    super.visitDoStatement(node);
+    assignedVariables.endStatement(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    var forLoopParts = node.forLoopParts;
+    if (forLoopParts is ForParts) {
+      if (forLoopParts is ForPartsWithExpression) {
+        forLoopParts.initialization?.accept(this);
+      } else if (forLoopParts is ForPartsWithDeclarations) {
+        forLoopParts.variables?.accept(this);
+      } else {
+        throw new StateError('Unrecognized for loop parts');
+      }
+
+      assignedVariables.beginStatement();
+      forLoopParts.condition?.accept(this);
+      node.body.accept(this);
+      forLoopParts.updaters?.accept(this);
+      assignedVariables.endStatement(node);
+    } else if (forLoopParts is ForEachParts) {
+      var iterable = forLoopParts.iterable;
+      var body = node.body;
+
+      iterable.accept(this);
+
+      assignedVariables.beginStatement();
+      body.accept(this);
+      assignedVariables.endStatement(node);
+    } else {
+      throw new StateError('Unrecognized for loop parts');
+    }
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    var expression = node.expression;
+    var members = node.members;
+
+    expression.accept(this);
+
+    assignedVariables.beginStatement();
+    members.accept(this);
+    assignedVariables.endStatement(node);
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    assignedVariables.beginStatement();
+    node.body.accept(this);
+    assignedVariables.endStatement(node.body);
+
+    node.catchClauses.accept(this);
+
+    var finallyBlock = node.finallyBlock;
+    if (finallyBlock != null) {
+      assignedVariables.beginStatement();
+      finallyBlock.accept(this);
+      assignedVariables.endStatement(finallyBlock);
+    }
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    assignedVariables.beginStatement();
+    super.visitWhileStatement(node);
+    assignedVariables.endStatement(node);
+  }
+}
+
+/// The result of performing flow analysis on a unit.
+class FlowAnalysisResult {
+  final List<LocalVariableElement> readBeforeWritten;
+
+  FlowAnalysisResult(this.readBeforeWritten);
+}
+
+/// [AstVisitor] that drives the [FlowAnalysis].
+///
+/// TODO(scheglov) Change other tests to use [performFlowAnalysis],
+/// and make this class private.
+class FlowAnalysisVisitor extends GeneralizingAstVisitor<void> {
+  static final trueLiteral = astFactory.booleanLiteral(null, true);
+
+  final NodeOperations<Expression> nodeOperations;
+  final TypeOperations<VariableElement, DartType> typeOperations;
+  final AssignedVariables assignedVariables;
+
+  final Map<AstNode, DartType> promotedTypes;
+  final List<LocalVariableElement> readBeforeWritten;
+  final List<AstNode> nullableNodes;
+  final List<AstNode> nonNullableNodes;
+  final List<AstNode> unreachableNodes;
+  final List<FunctionBody> functionBodiesThatDontComplete;
+
+  FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
+
+  FlowAnalysisVisitor(
+      TypeSystem typeSystem,
+      this.assignedVariables,
+      this.promotedTypes,
+      this.readBeforeWritten,
+      this.nullableNodes,
+      this.nonNullableNodes,
+      this.unreachableNodes,
+      this.functionBodiesThatDontComplete)
+      : nodeOperations = _NodeOperations(),
+        typeOperations = _TypeSystemTypeOperations(typeSystem);
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    if (flow == null) {
+      return super.visitAssignmentExpression(node);
+    }
+
+    var left = node.leftHandSide;
+    var right = node.rightHandSide;
+
+    VariableElement localElement;
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is VariableElement) {
+        localElement = element;
+      }
+    }
+
+    if (localElement != null) {
+      var isCompound = node.operator.type != TokenType.EQ;
+      if (isCompound) {
+        flow.read(localElement);
+      }
+      right.accept(this);
+      flow.write(
+        localElement,
+        isNull: _isNull(right),
+        isNonNull: _isNonNull(right),
+      );
+    } else {
+      left.accept(this);
+      right.accept(this);
+    }
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    if (flow == null) {
+      return super.visitBinaryExpression(node);
+    }
+
+    var left = node.leftOperand;
+    var right = node.rightOperand;
+
+    var operator = node.operator.type;
+
+    if (operator == TokenType.AMPERSAND_AMPERSAND) {
+      left.accept(this);
+
+      flow.logicalAnd_rightBegin(node, node.leftOperand);
+      _checkUnreachableNode(node.rightOperand);
+      right.accept(this);
+
+      flow.logicalAnd_end(node, node.rightOperand);
+    } else if (operator == TokenType.BAR_BAR) {
+      left.accept(this);
+
+      flow.logicalOr_rightBegin(node, node.leftOperand);
+      _checkUnreachableNode(node.rightOperand);
+      right.accept(this);
+
+      flow.logicalOr_end(node, node.rightOperand);
+    } else if (operator == TokenType.BANG_EQ) {
+      left.accept(this);
+      right.accept(this);
+      // TODO(scheglov) Support `null != name`
+      if (right is NullLiteral) {
+        if (left is SimpleIdentifier) {
+          var element = left.staticElement;
+          if (element is VariableElement) {
+            flow.conditionNotEqNull(node, element);
+          }
+        }
+      }
+    } else if (operator == TokenType.EQ_EQ) {
+      // TODO(scheglov) Support `null == name`
+      left.accept(this);
+      right.accept(this);
+      if (right is NullLiteral) {
+        if (left is SimpleIdentifier) {
+          var element = left.staticElement;
+          if (element is VariableElement) {
+            flow.conditionEqNull(node, element);
+          }
+        }
+      }
+    } else if (operator == TokenType.QUESTION_QUESTION) {
+      left.accept(this);
+
+      flow.ifNullExpression_rightBegin();
+      right.accept(this);
+
+      flow.ifNullExpression_end();
+    } else {
+      left.accept(this);
+      right.accept(this);
+    }
+  }
+
+  @override
+  void visitBlockFunctionBody(BlockFunctionBody node) {
+    if (flow != null) {
+      super.visitBlockFunctionBody(node);
+    } else {
+      flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
+        nodeOperations,
+        typeOperations,
+        _FunctionBodyAccess(node),
+      );
+
+      var function = node.parent;
+      if (function is FunctionExpression) {
+        var parameters = function.parameters;
+        if (parameters != null) {
+          for (var parameter in parameters?.parameters) {
+            flow.add(parameter.declaredElement, assigned: true);
+          }
+        }
+      }
+      // TODO(scheglov) Methods and constructors.
+
+      super.visitBlockFunctionBody(node);
+
+      for (var variable in flow.readBeforeWritten) {
+        assert(variable is LocalVariableElement);
+        readBeforeWritten.add(variable);
+      }
+
+      if (!flow.isReachable) {
+        functionBodiesThatDontComplete.add(node);
+      }
+
+      flow.verifyStackEmpty();
+      flow = null;
+    }
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    if (flow == null) {
+      return super.visitBooleanLiteral(node);
+    }
+
+    flow.booleanLiteral(node, node.value);
+  }
+
+  @override
+  void visitBreakStatement(BreakStatement node) {
+    super.visitBreakStatement(node);
+    var target = _getLabelTarget(node, node.label?.staticElement);
+    flow.handleBreak(target);
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    if (flow == null) {
+      return super.visitConditionalExpression(node);
+    }
+
+    var condition = node.condition;
+    var thenExpression = node.thenExpression;
+    var elseExpression = node.elseExpression;
+
+    condition.accept(this);
+
+    flow.conditional_thenBegin(node, node.condition);
+    _checkUnreachableNode(node.thenExpression);
+    thenExpression.accept(this);
+    var isBool = thenExpression.staticType.isDartCoreBool;
+
+    flow.conditional_elseBegin(node, node.thenExpression, isBool);
+    _checkUnreachableNode(node.elseExpression);
+    elseExpression.accept(this);
+
+    flow.conditional_end(node, node.elseExpression, isBool);
+  }
+
+  @override
+  void visitContinueStatement(ContinueStatement node) {
+    super.visitContinueStatement(node);
+    var target = _getLabelTarget(node, node.label?.staticElement);
+    flow.handleContinue(target);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    _checkUnreachableNode(node);
+
+    var body = node.body;
+    var condition = node.condition;
+
+    flow.doStatement_bodyBegin(node, assignedVariables[node]);
+    body.accept(this);
+
+    flow.doStatement_conditionBegin();
+    condition.accept(this);
+
+    flow.doStatement_end(node, node.condition);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    _checkUnreachableNode(node);
+
+    ForLoopParts parts = node.forLoopParts;
+    if (parts is ForEachParts) {
+      parts.iterable?.accept(this);
+
+      flow.forEachStatement_bodyBegin(assignedVariables[node]);
+
+      node.body.accept(this);
+
+      flow.forEachStatement_end();
+      return;
+    }
+    VariableDeclarationList variables;
+    Expression initialization;
+    Expression condition;
+    NodeList<Expression> updaters;
+    if (parts is ForPartsWithDeclarations) {
+      variables = parts.variables;
+      condition = parts.condition;
+      updaters = parts.updaters;
+    } else if (parts is ForPartsWithExpression) {
+      initialization = parts.initialization;
+      condition = parts.condition;
+      updaters = parts.updaters;
+    }
+    initialization?.accept(this);
+    variables?.accept(this);
+
+    flow.forStatement_conditionBegin(assignedVariables[node]);
+    if (condition != null) {
+      condition.accept(this);
+    } else {
+      flow.booleanLiteral(trueLiteral, true);
+    }
+
+    flow.forStatement_bodyBegin(node, condition ?? trueLiteral);
+    node.body.accept(this);
+
+    flow.forStatement_updaterBegin();
+    updaters?.accept(this);
+
+    flow.forStatement_end();
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    if (flow == null) {
+      return super.visitFunctionExpression(node);
+    }
+
+    flow.functionExpression_begin();
+    super.visitFunctionExpression(node);
+    flow.functionExpression_end();
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    _checkUnreachableNode(node);
+
+    var condition = node.condition;
+    var thenStatement = node.thenStatement;
+    var elseStatement = node.elseStatement;
+
+    condition.accept(this);
+
+    flow.ifStatement_thenBegin(node, node.condition);
+    thenStatement.accept(this);
+
+    if (elseStatement != null) {
+      flow.ifStatement_elseBegin();
+      elseStatement.accept(this);
+    }
+
+    flow.ifStatement_end(elseStatement != null);
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    if (flow == null) {
+      return super.visitIsExpression(node);
+    }
+
+    super.visitIsExpression(node);
+    var expression = node.expression;
+    var typeAnnotation = node.type;
+
+    if (expression is SimpleIdentifier) {
+      var element = expression.staticElement;
+      if (element is VariableElement) {
+        flow.isExpression_end(
+          node,
+          element,
+          node.notOperator != null,
+          typeAnnotation.type,
+        );
+      }
+    }
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    if (flow == null) {
+      return super.visitPrefixExpression(node);
+    }
+
+    var operand = node.operand;
+
+    var operator = node.operator.type;
+    if (operator == TokenType.BANG) {
+      operand.accept(this);
+      flow.logicalNot_end(node, node.operand);
+    } else {
+      operand.accept(this);
+    }
+  }
+
+  @override
+  void visitRethrowExpression(RethrowExpression node) {
+    if (flow == null) {
+      return super.visitRethrowExpression(node);
+    }
+
+    super.visitRethrowExpression(node);
+    flow.handleExit();
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    super.visitReturnStatement(node);
+    flow.handleExit();
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (flow == null) {
+      return super.visitSimpleIdentifier(node);
+    }
+
+    var element = node.staticElement;
+    var isLocalVariable = element is LocalVariableElement;
+    if (isLocalVariable || element is ParameterElement) {
+      if (node.inGetterContext() && !node.inDeclarationContext()) {
+        if (isLocalVariable) {
+          flow.read(element);
+        }
+
+        if (flow.isNullable(element)) {
+          nullableNodes?.add(node);
+        }
+
+        if (flow.isNonNullable(element)) {
+          nonNullableNodes?.add(node);
+        }
+
+        var promotedType = flow.promotedType(element);
+        if (promotedType != null) {
+          promotedTypes[node] = promotedType;
+        }
+      }
+    }
+  }
+
+  @override
+  void visitStatement(Statement node) {
+    _checkUnreachableNode(node);
+    super.visitStatement(node);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    _checkUnreachableNode(node);
+
+    node.expression.accept(this);
+    flow.switchStatement_expressionEnd(node);
+
+    var assignedInCases = assignedVariables[node];
+
+    var members = node.members;
+    var membersLength = members.length;
+    var hasDefault = false;
+    for (var i = 0; i < membersLength; i++) {
+      var member = members[i];
+
+      flow.switchStatement_beginCase(
+        member.labels.isNotEmpty ? assignedInCases : assignedVariables.emptySet,
+      );
+      member.accept(this);
+
+      // Implicit `break` at the end of `default`.
+      if (member is SwitchDefault) {
+        hasDefault = true;
+        flow.handleBreak(node);
+      }
+    }
+
+    flow.switchStatement_end(node, hasDefault);
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    if (flow == null) {
+      return super.visitThrowExpression(node);
+    }
+
+    super.visitThrowExpression(node);
+    flow.handleExit();
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    _checkUnreachableNode(node);
+
+    var body = node.body;
+    var catchClauses = node.catchClauses;
+    var finallyBlock = node.finallyBlock;
+
+    if (finallyBlock != null) {
+      flow.tryFinallyStatement_bodyBegin();
+    }
+
+    flow.tryCatchStatement_bodyBegin();
+    body.accept(this);
+    flow.tryCatchStatement_bodyEnd(assignedVariables[body]);
+
+    var catchLength = catchClauses.length;
+    for (var i = 0; i < catchLength; ++i) {
+      var catchClause = catchClauses[i];
+      flow.tryCatchStatement_catchBegin();
+      catchClause.accept(this);
+      flow.tryCatchStatement_catchEnd();
+    }
+
+    flow.tryCatchStatement_end();
+
+    if (finallyBlock != null) {
+      flow.tryFinallyStatement_finallyBegin(assignedVariables[body]);
+      finallyBlock.accept(this);
+      flow.tryFinallyStatement_end(assignedVariables[finallyBlock]);
+    }
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    var variables = node.variables.variables;
+    for (var i = 0; i < variables.length; ++i) {
+      var variable = variables[i];
+      flow.add(variable.declaredElement,
+          assigned: variable.initializer != null);
+    }
+
+    super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    _checkUnreachableNode(node);
+
+    var condition = node.condition;
+    var body = node.body;
+
+    flow.whileStatement_conditionBegin(assignedVariables[node]);
+    condition.accept(this);
+
+    flow.whileStatement_bodyBegin(node, node.condition);
+    body.accept(this);
+
+    flow.whileStatement_end();
+  }
+
+  /// Mark the [node] as unreachable if it is not covered by another node that
+  /// is already known to be unreachable.
+  void _checkUnreachableNode(AstNode node) {
+    if (flow.isReachable) return;
+
+    // Ignore the [node] if it is fully covered by the last unreachable.
+    if (unreachableNodes.isNotEmpty) {
+      var last = unreachableNodes.last;
+      if (node.offset >= last.offset && node.end <= last.end) return;
+    }
+
+    unreachableNodes.add(node);
+  }
+
+  /// Return the target of the `break` or `continue` statement with the
+  /// [element] label. The [element] might be `null` (when the statement does
+  /// not specify a label), so the default enclosing target is returned.
+  AstNode _getLabelTarget(AstNode node, LabelElement element) {
+    for (; node != null; node = node.parent) {
+      if (node is DoStatement ||
+          node is ForStatement ||
+          node is SwitchStatement ||
+          node is WhileStatement) {
+        if (element == null) {
+          return node;
+        }
+        var parent = node.parent;
+        if (parent is LabeledStatement) {
+          for (var nodeLabel in parent.labels) {
+            if (identical(nodeLabel.label.staticElement, element)) {
+              return node;
+            }
+          }
+        }
+      }
+      if (element != null && node is SwitchStatement) {
+        for (var member in node.members) {
+          for (var nodeLabel in member.labels) {
+            if (identical(nodeLabel.label.staticElement, element)) {
+              return node;
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  static bool _isNonNull(Expression node) {
+    if (node is NullLiteral) return false;
+
+    return node is Literal;
+  }
+
+  static bool _isNull(Expression node) {
+    return node is NullLiteral;
+  }
+}
+
+class _FunctionBodyAccess implements FunctionBodyAccess<VariableElement> {
+  final FunctionBody node;
+
+  _FunctionBodyAccess(this.node);
+
+  @override
+  bool isPotentiallyMutatedInClosure(VariableElement variable) {
+    return node.isPotentiallyMutatedInClosure(variable);
+  }
+
+  @override
+  bool isPotentiallyMutatedInScope(VariableElement variable) {
+    return node.isPotentiallyMutatedInScope(variable);
+  }
+}
+
+class _NodeOperations implements NodeOperations<Expression> {
+  @override
+  Expression unwrapParenthesized(Expression node) {
+    return node.unParenthesized;
+  }
+}
+
+class _TypeSystemTypeOperations
+    implements TypeOperations<VariableElement, DartType> {
+  final TypeSystem typeSystem;
+
+  _TypeSystemTypeOperations(this.typeSystem);
+
+  @override
+  DartType elementType(VariableElement element) {
+    return element.type;
+  }
+
+  @override
+  bool isLocalVariable(VariableElement element) {
+    return element is LocalVariableElement;
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return typeSystem.isSubtypeOf(leftType, rightType);
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 2d8ea10..4bfcbba 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -43,7 +44,7 @@
 class ErrorVerifier extends RecursiveAstVisitor<void> {
   /**
    * Properties on the object class which are safe to call on nullable types.
-   * 
+   *
    * Note that this must include tear-offs.
    *
    * TODO(mfairhurst): Calculate these fields rather than hard-code them.
@@ -293,6 +294,10 @@
   /// fixed.
   final bool disableConflictingGenericsCheck;
 
+  /// If running with [_isNonNullable], the result of the flow analysis of the
+  /// unit being verified by this visitor.
+  final FlowAnalysisResult flowAnalysisResult;
+
   /// The features enabled in the unit currently being checked for errors.
   FeatureSet _featureSet;
 
@@ -301,7 +306,7 @@
    */
   ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
       this._typeProvider, this._inheritanceManager, bool enableSuperMixins,
-      {this.disableConflictingGenericsCheck: false})
+      {this.disableConflictingGenericsCheck: false, this.flowAnalysisResult})
       : _errorReporter = errorReporter,
         _uninstantiatedBoundChecker =
             new _UninstantiatedBoundChecker(errorReporter) {
@@ -3395,7 +3400,9 @@
     }
 
     for (var variable in node.variables) {
-      if (variable.initializer == null) {
+      if (variable.initializer == null &&
+          flowAnalysisResult.readBeforeWritten
+              .contains(variable.declaredElement)) {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode
               .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
diff --git a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
index 6a39734..19dc3b0 100644
--- a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
@@ -3,13 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -1307,21 +1304,10 @@
     await resolveTestFile();
 
     var unit = result.unit;
+    var typeSystem = result.typeSystem;
 
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
-      typeSystem,
-      assignedVariables,
-      {},
-      readBeforeWritten,
-      [],
-      [],
-      [],
-      [],
-    ));
+    var flowAnalysisResult = performFlowAnalysis(typeSystem, unit);
+    readBeforeWritten.addAll(flowAnalysisResult.readBeforeWritten);
   }
 }
 
@@ -1624,10 +1610,10 @@
     var unit = result.unit;
 
     var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
+    unit.accept(AssignedVariablesVisitor(assignedVariables));
 
     var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
+    unit.accept(FlowAnalysisVisitor(
       typeSystem,
       assignedVariables,
       {},
@@ -2071,10 +2057,10 @@
     var unit = result.unit;
 
     var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
+    unit.accept(AssignedVariablesVisitor(assignedVariables));
 
     var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
+    unit.accept(FlowAnalysisVisitor(
       typeSystem,
       assignedVariables,
       {},
@@ -2904,10 +2890,10 @@
     var unit = result.unit;
 
     var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
+    unit.accept(AssignedVariablesVisitor(assignedVariables));
 
     var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
+    unit.accept(FlowAnalysisVisitor(
       typeSystem,
       assignedVariables,
       promotedTypes,
@@ -2919,677 +2905,3 @@
     ));
   }
 }
-
-class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
-  final AssignedVariables assignedVariables;
-
-  _AssignedVariablesVisitor(this.assignedVariables);
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var left = node.leftHandSide;
-
-    super.visitAssignmentExpression(node);
-
-    if (left is SimpleIdentifier) {
-      var element = left.staticElement;
-      if (element is VariableElement) {
-        assignedVariables.write(element);
-      }
-    }
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    assignedVariables.beginLoop();
-    super.visitDoStatement(node);
-    assignedVariables.endLoop(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    var forLoopParts = node.forLoopParts;
-    if (forLoopParts is ForParts) {
-      if (forLoopParts is ForPartsWithExpression) {
-        forLoopParts.initialization?.accept(this);
-      } else if (forLoopParts is ForPartsWithDeclarations) {
-        forLoopParts.variables?.accept(this);
-      } else {
-        throw new StateError('Unrecognized for loop parts');
-      }
-
-      assignedVariables.beginLoop();
-      forLoopParts.condition?.accept(this);
-      node.body.accept(this);
-      forLoopParts.updaters?.accept(this);
-      assignedVariables.endLoop(node);
-    } else if (forLoopParts is ForEachParts) {
-      var iterable = forLoopParts.iterable;
-      var body = node.body;
-
-      iterable.accept(this);
-
-      assignedVariables.beginLoop();
-      body.accept(this);
-      assignedVariables.endLoop(node);
-    } else {
-      throw new StateError('Unrecognized for loop parts');
-    }
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    var expression = node.expression;
-    var members = node.members;
-
-    expression.accept(this);
-
-    assignedVariables.beginLoop();
-    members.accept(this);
-    assignedVariables.endLoop(node);
-  }
-
-  @override
-  void visitTryStatement(TryStatement node) {
-    assignedVariables.beginLoop();
-    node.body.accept(this);
-    assignedVariables.endLoop(node.body);
-
-    node.catchClauses.accept(this);
-
-    var finallyBlock = node.finallyBlock;
-    if (finallyBlock != null) {
-      assignedVariables.beginLoop();
-      finallyBlock.accept(this);
-      assignedVariables.endLoop(finallyBlock);
-    }
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    assignedVariables.beginLoop();
-    super.visitWhileStatement(node);
-    assignedVariables.endLoop(node);
-  }
-}
-
-/// [AstVisitor] that drives the [flow] in the way we expect the resolver
-/// will do in production.
-class _AstVisitor extends GeneralizingAstVisitor<void> {
-  static final trueLiteral = astFactory.booleanLiteral(null, true);
-
-  final NodeOperations<Expression> nodeOperations;
-  final TypeOperations<VariableElement, DartType> typeOperations;
-  final AssignedVariables assignedVariables;
-  final Map<AstNode, DartType> promotedTypes;
-  final List<LocalVariableElement> readBeforeWritten;
-  final List<AstNode> nullableNodes;
-  final List<AstNode> nonNullableNodes;
-  final List<AstNode> unreachableNodes;
-  final List<FunctionBody> functionBodiesThatDontComplete;
-
-  FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
-
-  _AstVisitor(
-      TypeSystem typeSystem,
-      this.assignedVariables,
-      this.promotedTypes,
-      this.readBeforeWritten,
-      this.nullableNodes,
-      this.nonNullableNodes,
-      this.unreachableNodes,
-      this.functionBodiesThatDontComplete)
-      : nodeOperations = _NodeOperations(),
-        typeOperations = _TypeSystemTypeOperations(typeSystem);
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var left = node.leftHandSide;
-    var right = node.rightHandSide;
-
-    VariableElement localElement;
-    if (left is SimpleIdentifier) {
-      var element = left.staticElement;
-      if (element is VariableElement) {
-        localElement = element;
-      }
-    }
-
-    if (localElement != null) {
-      var isPure = node.operator.type == TokenType.EQ;
-      if (!isPure) {
-        flow.read(localElement);
-      }
-      right.accept(this);
-      flow.write(
-        localElement,
-        isNull: _isNull(right),
-        isNonNull: _isNonNull(right),
-      );
-    } else {
-      left.accept(this);
-      right.accept(this);
-    }
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    var left = node.leftOperand;
-    var right = node.rightOperand;
-
-    var operator = node.operator.type;
-
-    if (operator == TokenType.AMPERSAND_AMPERSAND) {
-      left.accept(this);
-
-      flow.logicalAnd_rightBegin(node, node.leftOperand);
-      _checkUnreachableNode(node.rightOperand);
-      right.accept(this);
-
-      flow.logicalAnd_end(node, node.rightOperand);
-    } else if (operator == TokenType.BAR_BAR) {
-      left.accept(this);
-
-      flow.logicalOr_rightBegin(node, node.leftOperand);
-      _checkUnreachableNode(node.rightOperand);
-      right.accept(this);
-
-      flow.logicalOr_end(node, node.rightOperand);
-    } else if (operator == TokenType.BANG_EQ) {
-      left.accept(this);
-      right.accept(this);
-      if (right is NullLiteral) {
-        if (left is SimpleIdentifier) {
-          var element = left.staticElement;
-          if (element is VariableElement) {
-            flow.conditionNotEqNull(node, element);
-          }
-        }
-      }
-    } else if (operator == TokenType.EQ_EQ) {
-      left.accept(this);
-      right.accept(this);
-      if (right is NullLiteral) {
-        if (left is SimpleIdentifier) {
-          var element = left.staticElement;
-          if (element is VariableElement) {
-            flow.conditionEqNull(node, element);
-          }
-        }
-      }
-    } else if (operator == TokenType.QUESTION_QUESTION) {
-      left.accept(this);
-
-      flow.ifNullExpression_rightBegin();
-      right.accept(this);
-
-      flow.ifNullExpression_end();
-    } else {
-      left.accept(this);
-      right.accept(this);
-    }
-  }
-
-  @override
-  void visitBlockFunctionBody(BlockFunctionBody node) {
-    var isFlowOwner = flow == null;
-
-    if (isFlowOwner) {
-      flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
-        nodeOperations,
-        typeOperations,
-        _FunctionBodyAccess(node),
-      );
-
-      var function = node.parent;
-      if (function is FunctionExpression) {
-        var parameters = function.parameters;
-        if (parameters != null) {
-          for (var parameter in parameters?.parameters) {
-            flow.add(parameter.declaredElement, assigned: true);
-          }
-        }
-      }
-    }
-
-    super.visitBlockFunctionBody(node);
-
-    if (isFlowOwner) {
-      for (var variable in flow.readBeforeWritten) {
-        assert(variable is LocalVariableElement);
-        readBeforeWritten.add(variable);
-      }
-
-      if (!flow.isReachable) {
-        functionBodiesThatDontComplete.add(node);
-      }
-
-      flow.verifyStackEmpty();
-      flow = null;
-    }
-  }
-
-  @override
-  void visitBooleanLiteral(BooleanLiteral node) {
-    super.visitBooleanLiteral(node);
-    if (_isFalseLiteral(node)) {
-      flow.falseLiteral(node);
-    }
-    if (_isTrueLiteral(node)) {
-      flow.trueLiteral(node);
-    }
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    super.visitBreakStatement(node);
-    var target = _getLabelTarget(node, node.label?.staticElement);
-    flow.handleBreak(target);
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    var condition = node.condition;
-    var thenExpression = node.thenExpression;
-    var elseExpression = node.elseExpression;
-
-    condition.accept(this);
-
-    flow.conditional_thenBegin(node, node.condition);
-    _checkUnreachableNode(node.thenExpression);
-    thenExpression.accept(this);
-    var isBool = thenExpression.staticType.isDartCoreBool;
-
-    flow.conditional_elseBegin(node, node.thenExpression, isBool);
-    _checkUnreachableNode(node.elseExpression);
-    elseExpression.accept(this);
-
-    flow.conditional_end(node, node.elseExpression, isBool);
-  }
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {
-    super.visitContinueStatement(node);
-    var target = _getLabelTarget(node, node.label?.staticElement);
-    flow.handleContinue(target);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    _checkUnreachableNode(node);
-
-    var body = node.body;
-    var condition = node.condition;
-
-    flow.doStatement_bodyBegin(node, assignedVariables[node]);
-    body.accept(this);
-
-    flow.doStatement_conditionBegin();
-    condition.accept(this);
-
-    flow.doStatement_end(node, node.condition);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    _checkUnreachableNode(node);
-
-    ForLoopParts parts = node.forLoopParts;
-    if (parts is ForEachParts) {
-      parts.iterable?.accept(this);
-
-      flow.forEachStatement_bodyBegin(assignedVariables[node]);
-
-      node.body.accept(this);
-
-      flow.forEachStatement_end();
-      return;
-    }
-    VariableDeclarationList variables;
-    Expression initialization;
-    Expression condition;
-    NodeList<Expression> updaters;
-    if (parts is ForPartsWithDeclarations) {
-      variables = parts.variables;
-      condition = parts.condition;
-      updaters = parts.updaters;
-    } else if (parts is ForPartsWithExpression) {
-      initialization = parts.initialization;
-      condition = parts.condition;
-      updaters = parts.updaters;
-    }
-    initialization?.accept(this);
-    variables?.accept(this);
-
-    flow.forStatement_conditionBegin(assignedVariables[node]);
-    if (condition != null) {
-      condition.accept(this);
-    } else {
-      flow.trueLiteral(trueLiteral);
-    }
-
-    flow.forStatement_bodyBegin(node, condition ?? trueLiteral);
-    node.body.accept(this);
-
-    flow.forStatement_updaterBegin();
-    updaters?.accept(this);
-
-    flow.forStatement_end();
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    flow?.functionExpression_begin();
-    super.visitFunctionExpression(node);
-    flow?.functionExpression_end();
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    _checkUnreachableNode(node);
-
-    var condition = node.condition;
-    var thenStatement = node.thenStatement;
-    var elseStatement = node.elseStatement;
-
-    condition.accept(this);
-
-    flow.ifStatement_thenBegin(node, node.condition);
-    thenStatement.accept(this);
-
-    if (elseStatement != null) {
-      flow.ifStatement_elseBegin();
-      elseStatement.accept(this);
-    }
-
-    flow.ifStatement_end(elseStatement != null);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    super.visitIsExpression(node);
-    var expression = node.expression;
-    var typeAnnotation = node.type;
-
-    if (expression is SimpleIdentifier) {
-      var element = expression.staticElement;
-      if (element is VariableElement) {
-        flow.isExpression_end(
-          node,
-          element,
-          node.notOperator != null,
-          typeAnnotation.type,
-        );
-      }
-    }
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    var operand = node.operand;
-
-    var operator = node.operator.type;
-    if (operator == TokenType.BANG) {
-      operand.accept(this);
-      flow.logicalNot_end(node, node.operand);
-    } else {
-      operand.accept(this);
-    }
-  }
-
-  @override
-  void visitRethrowExpression(RethrowExpression node) {
-    super.visitRethrowExpression(node);
-    flow.handleExit();
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    super.visitReturnStatement(node);
-    flow.handleExit();
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    var element = node.staticElement;
-    var isLocalVariable = element is LocalVariableElement;
-    if (isLocalVariable || element is ParameterElement) {
-      if (node.inGetterContext() && !node.inDeclarationContext()) {
-        if (isLocalVariable) {
-          flow.read(element);
-        }
-
-        if (flow.isNullable(element)) {
-          nullableNodes?.add(node);
-        }
-
-        if (flow.isNonNullable(element)) {
-          nonNullableNodes?.add(node);
-        }
-
-        var promotedType = flow?.promotedType(element);
-        if (promotedType != null) {
-          promotedTypes[node] = promotedType;
-        }
-      }
-    }
-
-    super.visitSimpleIdentifier(node);
-  }
-
-  @override
-  void visitStatement(Statement node) {
-    _checkUnreachableNode(node);
-    super.visitStatement(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    _checkUnreachableNode(node);
-
-    node.expression.accept(this);
-    flow.switchStatement_expressionEnd(node);
-
-    var assignedInCases = assignedVariables[node];
-
-    var members = node.members;
-    var membersLength = members.length;
-    var hasDefault = false;
-    for (var i = 0; i < membersLength; i++) {
-      var member = members[i];
-
-      flow.switchStatement_beginCase(
-        member.labels.isNotEmpty ? assignedInCases : assignedVariables.emptySet,
-      );
-      member.accept(this);
-
-      // Implicit `break` at the end of `default`.
-      if (member is SwitchDefault) {
-        hasDefault = true;
-        flow.handleBreak(node);
-      }
-    }
-
-    flow.switchStatement_end(node, hasDefault);
-  }
-
-  @override
-  void visitThrowExpression(ThrowExpression node) {
-    super.visitThrowExpression(node);
-    flow.handleExit();
-  }
-
-  @override
-  void visitTryStatement(TryStatement node) {
-    _checkUnreachableNode(node);
-
-    var body = node.body;
-    var catchClauses = node.catchClauses;
-    var finallyBlock = node.finallyBlock;
-
-    if (finallyBlock != null) {
-      flow.tryFinallyStatement_bodyBegin();
-    }
-
-    flow.tryCatchStatement_bodyBegin();
-    body.accept(this);
-    flow.tryCatchStatement_bodyEnd(assignedVariables[body]);
-
-    var catchLength = catchClauses.length;
-    for (var i = 0; i < catchLength; ++i) {
-      var catchClause = catchClauses[i];
-      flow.tryCatchStatement_catchBegin();
-      catchClause.accept(this);
-      flow.tryCatchStatement_catchEnd();
-    }
-
-    flow.tryCatchStatement_end();
-
-    if (finallyBlock != null) {
-      flow.tryFinallyStatement_finallyBegin(assignedVariables[body]);
-      finallyBlock.accept(this);
-      flow.tryFinallyStatement_end(assignedVariables[finallyBlock]);
-    }
-  }
-
-  @override
-  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    var variables = node.variables.variables;
-    for (var i = 0; i < variables.length; ++i) {
-      var variable = variables[i];
-      flow.add(variable.declaredElement,
-          assigned: variable.initializer != null);
-    }
-
-    super.visitVariableDeclarationStatement(node);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    _checkUnreachableNode(node);
-
-    var condition = node.condition;
-    var body = node.body;
-
-    flow.whileStatement_conditionBegin(assignedVariables[node]);
-    condition.accept(this);
-
-    flow.whileStatement_bodyBegin(node, node.condition);
-    body.accept(this);
-
-    flow.whileStatement_end();
-  }
-
-  /// Mark the [node] as unreachable if it is not covered by another node that
-  /// is already known to be unreachable.
-  void _checkUnreachableNode(AstNode node) {
-    if (flow.isReachable) return;
-
-    // Ignore the [node] if it is fully covered by the last unreachable.
-    if (unreachableNodes.isNotEmpty) {
-      var last = unreachableNodes.last;
-      if (node.offset >= last.offset && node.end <= last.end) return;
-    }
-
-    unreachableNodes.add(node);
-  }
-
-  /// This code has OK performance for tests, but think if there is something
-  /// better when using in production.
-  AstNode _getLabelTarget(AstNode node, LabelElement element) {
-    for (; node != null; node = node.parent) {
-      if (node is DoStatement ||
-          node is ForStatement ||
-          node is SwitchStatement ||
-          node is WhileStatement) {
-        if (element == null) {
-          return node;
-        }
-        var parent = node.parent;
-        if (parent is LabeledStatement) {
-          for (var nodeLabel in parent.labels) {
-            if (identical(nodeLabel.label.staticElement, element)) {
-              return node;
-            }
-          }
-        }
-      }
-      if (element != null && node is SwitchStatement) {
-        for (var member in node.members) {
-          for (var nodeLabel in member.labels) {
-            if (identical(nodeLabel.label.staticElement, element)) {
-              return node;
-            }
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  static bool _isFalseLiteral(AstNode node) {
-    return node is BooleanLiteral && !node.value;
-  }
-
-  static bool _isNonNull(Expression node) {
-    if (node is NullLiteral) return false;
-
-    return node is Literal;
-  }
-
-  static bool _isNull(Expression node) {
-    return node is NullLiteral;
-  }
-
-  static bool _isTrueLiteral(AstNode node) {
-    return node is BooleanLiteral && node.value;
-  }
-}
-
-class _FunctionBodyAccess implements FunctionBodyAccess<VariableElement> {
-  final FunctionBody node;
-
-  _FunctionBodyAccess(this.node);
-
-  @override
-  bool isPotentiallyMutatedInClosure(VariableElement variable) {
-    return node.isPotentiallyMutatedInClosure(variable);
-  }
-
-  @override
-  bool isPotentiallyMutatedInScope(VariableElement variable) {
-    return node.isPotentiallyMutatedInScope(variable);
-  }
-}
-
-class _NodeOperations implements NodeOperations<Expression> {
-  @override
-  Expression unwrapParenthesized(Expression node) {
-    while (node is ParenthesizedExpression) {
-      node = (node as ParenthesizedExpression).expression;
-    }
-    return node;
-  }
-}
-
-class _TypeSystemTypeOperations
-    implements TypeOperations<VariableElement, DartType> {
-  final TypeSystem typeSystem;
-
-  _TypeSystemTypeOperations(this.typeSystem);
-
-  @override
-  DartType elementType(VariableElement element) {
-    return element.type;
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return typeSystem.isSubtypeOf(leftType, rightType);
-  }
-
-  @override
-  bool isLocalVariable(VariableElement element) {
-    return element is LocalVariableElement;
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
index 373e9b5..fb5d0d0 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
@@ -24,6 +24,56 @@
   AnalysisOptionsImpl get analysisOptions =>
       AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
 
+  test_definitelyAssigned_basic() async {
+    assertNoErrorsInCode('''
+void f() {
+  int v;
+  v = 0;
+  v;
+}
+''');
+  }
+
+  test_definitelyAssigned_if_then() async {
+    assertErrorsInCode('''
+void f(bool b) {
+  int v;
+  if (b) {
+    v = 1;
+  }
+  v;
+}
+''', [
+      error(
+          CompileTimeErrorCode
+              .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+          23,
+          1),
+    ]);
+  }
+
+  test_definitelyAssigned_if_thenElse_all() async {
+    assertNoErrorsInCode('''
+void f(bool b) {
+  int v;
+  if (b) {
+    v = 1;
+  } else {
+    v = 2;
+  }
+  v;
+}
+''');
+  }
+
+  test_definitelyAssigned_notUsed() async {
+    assertNoErrorsInCode('''
+void f() {
+  int v;
+}
+''');
+  }
+
   test_hasInitializer() async {
     assertNoErrorsInCode('''
 f() {
@@ -44,6 +94,7 @@
     assertErrorsInCode('''
 f() {
   int v;
+  v;
 }
 ''', [
       error(
@@ -51,7 +102,6 @@
               .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
           12,
           1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 12, 1),
     ]);
   }
 
@@ -59,6 +109,7 @@
     assertErrorsInCode('''
 f<T>() {
   T v;
+  v;
 }
 ''', [
       error(
@@ -66,7 +117,6 @@
               .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
           13,
           1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
     ]);
   }
 
diff --git a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart b/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
index d4b2207..45fc654 100644
--- a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
+++ b/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
@@ -10,20 +10,21 @@
 // TODO(scheglov) Update once we implement definite assignment analysis.
 
 void main() {
-  int v; //# 01: compile-time error
-  int v = 0; //# 02: ok
-  late int v; //# 03: ok
-  late int v = 0; //# 04: ok
-  int? v; //# 05: ok
-  int? v = 0; //# 06: ok
+  int v; v; //# 01: compile-time error
+  int v; //# 02: ok
+  int v = 0; //# 03: ok
+  late int v; //# 04: ok
+  late int v = 0; //# 05: ok
+  int? v; //# 06: ok
+  int? v = 0; //# 07: ok
 
 }
 
 f<T>(T a) {
-  T v; //# 07: compile-time error
-  T v = a; //# 08: ok
-  late T v; //# 09: ok
-  late T v = a; //# 10: ok
-  T? v; //# 11: ok
-  T? v = a; //# 12: ok
+  T v; v; //# 08: compile-time error
+  T v = a; //# 09: ok
+  late T v; //# 10: ok
+  late T v = a; //# 11: ok
+  T? v; //# 12: ok
+  T? v = a; //# 13: ok
 }
