Skip to content

[Analyzer] Nullsafety on final after if, gives an error #47456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ikbendewilliam opened this issue Oct 14, 2021 · 2 comments
Closed

[Analyzer] Nullsafety on final after if, gives an error #47456

ikbendewilliam opened this issue Oct 14, 2021 · 2 comments
Labels
closed-duplicate Closed in favor of an existing report

Comments

@ikbendewilliam
Copy link

Small issue with the analyser regarding to nullsafety
I'm using version Dart SDK version: 2.14.2 (stable) (Wed Sep 15 12:32:06 2021 +0200) on "macos_x64"

We have the following flutter code. _controller is a nullable InAppWebViewController?. To not have to include a ! when we use it, we add a final final controller = _controller and do a check await controller?.canGoBack() == true. In this case, controller is never null, since controller?.anything will return null and null != true 😁. Therefore await controller.goBack(); should be fine, but it throws an error.
The method 'goBack' can't be unconditionally invoked because the receiver can be 'null'. Try making the call conditional (using '?.') or adding a null check to the target ('!').dart(unchecked_use_of_nullable_value)

  Widget build(BuildContext context) {
    final controller = _controller;
      return WillPopScope(
        onWillPop: () async {
          if (await controller?.canGoBack() == true) {
            await controller.goBack();
            return false;
          }
          return true;
        },

if we instead do

if (controller != null && await controller.canGoBack() == true) {
  await controller.goBack();
...

no errors are thrown. And everything compiles.
If I simplify the code further, this becomes more apparent:

onBackClicked: () async {
  final controller = _controller;
  if (controller?.canGoBack == true) {
    controller.goBack(); <-- The method 'goBack' can't be unconditionally invoked because the receiver can be 'null'.
    return;
  }

Is there any way that controller can be null?
Otherwise, I would suggest to check if the analyser can detect this and allow us to not have to check for null again.

@lrhn
Copy link
Member

lrhn commented Oct 14, 2021

Dart promotes the types of variables when you do certain checks on the variable itself.

Here the controller != null check will promote the controller variable to a non-null type along the true branch.

The check controller?.canGoBack == true does not check the variable controller directly, so there is no promotion.
It's logically correct that if controller?.canGoBack is the non-null value true, then controller cannot be null, but that's more logical inference steps than the compiler will do for you.

We are aware of this short-coming (see dart-lang/language#1224). We haven't decided whether to increase the complexity of the non-null inference to support this case yet.

@lrhn lrhn closed this as completed Oct 14, 2021
@lrhn lrhn added the closed-duplicate Closed in favor of an existing report label Oct 14, 2021
@ikbendewilliam
Copy link
Author

Oke, thank you for your response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-duplicate Closed in favor of an existing report
Projects
None yet
Development

No branches or pull requests

2 participants