Skip to content

Possible bug? foo["a"]="b" results in TypeError, even if foo is a Map<String,dynamic> #892

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
sloisel opened this issue Mar 23, 2020 · 1 comment
Labels
bug There is a mistake in the language specification or in an active document

Comments

@sloisel
Copy link

sloisel commented Mar 23, 2020

I think I understand why this "bug" happens but it was so baffling, my head did a couple of turns like in the exorcist when it happened. Consider this code:

Map fixprobset(Map<String,dynamic> P) {
  if(!P.containsKey("name")) {
    P["name"] = (P["tileset"] as List<String>).join(" ");
  }
  if(P.containsKey("children")) {
    final Q = P["children"];
    for(var k=0; k<Q.length;k++) Q[k] = fixprobset(Q[k]);
  }
  return P;
}

One would expect the parameter P to be of type Map<String,dynamic>, since that's what it says right there, but sometimes P.runtimeType is, e.g. Map<String,List<String>> and then the line P["name"]=... results in a baffling run-time TypeError. By abusing Map<String,dynamic>.from() and friends, I was able to get around this but it seems like a crazy way to do things. It was even more bizarre in my case because, by adding one field to my data structure, whichever map was getting runtimeTyped to Map<String,List>, was instead correctly typed as Map<String,dynamic>, which was getting around the real problem here, which is that the compiler ignores my type declaration in the parameter list of the function.

Here's a gist:

https://dartpad.dev/d041fe1d97bf1f6a378a45bc81cb4f28

@sloisel sloisel added the bug There is a mistake in the language specification or in an active document label Mar 23, 2020
@leafpetersen
Copy link
Member

Dart 2 generics are unsoundly covariant for historical reasons, with the consequence that errors like the above are only caught at runtime. There's a proposal to add sound variance to Dart. You can see some of the concrete proposals linked from here, and an article about the declaration site variance proposal here, written by my intern from last fall who implemented this in several of our tools.

Since this is (somewhat unfortunately) working as intended at the moment, I'm going to close this out in favor of the existing issues linked above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug There is a mistake in the language specification or in an active document
Projects
None yet
Development

No branches or pull requests

2 participants