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-10767] Generic type inference inconsistency & specificity issue when return value is optional or not. #53157

Open
swift-ci opened this issue May 24, 2019 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

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

md5: 59d97d497440eda28dff06be3f28f0ab

Issue Description:

In the following example, `X` resolves to the (more specific) argument type when the function's return type is non-optional but resolves to the (less specific) return type when the function's return type is optional.

The rational for this is unclear and the behaviour appears to be an inconsistency.

Furthermore, it is unclear why f1 would opt to resolve X against the subtype B when the more generic type A is sufficient to solve the type constraints. Resolving X against B needlessly narrows the return type when the function should be perfectly capable of returning any more generic type-A instance.

class A     {}
class B : A {}

func f1<X>( _ v: X ) -> X  {
    print(X.self) // prints B
    return v
}
func f2<X>( _ v: X? ) -> X? {
    print(X.self) // prints A
    return v
}

let _ : A  = f1( B() )
let _ : A? = f2( B() )
@belkadan
Copy link
Contributor

It's consistent, but I agree it's not so useful. What's happening is that the conversion B -> A is being treated as cheaper than the conversion B? -> A?.

cc @xedin

@swift-ci
Copy link
Collaborator Author

Comment by Maarten Billemont (JIRA)

What puzzles me is the fact that type weakening isn't happening here.

f1 has essentially two solutions:

  1. X resolves to the argument's type (ie. B)

  2. X resolves to the return value's type (ie. A)

The compiler chooses option [1]. But I'm unsure why the compiler doesn't choose the solution with the weaker type.

@belkadan
Copy link
Contributor

The compiler tries not to weaken types when it doesn't have to, which is generally what you want. Otherwise, it could evaluate f1(B()) with a type of Any

@swift-ci
Copy link
Collaborator Author

Comment by Maarten Billemont (JIRA)

Is there any method for communicating that I'm looking for it to resolve against the weaker type?

If it were legal, I might have gone with:

func f1<X, Y:X>( _ v: Y ) -> X  {
    print(X.self)
    return v
}

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
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 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants