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-12991] Type checker doesn't take context from "<key path expr> as <function type>" - Examples in Key Path Expressions as Functions proposal don't compile #55436

Closed
beccadax opened this issue Jun 12, 2020 · 2 comments · Fixed by #69031
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

@beccadax
Copy link
Contributor

Previous ID SR-12991
Radar rdar://problem/64304000
Original Reporter @beccadax
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, TypeChecker
Assignee None
Priority Medium

md5: c64fc41feeb4a1205ee0f1de49f07037

cloned from:

  • SR-12897 ".self" not working with keypath-as-function - Examples in Key Path Expressions as Functions proposal don't compile

is duplicated by:

  • SR-13392 Can't use as to coerce KeyPath to function

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:

struct User {
    let email: String
}

let users = [User]()
let f3 = \User.email as (User) -> String
users.map(f3) // Error: Expression type '(User) -> String' is ambiguous without more context
 

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

@beccadax
Copy link
Contributor Author

@swift-ci create

@beccadax
Copy link
Contributor Author

In a near-release/5.3 Swift, I see an improved diagnostic, but it still fails:

<stdin>:6:22: error: cannot convert value of type 'KeyPath<User, String>' to type '(User) -> String' in coercion
let f3 = \User.email as (User) -> String
         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~

With -debug-constraints, I see that solving fails very quickly. It seems like we never consider interpreting the keypath as a function at all—maybe this goes through a path we didn't update for SE-0249.

---Constraint solving at [<stdin>:6:10 - line:6:35]---
---Initial constraints for the given expression---
(coerce_expr type='(User) -> String' location=<stdin>:6:22 range=[<stdin>:6:10 - line:6:35] writtenType='(User) -> String'
  (keypath_expr type='$T3' location=<stdin>:6:10 range=[<stdin>:6:10 - line:6:16]
    (components      
      (unresolved_property decl_name='email' type='_'))
    (parsed_root
      (unresolved_dot_expr type='<null>' field 'email' function_ref=unapplied
        (type_expr type='<null>' typerepr='User')))))
Score: 0 0 0 0 0 0 0 0 0 0 0 0 0
Contextual Type: <null>
Type Variables:
  $T0 [noescape allowed] bindings={(supertypes of) User} @ locator@0x7fe1e6938800 [KeyPath@<stdin>:6:10 -> key path root]
  $T1 [lvalue allowed] [noescape allowed] fully_bound subtype_of_existential involves_type_vars bindings={} @ locator@0x7fe1e6938910 [KeyPath@<stdin>:6:10 -> key path component #&#8203;0 -> key path component result]
  $T2 [noescape allowed] subtype_of_existential involves_type_vars bindings={} @ locator@0x7fe1e69389e0 [KeyPath@<stdin>:6:10 -> key path value]
  $T3 [noescape allowed] involves_type_vars #defaultable_bindings=1 bindings={<<unresolvedtype>>} @ locator@0x7fe1e6938aa0 [KeyPath@<stdin>:6:10 -> key path type]

Active Constraints:

Inactive Constraints:
  User subtype $T0 [[locator@0x7fe1e6938820 [KeyPath@<stdin>:6:10]]];
  @lvalue $T0[.email: value] == $T1 [[locator@0x7fe1e69388f0 [KeyPath@<stdin>:6:10 -> key path component #&#8203;0]]];
  $T1 equal $T2 [[locator@0x7fe1e6938820 [KeyPath@<stdin>:6:10]]];
  $T3 key path from $T0 -> $T2 [[locator@0x7fe1e6938820 [KeyPath@<stdin>:6:10]]];
  disjunction (remembered) [[locator@0x7fe1e6938b70 [Coerce@<stdin>:6:22]]]:$T3 conv (User) -> String [[locator@0x7fe1e6938b70 [Coerce@<stdin>:6:22]]]; or $T3 bridging conv (User) -> String [[locator@0x7fe1e6938b70 [Coerce@<stdin>:6:22]]];
  ($T0 bindings={(supertypes of) User})
  Initial bindings: $T0 := User
  (attempting type variable $T0 := User
    (overload set choice binding $T1 := String)
    (attempting disjunction choice $T3 conv (User) -> String [[locator@0x7fe1e6938b70 [Coerce@<stdin>:6:22]]];
    )
    (attempting disjunction choice $T3 bridging conv (User) -> String [[locator@0x7fe1e6938b70 [Coerce@<stdin>:6:22]]];
      (increasing score due to user conversion)
    )
  )
---Solver statistics---
Total number of scopes explored: 4
Maximum depth reached while exploring solutions: 3
Time: 6.445000e+00ms
---Attempting to salvage and emit diagnostics---

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

Successfully merging a pull request may close this issue.

1 participant