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-12897] "\.self" not working with keypath-as-function - Examples in Key Path Expressions as Functions proposal don't compile #55343

Closed
swift-ci opened this issue May 28, 2020 · 8 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself expressions Feature: expressions implicit conversions Feature: implicit conversions key paths Feature: key paths (both native and Objective-C) swift 5.10 type checker Area → compiler: Semantic analysis unexpected error Bug: Unexpected error

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-12897
Radar rdar://problem/63819463
Original Reporter mozeryansky (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 4
Component/s Compiler
Labels Bug, TypeChecker
Assignee None
Priority Medium

md5: 51619b34af87072237ed5a533887a7df

cloned to:

  • SR-12991 Type checker doesn't take context from " as " - Examples in Key Path Expressions as Functions proposal don't compile

Issue Description:

The proposal which was Implemented in Swift 5.2 for Key Path Expressions as Functions has examples which do not compile. https://github.com/apple/swift-evolution/blob/master/proposals/0249-key-path-literal-function-expressions.md

When run in a playground:

[Edited to remove symptoms of a separate bug tracked as SR-12991.]

[1, nil, 3, nil, 5].compactMap(\.self) // Error: Type of expression is ambiguous without more context
let x: [Int] = [1, nil, 3, nil, 5].compactMap(\.self) // Error: Cannot convert value of type 'WritableKeyPath<_, _>' to expected argument type '(Int?) throws -> Int?'

My biggest issue is the inability to use `(.self)` as a lot of my uses of `compactMap` involve filtering nil values in the array and not based on a property.

@typesanitizer
Copy link

@swift-ci create

@LucianoPAlmeida
Copy link
Collaborator

Just an update with what we are seeing on the 2020-05-22 master snapshot.

struct User {
    let email: String
}

let users = [User]()
let f3 = \User.email as (User) -> String // Cannot convert value of type 'KeyPath<User, String>' to type '(User) -> String' in coercion
users.map(f3)

[1, nil, 3, nil, 5].compactMap(\.self) // Cannot convert value of type 'WritableKeyPath<_, _>' to expected argument type '(Int?) throws -> ElementOfResult?'
// Cannot infer key path type from context; consider explicitly specifying a root type fix-it root
// Generic parameter 'ElementOfResult' could not be inferred

let x: [Int] = [1, nil, 3, nil, 5].compactMap(\.self) // Cannot convert value of type 'WritableKeyPath<_, _>' to expected argument type '(Int?) throws -> Int?'
// Cannot infer key path type from context; consider explicitly specifying a root type.

@beccadax
Copy link
Contributor

On investigation, the \User.email issue seems to be separate from the .self one. Since you said .self is more important to you, I've cloned the \User.email issue as SR-12991 and we'll use this report solely to track the .self bug.

@beccadax
Copy link
Contributor

In a near-release/5.3 Swift, I see better diagnostics but not better behavior:

<stdin>:1:1: error: generic parameter 'ElementOfResult' could not be inferred
[1, nil, 3, nil, 5].compactMap(\.self)
^
Swift.Sequence:2:28: note: in call to function 'compactMap'
    @inlinable public func compactMap<ElementOfResult>(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
                           ^
<stdin>:1:32: error: cannot convert value of type 'WritableKeyPath<_, _>' to expected argument type '(Int?) throws -> ElementOfResult?'
[1, nil, 3, nil, 5].compactMap(\.self)
                               ^
<stdin>:1:32: error: cannot infer key path type from context; consider explicitly specifying a root type
[1, nil, 3, nil, 5].compactMap(\.self)
                               ^
                                <#Root#>

The problem appears to be specific to self. For instance, this compiles just fine:

extension Optional { var mySelf: Self { self } }

[1, nil, 3, nil, 5].compactMap(\.mySelf)

Whereas even simpler .self expressions, like [1, 3, 5].map(.self), fail.

@swift-ci
Copy link
Collaborator Author

Comment by Michael Ozeryansky (JIRA)

brentdax (JIRA User) Awesome, thanks. I'm glad there's a slight workaround if I really want the syntax, good find.

@mattyoung
Copy link

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 8, 2021

Comment by Frederick Kellison-Linn (JIRA)

It looks to me like this happens during constraint simplification when the entire key path literal can be resolved before we have the necessary external context to determine whether the literal should be a function or a key path. In such a situation we assume that it will resolve to a key path... but in a situation like `.self` we can trivially resolve the keypath during constraint generation and so we never even have a chance to get the function type context.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@xedin
Copy link
Member

xedin commented Dec 8, 2023

I think this has been fixed by combination of the following PRs - #69742, #69742. All of the expressions mentioned in the description now type-check.

Please use the latest main compiler snapshot to verify and re-open.

@xedin xedin closed this as completed Dec 8, 2023
@AnthonyLatsis AnthonyLatsis added key paths Feature: key paths (both native and Objective-C) expressions Feature: expressions unexpected error Bug: Unexpected error implicit conversions Feature: implicit conversions swift 5.10 labels Feb 14, 2024
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 expressions Feature: expressions implicit conversions Feature: implicit conversions key paths Feature: key paths (both native and Objective-C) swift 5.10 type checker Area → compiler: Semantic analysis unexpected error Bug: Unexpected error
Projects
None yet
Development

No branches or pull requests

7 participants