0

Reading this article https://dart.dev/tools/non-promotion-reasons, after I encountered a promotion issue in this code:

class UserViewModel extends ChangeNotifier {
  final UserRepository _userRepo = UserRepository();
  LocationData? currentLocationValue;

  Future<bool> savePosition() async {
    if (currentLocationValue != null) {
      return _userRepo.saveUserPositioninProfile(
          currentLocation: currentLocationValue); // <- ERROR: 'currentLocationValue' refers to a property so it couldn't be promoted.
    } else {
      return Future.value(false);
    }
  }
}

Why is it a problem for Dart to promote a field value? I am doing the null check right before the usage, how could the field still be null after my check?

I've read this explanation:

Flow-based type promotion does not apply to fields because the static analysis cannot prove that the field’s value doesn’t change between the point that you check for null and the point that you use it.

But I still cannot comprehend a real example, where the value could change if the check happens right before the usage of the variable.

Big_Chair
  • 2,781
  • 3
  • 31
  • 58
  • 1
    concurrent threads possibly still could change it after the if and before the line after the if – Ivo Apr 14 '23 at 11:18
  • 1
    @Ivo Not from pure Dart code. Dart has isolates, not threads. – jamesdlin Apr 14 '23 at 14:46
  • 2
    The property can be overridden in a subclass to be a getter that returns a different value each time it is fetched. I have a video on this: https://www.youtube.com/watch?v=rqS_Q34RcUk. Locals cannot be overridden, and there are proposals to do some sort of static analysis of private classes to enable promotion in certain cases. – Randal Schwartz Apr 14 '23 at 18:37
  • @RandalSchwartz Yeah I have been reading through this proposal here: https://github.com/dart-lang/language/issues/1188. And as the poster there says, this subclass override reasoning is not the strongest, as it seems like 95% of users are being held back on functionality for the edge cases of 5% of users. – Big_Chair Apr 14 '23 at 18:41
  • You cannot have the analyzer promote types unsafely though. And there are workarounds. And there are proposals for additional annotation to make it safe. I don't know what your 95%/5% argument is revealing, other than we must allow for the 5%. – Randal Schwartz Apr 14 '23 at 20:21
  • @RandalSchwartz Certainly. What I meant is: from my perspective, the default implementation should cater to the majority of "simple" use cases and the 5% with edge cases should be the ones who should need workarounds. But I can see that it's easier said than done. Though, coming from Swift, they also found safe ways to let users unwrap optionals there with `if let x = fieldX` (which now that I think about it, is simply just a local copy workaround as in Dart, but with more syntax sugar :)) – Big_Chair Apr 15 '23 at 07:03

0 Answers0