Skip to content

null is not legal from Map<String, Object> from analyzer #48477

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
drpond1 opened this issue Feb 26, 2022 · 8 comments
Closed

null is not legal from Map<String, Object> from analyzer #48477

drpond1 opened this issue Feb 26, 2022 · 8 comments

Comments

@drpond1
Copy link

drpond1 commented Feb 26, 2022

No description provided.

@drpond1
Copy link
Author

drpond1 commented Feb 26, 2022

Using IntelliJ with Dart 2.16

I do not understand the behavior of the following:

Object s= getObject();
if (s is Map) {
   s= s["fluffy"];
}

This is not reported as an error. However, I thought the return value was null if the Map did not contain the key ???

Not a problem for me, as I just changed the code to

  Object s= getObject();
  if (s is Map) {
    Object? temp= s["fluffy"];
    if (temp==null) {
     ...do something...
   }  else {
     s=temp;
  } 
}

If this really is an error I will generate and test code that exhibits the behavior.
The above was just summarized from my current code.

@lrhn
Copy link
Member

lrhn commented Feb 26, 2022

I do get a warning about Object? not being assignable to Object when I try the code in DartPad.

Is your project using language version Dart 2.12 or later, by setting the SDK version to >=2.12.0 in pubspec.yaml?
(That is, can you write Object? s = ... instead and have the compiler accept it?)

If not, then your code is still being compiled as pre-Null Safety code.

@drpond1
Copy link
Author

drpond1 commented Feb 26, 2022

I am using the null safe version of the compiler. I use ! and late etc without problems.
I will generate and check a simple example, to be sure I did not make a misatke.

@drpond1
Copy link
Author

drpond1 commented Feb 26, 2022

Made a transcription mistake. I used
if (s is Map)

Here is the short example that I checked.

class Huh {
  Object s= new Map<String, Object>();
  Huh();
  exec() {
    Object t=s;
    if (t is Map) {
      t=t["fluff"];
    }
  }
}

@lrhn
Copy link
Member

lrhn commented Feb 26, 2022

That explains it. Doing t is Map promotes t to Map<dynamic, dynamic>.
That makes the assignment t = t["fluff"]; be an assignment from dynamic to Object, which is allowed as an implicit downcast from dynamic.

So, it's all because of an implicit dynamic.

@drpond1
Copy link
Author

drpond1 commented Feb 26, 2022

I would expect that t=null would not be allowed because t is of type Object and not
Object?. Yet this is possible with
t=t["fluff"] for any Map.

The type of B for Map<A,B> does not matter for type safety when accessing the result of a map. The type of the result is always nullable.

Well I can see why a runtime check could be used, but in this case there is a clear
error in the code known at compile time.
The null safety check could be made stronger.

You answered my question, so thank you for your help.

@drpond1
Copy link
Author

drpond1 commented Feb 26, 2022

I found this issue mentioned earlier as part of open issue #1324

void main(List<String> args) { Map<String, dynamic> l = {"a": "a"}; 
String b = l["b"]; // runtime error }

"If null safety is about the compiler catching possible null assignments, then dynamic spoils this."

So this "new" issue should be closed.

Thank you again for your help.

@lrhn
Copy link
Member

lrhn commented Feb 26, 2022

The type dynamic turns off all static type checks. Nullability is just one of those.

Example:

Map<String, dynamic> map = <String, String>{"x": "a string"};
int number = map["x"]; // No warning, guaranteed run-time error.

Heck, even

int x = "not an int" as dynamic;

will compiler fine and throw at runtime. That's what dynamic exists for: Dodging static type checking. You just have to be very careful when you use it, which is why it's problematic when you get dynamic implicitly. But that's another issue.

@lrhn lrhn closed this as completed Feb 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants