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-9230] Crash with protocol-typed argument for @dynamicCallable method #51718

Closed
swift-ci opened this issue Nov 13, 2018 · 5 comments
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-9230
Radar None
Original Reporter pschuh (JIRA User)
Type Bug
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee pschuh (JIRA)
Priority Medium

md5: 8ae887542ad4bffb4db2001ae7cd1475

Issue Description:

I get this error:

tuple_expr element type mismatch:
 field: Proto
 element: Struct

For this code:

protocol Proto {}

@dynamicCallable
struct Struct : Proto {
  func dynamicallyCall(withArguments args: [Proto] = []) {}
  func dynamicallyCall(withKeywordArguments args: DictionaryLiteral<String, Proto> = [:]) -> Struct {
    return Struct()
  }
}

func crasher() {
  let a = Struct()
  // Dynamic call crashes.
  a(a(a, key: a))

  // Direct call doesn't crash.
  // a.dynamicallyCall(withArguments: [a.dynamicallyCall(withKeywordArguments: ["": a, "key": a])])

  // Simpler dynamic calls don't crash.
  // a(a, key: a)
  // a(a)
}
@dan-zheng
Copy link
Collaborator

Ah darn, thanks for finding the bug! Somehow I never thought to test default arguments when implementing @dynamicCallable.
Investigating quickly.

EDIT: The problem occurs even when default arguments (for both methods) are removed. So the problem seems unrelated to default arguments.

@dan-zheng
Copy link
Collaborator

Interesting, removing the protocol Proto makes the crash go away:

// This doesn't crash.
@dynamicCallable
struct Struct {
  func dynamicallyCall(withArguments args: [Struct] = []) {}
  func dynamicallyCall(withKeywordArguments args: DictionaryLiteral<String, Struct> = [:]) -> Struct {
    return Struct()
  }
}

func crasher() {
  let a = Struct()
  a(a(a, key: a))
}

@dan-zheng
Copy link
Collaborator

Incidentally, I lean towards the opinion that default arguments on dynamicallyCall methods should be disabled.
Implicitly, dynamic calls already have a default argument: [] for the withArguments: method and [:] for the withKeywordArguments: method.

This is just the natural behavior:

@dynamicCallable
struct Callable {
  func dynamicallyCall(withArguments: [Int]) {}
}
let c = Callable()
c() // This always sugars to `dynamicallyCall(withArguments: [])`.
// Never sugars to `dynamicallyCall()` (using default arguments).

We could change @dynamicCallable to rewrite dynamic calls with no arguments into default argument calls, but that's quite irregular. Disabling default arguments makes more sense to me.

@dan-zheng
Copy link
Collaborator

The "tuple_expr element type mismatch" error happens during AST verification.
Namely, a tuple argument has type Struct, not Proto as expected.

I dumped the AST of the code with the direct call (i.e. a.dynamicallyCall(withArguments: [a.dynamicallyCall(withKeywordArguments: ["": a, "key": a])])), and found uses of ErasureExpr:

$ swiftc -dump-ast dc.swift
... // whole bunch of stuff
(erasure_expr implicit type='Proto' location=dc.swift:29:92 range=[dc.swift:29:92 - line:29:92]
    (normal_conformance type=Struct protocol=Proto)
    (declref_expr type='Struct' location=dc.swift:29:92 range=[dc.swift:29:92 - line:29:92] decl=dc.(file).crasher().a@dc.swift:25:7 function_ref=unapplied)))

In CSApply.cpp, perhaps generating ErasureExpr in situations like this is necessary. (Though, really we'd like TC.typeCheckExpression to perform erasure and resolve the correct type for us.)

@swift-ci
Copy link
Collaborator Author

Comment by Parker Schuh (JIRA)

This has been fixed in the tensorflow branch.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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
Projects
None yet
Development

No branches or pull requests

2 participants