Skip to content

[cxx-interop] Import non-member operators as global functions #62711

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

Merged
merged 1 commit into from
Dec 21, 2022

Conversation

egorzhdan
Copy link
Contributor

If a non-member operator is declared in a C++ namespace, we previously imported it as a static member of the enum that represents the C++ namespace.

This is not always correct under Swift rules for operators. In pure Swift, this code is valid:

public protocol UnsafeCxxRandomAccessIterator {
  static func +=(lhs: inout Self, rhs: Int)
}

enum std {
  public struct A : UnsafeCxxRandomAccessIterator {
    public static func += (lhs: inout A, rhs: Int) {
    }
  }
}

but this is not valid:

public protocol UnsafeCxxRandomAccessIterator {
  static func +=(lhs: inout Self, rhs: Int)
}

enum std {
  public struct A : UnsafeCxxRandomAccessIterator {}
  public static func += (lhs: inout A, rhs: Int) {}
}
// error: Member operator '+=' must have at least one argument of type 'std'

This caused assertion failures in SILGen when conforming C++ iterator types to UnsafeCxxRandomAccessIterator.

@egorzhdan egorzhdan added the c++ interop Feature: Interoperability with C++ label Dec 20, 2022
@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test

If a non-member operator is declared in a C++ namespace, we previously imported it as a static member of the enum that represents the C++ namespace.

This is not always correct under Swift rules for operators. In pure Swift, this code is valid:
```
public protocol UnsafeCxxRandomAccessIterator {
  static func +=(lhs: inout Self, rhs: Int)
}

enum std {
  public struct A : UnsafeCxxRandomAccessIterator {
    public static func += (lhs: inout A, rhs: Int) {
    }
  }
}
```
but this is not valid:
```
public protocol UnsafeCxxRandomAccessIterator {
  static func +=(lhs: inout Self, rhs: Int)
}

enum std {
  public struct A : UnsafeCxxRandomAccessIterator {}
  public static func += (lhs: inout A, rhs: Int) {}
}
// error: Member operator '+=' must have at least one argument of type 'std'
```

This caused assertion failures in SILGen when conforming C++ iterator types to `UnsafeCxxRandomAccessIterator`.
@egorzhdan egorzhdan force-pushed the egorzhdan/cxx-non-member-operator branch from fab91da to 2d67ab2 Compare December 21, 2022 15:20
@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test

@egorzhdan egorzhdan marked this pull request as ready for review December 21, 2022 15:20
Copy link
Contributor

@zoecarver zoecarver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks

@egorzhdan egorzhdan merged commit a0c9a54 into main Dec 21, 2022
@egorzhdan egorzhdan deleted the egorzhdan/cxx-non-member-operator branch December 21, 2022 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ interop Feature: Interoperability with C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants