Skip to content
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

[SR-1789] Swift can't infer types in generic methods that reuse part of the struct/class' parameters #44398

Open
swift-ci opened this issue Jun 16, 2016 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jun 16, 2016

Previous ID SR-1789
Radar None
Original Reporter robotlolita (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, LanguageFeatureRequest, TypeChecker
Assignee None
Priority Medium

md5: 0101359cc12f70fff9f02db7121d39ee

is duplicated by:

  • SR-514 Generic type cannot construct itself with a transformed type
  • SR-4155 Generic argument deduction disabled in generic context
  • SR-8401 Generic class, type aliases and type inference at compile for a static function on a generic class
  • SR-10765 Dictionary(uniqueKeysWithValues: ) in Dictionary extension causes error
  • SR-11472 Generic parameter inference problem

relates to:

  • SR-4247 Generic Factory Method on Struct Reports Unhelpful Type Error

Issue Description:

The following code fails because Swift can't infer the types:

struct Product<A, B> { 
    let left: A 
    let right: B 
     
    func map<C>(f: (A) -> C) -> Product<C, B> { 
        return Product(left: f(left), right: right) 
    } 
}

Running this results in the following type error:

error: repl.swift:6:23: error: '(left: C, right: B)' is not convertible to '(left: A, right: B)'
        return Product(left: f(left), right: right)
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

What I Expected

Given that the return value for the generic type says `Product<C, B>`, that's what I would have expected Swift to infer the type as, in which case the code should type check. But instead Swift is inferring it as `Product<A, B>`.

A different❓ type inference error occurs when you have a tuple for the values there instead of the values in separated fields. In this case, Swift infers the tuple to be `(_, _)`.

struct Product<A, B> { 
    let values: (A, B)
     
    func map<C>(f: (A) -> C) -> Product<C, B> { 
        let (a, b) = values
        return Product(values: (f(a), b))
    } 
} 
error: repl.swift:6:32: error: cannot convert value of type '(C, B)' to expected argument type '(_, _)'
        return Product(values: (f(a), b))
                               ^~~~~~~~~

In both cases I expected the code to type check correctly.

@belkadan
Copy link
Contributor

Just to confirm, this does work when you explicitly say Product<C, B>, so it seems to be a case of us eagerly assuming the parameters are the same as for self. (That's usually a feature, but not when it gets in the way of other inference.)

@belkadan
Copy link
Contributor

Some minor discussion on SR-4155 about this determines that we'd be open to changing this, but we'd want to put it through the Swift Evolution Process.

@mdiep
Copy link
Contributor

mdiep commented Jun 15, 2018

This seems like a duplicate of SR-514?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

3 participants