anchor.diff:      _propagateDownstream();
     }
   
  +  Iterable<_NullabilityEdge> _getDownstreamEdges(NullabilityNode node) {
  +    if (node is NullabilityNodeMutable) {
  +      return node._downstreamEdges;
  +    } else if (node == NullabilityNode.always) {
  +      return _downstreamFromAlways;
  +    } else {
  +      // No nodes are downstream from `never`.
  +      assert(node == NullabilityNode.never);
  +      return const [];
  +    }
  +  }
  +
     /// Propagates nullability downstream.
     void _propagateDownstream() {
  -    var pendingEdges = <_NullabilityEdge>[]
  -      ..addAll(_downstream[NullabilityNode.always] ?? const []);
  +    var pendingEdges = <_NullabilityEdge>[]..addAll(_downstreamFromAlways);
       var pendingSubstitutions = <NullabilityNodeForSubstitution>[];
       while (true) {
         nextEdge:
         while (pendingEdges.isNotEmpty) {
           var edge = pendingEdges.removeLast();
           var node = edge.destinationNode;
  -        if (_nonNullIntentNodes.contains(node)) {
  +        if (node.hasNonNullIntent) {
             // Non-null intent nodes are never made nullable; a null check will need
             // to be added instead.
             continue;
  
positive.code:   ///
    /// There is no guarantee of uniqueness of the iterated nodes.
    Iterable<NullabilityNode> getUnconditionalUpstreamNodes(
            NullabilityNode node) =>
        _unconditionalUpstream[node] ?? const [];
  
    /// Iterates through all nodes that are "upstream" of [node] (i.e. if
    /// any of the iterated nodes are nullable, then [node] will either have to be
  
negative.code: abstract class NullabilityNodeMutable extends NullabilityNode {
    bool _isNullable = false;
  
    bool _hasNonNullIntent = false;
  
    /// List of [_NullabilityEdge] objects describing this node's relationship to
    /// other nodes that are "downstream" from it (meaning that if a key node is
    /// nullable, then all the nodes in the corresponding value will either have
    /// to be nullable, or null checks will have to be added).
    final _downstreamEdges = <_NullabilityEdge>[];
  
    /// List of nodes that are "upstream" from this node via unconditional control
    /// flow (meaning that if a node in the list is nullable, then there exists
    /// code that is unguarded by an "if" statement that indicates that this node
    /// will have to be nullable, or null checks will have to be added).
    final _unconditionalUpstreamNodes = <NullabilityNode>[];
  
    NullabilityNodeMutable._() : super._();
  
    @override
    bool get hasNonNullIntent => _hasNonNullIntent;
  
    @override
    bool get isNullable => _isNullable;
  
    /// During nullability propagation, this method marks the type as nullable, or
    /// does nothing if the type was already nullable.
    ///
    /// Return value indicates whether a change was made.
    bool _becomeNullable() {
      if (_isNullable) return false;
      _isNullable = true;
      return true;
    }
  
    /// During nullability propagation, this method marks the type as having
    /// non-null intent, or does nothing if the type was already marked as having
    /// non-null intent.
    ///
    /// Return value indicates whether a change was made.
    bool _setNonNullIntent() {
      if (_hasNonNullIntent) return false;
      _hasNonNullIntent = true;
      return true;
    }
  }
  