anchor.diff:  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 constraint solving, this method marks the type as nullable, or does
  -  /// nothing if the type was already nullable.
  +  /// 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() {
  +  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;
     }
   }
  
positive.code:     _propagateDownstream();
    }
  
    /// Propagates nullability downstream.
    void _propagateDownstream() {
      var pendingEdges = <_NullabilityEdge>[]
        ..addAll(_downstream[NullabilityNode.always] ?? const []);
      var pendingSubstitutions = <NullabilityNodeForSubstitution>[];
      while (true) {
        nextEdge:
        while (pendingEdges.isNotEmpty) {
          var edge = pendingEdges.removeLast();
          var node = edge.destinationNode;
          if (_nonNullIntentNodes.contains(node)) {
            // Non-null intent nodes are never made nullable; a null check will need
            // to be added instead.
            continue;
  
negative.code:   ///
    /// There is no guarantee of uniqueness of the iterated nodes.
    Iterable<NullabilityNode> getUnconditionalUpstreamNodes(
        NullabilityNode node) {
      if (node is NullabilityNodeMutable) {
        return node._unconditionalUpstreamNodes;
      } else if (node == NullabilityNode.never) {
        return _unconditionalUpstreamFromNever;
      } else {
        // No nodes are upstream from `always`.
        assert(node == NullabilityNode.always);
        return 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
  