{"action":"closed","issue":{"url":"https://api.github.com/repos/dart-lang/sdk/issues/32130","repository_url":"https://api.github.com/repos/dart-lang/sdk","labels_url":"https://api.github.com/repos/dart-lang/sdk/issues/32130/labels{/name}","comments_url":"https://api.github.com/repos/dart-lang/sdk/issues/32130/comments","events_url":"https://api.github.com/repos/dart-lang/sdk/issues/32130/events","html_url":"https://github.com/dart-lang/sdk/issues/32130","id":296564567,"node_id":"MDU6SXNzdWUyOTY1NjQ1Njc=","number":32130,"title":"Type inference in fasta doesn't work for redirecting factory constructors with more than one type arguments","user":{"login":"stefantsov","id":519320,"node_id":"MDQ6VXNlcjUxOTMyMA==","avatar_url":"https://avatars1.githubusercontent.com/u/519320?v=4","gravatar_id":"","url":"https://api.github.com/users/stefantsov","html_url":"https://github.com/stefantsov","followers_url":"https://api.github.com/users/stefantsov/followers","following_url":"https://api.github.com/users/stefantsov/following{/other_user}","gists_url":"https://api.github.com/users/stefantsov/gists{/gist_id}","starred_url":"https://api.github.com/users/stefantsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefantsov/subscriptions","organizations_url":"https://api.github.com/users/stefantsov/orgs","repos_url":"https://api.github.com/users/stefantsov/repos","events_url":"https://api.github.com/users/stefantsov/events{/privacy}","received_events_url":"https://api.github.com/users/stefantsov/received_events","type":"User","site_admin":false},"labels":[{"id":524536392,"node_id":"MDU6TGFiZWw1MjQ1MzYzOTI=","url":"https://api.github.com/repos/dart-lang/sdk/labels/area-front-end","name":"area-front-end","color":"c5def5","default":false},{"id":520924985,"node_id":"MDU6TGFiZWw1MjA5MjQ5ODU=","url":"https://api.github.com/repos/dart-lang/sdk/labels/front-end-fasta","name":"front-end-fasta","color":"d4c5f9","default":false}],"state":"closed","locked":false,"assignee":{"login":"stereotype441","id":306375,"node_id":"MDQ6VXNlcjMwNjM3NQ==","avatar_url":"https://avatars2.githubusercontent.com/u/306375?v=4","gravatar_id":"","url":"https://api.github.com/users/stereotype441","html_url":"https://github.com/stereotype441","followers_url":"https://api.github.com/users/stereotype441/followers","following_url":"https://api.github.com/users/stereotype441/following{/other_user}","gists_url":"https://api.github.com/users/stereotype441/gists{/gist_id}","starred_url":"https://api.github.com/users/stereotype441/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stereotype441/subscriptions","organizations_url":"https://api.github.com/users/stereotype441/orgs","repos_url":"https://api.github.com/users/stereotype441/repos","events_url":"https://api.github.com/users/stereotype441/events{/privacy}","received_events_url":"https://api.github.com/users/stereotype441/received_events","type":"User","site_admin":false},"assignees":[{"login":"stereotype441","id":306375,"node_id":"MDQ6VXNlcjMwNjM3NQ==","avatar_url":"https://avatars2.githubusercontent.com/u/306375?v=4","gravatar_id":"","url":"https://api.github.com/users/stereotype441","html_url":"https://github.com/stereotype441","followers_url":"https://api.github.com/users/stereotype441/followers","following_url":"https://api.github.com/users/stereotype441/following{/other_user}","gists_url":"https://api.github.com/users/stereotype441/gists{/gist_id}","starred_url":"https://api.github.com/users/stereotype441/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stereotype441/subscriptions","organizations_url":"https://api.github.com/users/stereotype441/orgs","repos_url":"https://api.github.com/users/stereotype441/repos","events_url":"https://api.github.com/users/stereotype441/events{/privacy}","received_events_url":"https://api.github.com/users/stereotype441/received_events","type":"User","site_admin":false},{"login":"stefantsov","id":519320,"node_id":"MDQ6VXNlcjUxOTMyMA==","avatar_url":"https://avatars1.githubusercontent.com/u/519320?v=4","gravatar_id":"","url":"https://api.github.com/users/stefantsov","html_url":"https://github.com/stefantsov","followers_url":"https://api.github.com/users/stefantsov/followers","following_url":"https://api.github.com/users/stefantsov/following{/other_user}","gists_url":"https://api.github.com/users/stefantsov/gists{/gist_id}","starred_url":"https://api.github.com/users/stefantsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefantsov/subscriptions","organizations_url":"https://api.github.com/users/stefantsov/orgs","repos_url":"https://api.github.com/users/stefantsov/repos","events_url":"https://api.github.com/users/stefantsov/events{/privacy}","received_events_url":"https://api.github.com/users/stefantsov/received_events","type":"User","site_admin":false}],"milestone":null,"comments":2,"created_at":"2018-02-12T23:42:22Z","updated_at":"2018-07-06T09:09:19Z","closed_at":"2018-07-06T09:09:19Z","author_association":"CONTRIBUTOR","body":"Consider the following example:\r\n\r\n```dart\r\nclass A<T> {\r\n  factory A() = B<T, num>;\r\n  A.empty();\r\n}\r\n\r\nclass B<U, W> extends A<U> {\r\n  B(): super.empty();\r\n  toString() => \"${U},${W}\";\r\n}\r\n\r\nmain() {\r\n  var a = new A<int>();\r\n}\r\n```\r\n\r\nThe expected inferred type of variable `a` is `A<int>`.  However, the following Kernel code is produced:\r\n\r\n```bash\r\n$ pkg/front_end/tool/fasta compile --strong --dump-ir /tmp/example.dart\r\nNote: strong mode support is preliminary and may not work.\r\nlibrary;\r\nimport self as self;\r\nimport \"dart:core\" as core;\r\n\r\nclass A<T extends core::Object> extends core::Object {\r\n  static field dynamic _redirecting# = <dynamic>[self::A::•];\r\n  constructor empty() → void\r\n    : super core::Object::•()\r\n    ;\r\n  static factory •<T extends core::Object>() → self::A<self::A::•::T>\r\n    let dynamic #redirecting_factory = self::B::• in invalid-expression;\r\n}\r\nclass B<U extends core::Object, W extends core::Object> extends self::A<self::B::U> {\r\n  constructor •() → void\r\n    : super self::A::empty()\r\n    ;\r\n  method toString() → core::String\r\n    return \"${self::B::U},${self::B::W}\";\r\n}\r\nstatic method main() → dynamic {\r\n  self::A<dynamic> a = new self::B::•<dynamic, dynamic>();\r\n}\r\n```\r\n\r\nIt shows that the inferred type of `a` is `A<dynamic>`.\r\n\r\nIn contrast, when `B` has only one type parameter, type inference produces the expected result.\r\n\r\nThe Dart program:\r\n\r\n```dart\r\nclass A<T> {\r\n  factory A() = B<T>;\r\n  A.empty();\r\n}\r\n\r\nclass B<U> extends A<U> {\r\n  B(): super.empty();\r\n  toString() => \"${U}\";\r\n}\r\n\r\nmain() {\r\n  var a = new A<int>();\r\n}\r\n```\r\n\r\nThe corresponding compiler output in Kernel:\r\n\r\n```bash\r\n$ pkg/front_end/tool/fasta compile --strong --dump-ir /tmp/example2.dart\r\nNote: strong mode support is preliminary and may not work.\r\nlibrary;\r\nimport self as self;\r\nimport \"dart:core\" as core;\r\n\r\nclass A<T extends core::Object> extends core::Object {\r\n  static field dynamic _redirecting# = <dynamic>[self::A::•];\r\n  constructor empty() → void\r\n    : super core::Object::•()\r\n    ;\r\n  static factory •<T extends core::Object>() → self::A<self::A::•::T>\r\n    let dynamic #redirecting_factory = self::B::• in invalid-expression;\r\n}\r\nclass B<U extends core::Object> extends self::A<self::B::U> {\r\n  constructor •() → void\r\n    : super self::A::empty()\r\n    ;\r\n  method toString() → core::String\r\n    return \"${self::B::U}\";\r\n}\r\nstatic method main() → dynamic {\r\n  self::A<core::int> a = new self::B::•<core::int>();\r\n}\r\n```"}}
{"actor":{"display_login":"dart-bot"}}