{"action":"created","issue":{"url":"https://api.github.com/repos/dart-lang/sdk/issues/26265","repository_url":"https://api.github.com/repos/dart-lang/sdk","labels_url":"https://api.github.com/repos/dart-lang/sdk/issues/26265/labels{/name}","comments_url":"https://api.github.com/repos/dart-lang/sdk/issues/26265/comments","events_url":"https://api.github.com/repos/dart-lang/sdk/issues/26265/events","html_url":"https://github.com/dart-lang/sdk/issues/26265","id":148442672,"number":26265,"title":"Unpredictable missing strong mode errors when analyzing across files.","user":{"login":"leafpetersen","id":8484504,"avatar_url":"https://avatars.githubusercontent.com/u/8484504?v=3","gravatar_id":"","url":"https://api.github.com/users/leafpetersen","html_url":"https://github.com/leafpetersen","followers_url":"https://api.github.com/users/leafpetersen/followers","following_url":"https://api.github.com/users/leafpetersen/following{/other_user}","gists_url":"https://api.github.com/users/leafpetersen/gists{/gist_id}","starred_url":"https://api.github.com/users/leafpetersen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leafpetersen/subscriptions","organizations_url":"https://api.github.com/users/leafpetersen/orgs","repos_url":"https://api.github.com/users/leafpetersen/repos","events_url":"https://api.github.com/users/leafpetersen/events{/privacy}","received_events_url":"https://api.github.com/users/leafpetersen/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dart-lang/sdk/labels/analyzer-strong-mode","name":"analyzer-strong-mode","color":"d4c5f9"},{"url":"https://api.github.com/repos/dart-lang/sdk/labels/area-analyzer","name":"area-analyzer","color":"c7def8"},{"url":"https://api.github.com/repos/dart-lang/sdk/labels/ddc-beta","name":"ddc-beta","color":"fbca04"},{"url":"https://api.github.com/repos/dart-lang/sdk/labels/P1%20high","name":"P1 high","color":"eb6420"}],"state":"open","locked":false,"assignee":{"login":"scheglov","id":384794,"avatar_url":"https://avatars.githubusercontent.com/u/384794?v=3","gravatar_id":"","url":"https://api.github.com/users/scheglov","html_url":"https://github.com/scheglov","followers_url":"https://api.github.com/users/scheglov/followers","following_url":"https://api.github.com/users/scheglov/following{/other_user}","gists_url":"https://api.github.com/users/scheglov/gists{/gist_id}","starred_url":"https://api.github.com/users/scheglov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scheglov/subscriptions","organizations_url":"https://api.github.com/users/scheglov/orgs","repos_url":"https://api.github.com/users/scheglov/repos","events_url":"https://api.github.com/users/scheglov/events{/privacy}","received_events_url":"https://api.github.com/users/scheglov/received_events","type":"User","site_admin":false},"milestone":null,"comments":5,"created_at":"2016-04-14T18:18:34Z","updated_at":"2016-04-22T22:28:25Z","closed_at":null,"body":"With the following three files:\r\n\r\n// tobounds_a.dart\r\n```dart\r\nclass S<T> {}\r\nclass Remote<T extends S> {\r\n  List<T> get listOfS => [];\r\n  List<S> get listOfS2 => [];\r\n}\r\n```\r\n//tobounds.dart\r\n```dart\r\nimport 'tobounds_a.dart';\r\n\r\nclass Local<T extends S> {\r\n  List<T> get listOfS => [];\r\n  List<S> get listOfS2 => [];\r\n}\r\n\r\nclass B {\r\n  Remote a;\r\n  Local b;\r\n  void test() {\r\n    List l = [];\r\n    a.listOfS.addAll(l); // should be warning\r\n    b.listOfS.addAll(l); // should be warning\r\n    a.listOfS2.addAll(l); // should be warning\r\n    b.listOfS2.addAll(l); // should be warning\r\n  }\r\n}\r\n```\r\n//tobounds_client.dart\r\n```dart\r\nimport 'tobounds_a.dart';\r\nimport 'tobounds.dart';\r\n\r\nvar x = new B();\r\n```\r\n\r\nAnalyzing tobounds.dart directly in strong mode yields three of the four expected errors:\r\n```\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 14, col 22)\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 15, col 23)\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 16, col 23)\r\n3 warnings found.\r\n```\r\n\r\nAnalyzing tobounds_client.dart in strong mode yields all four of the expected errors:\r\n```\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 13, col 22)\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 14, col 22)\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 15, col 23)\r\n[warning] Unsound implicit cast from List<dynamic> to Iterable<S<dynamic>> (/usr/local/google/home/leafp/tmp/tobounds.dart, line 16, col 23)\r\n[hint] Unused import (/usr/local/google/home/leafp/tmp/tobounds_client.dart, line 1, col 8)\r\n4 warnings and 1 hint found.\r\n```\r\n\r\nRemoving the unused import in tobounds_client.dart causes the fourth expected error not to be reported again.\r\n"},"comment":{"url":"https://api.github.com/repos/dart-lang/sdk/issues/comments/213611599","html_url":"https://github.com/dart-lang/sdk/issues/26265#issuecomment-213611599","issue_url":"https://api.github.com/repos/dart-lang/sdk/issues/26265","id":213611599,"user":{"login":"leafpetersen","id":8484504,"avatar_url":"https://avatars.githubusercontent.com/u/8484504?v=3","gravatar_id":"","url":"https://api.github.com/users/leafpetersen","html_url":"https://github.com/leafpetersen","followers_url":"https://api.github.com/users/leafpetersen/followers","following_url":"https://api.github.com/users/leafpetersen/following{/other_user}","gists_url":"https://api.github.com/users/leafpetersen/gists{/gist_id}","starred_url":"https://api.github.com/users/leafpetersen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leafpetersen/subscriptions","organizations_url":"https://api.github.com/users/leafpetersen/orgs","repos_url":"https://api.github.com/users/leafpetersen/repos","events_url":"https://api.github.com/users/leafpetersen/events{/privacy}","received_events_url":"https://api.github.com/users/leafpetersen/received_events","type":"User","site_admin":false},"created_at":"2016-04-22T22:28:25Z","updated_at":"2016-04-22T22:28:25Z","body":"Oh, that's a fun one!  I think it would possible to make it an error and detect it - it would look something like typedef cycle detection.  So when you get to `A<B<A>>` and ask what the expansion of `A` is, you make it a circular type error.\r\n\r\nAn alternative would be to say that in bounds, `extends A` means `extends A<dynamic>`, which in this case would then generate an error since `dynamic` does not extend `B`.  This feels a bit ad-hoc though.  I wonder if there's something in between the two?\r\n\r\nYet another alternative would be to forbid implicit instantiation in bounds for things with a non-default bound.  \r\n\r\nI'd suggest filing a separate bug for the language issue, and in the meantime seeing if there's something pragmatic we can do to fix the immediate issue.  For example, if it would be possible to implement a version which does the right thing for top level uses, and instantiates all uses in bounds to dynamic, then this would at least put us in a stable position.  If doing this is pretty straightforward, I'd suggest doing this for now.  If doing even this much requires substantial changes that might have to be backed out if we do something else, then perhaps we should discuss more first."}}