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-5581] Proper support for protocol 'where' clause with constraints on 'Self' #48153

Closed
swift-ci opened this issue Jul 30, 2017 · 5 comments
Closed
Assignees
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-5581
Radar rdar://problem/38077232
Original Reporter rayfix (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Xcode Version 9.0 beta 4 (9M189t), Playground, MacBook Pro 10.12.6

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug
Assignee @slavapestov
Priority Medium

md5: 765079ddd3f018ba4c61239ed7475537

is duplicated by:

  • SR-8595 Protocol extension on protocol with subclass where restriction doesn't apply : class semantics
  • SR-8596 Existential of protocol with subclass where restriction is not substitutable
  • SR-8676 Swift compiler doesn't infer "class only protocol" from generic where clause
  • SR-8730 Illegal instruction: 4; While emitting SIL for getter
  • SR-8815 Adding protocol restriction causes crash
  • SR-9275 Crash when calling init on a protocol's metatype where the protocol is constrained to a type
  • SR-9477 Dynamic-stack-buffer-overflow caused by where clause on protocol
  • SR-7331 Diagnose protocol 'where' clause with constraints on 'Self'

Issue Description:

The following code fails to compile in a swift playground:

protocol Toggling where Self: Equatable {
  static var all: [Self] { get }
  func toggled() -> Self
}
extension Toggling {
  func toggled() -> Self {
    let current = Self.all.index(of: self) ?? 0
    let next = (current + 1) % Self.all.count
    return Self.all[next]
  }
}

Changing to simple conformance makes it work:

protocol Toggling : Equatable { .... }

The two should be equivalent.

Also, putting the constraint of Self: Equatable on the protocol extension (and removing it from the protocol declaration) also makes it work.

Having the Self requirement on both the protocol definition and extension correctly identifies that the constraint is redundant but also fails to compile.

@slavapestov
Copy link
Member

Minimal test case:

protocol P {}
protocol Q where Self : P {}

func f<T : P>(_: T) {}
func g<T : Q>(t: T) { f(t) }

@belkadan
Copy link
Contributor

cc @huonw

@slavapestov
Copy link
Member

Module::lookupConformance() calls ProtocolDecl::inheritsFrom() which calls NominalTypeDecl::getLocalConformances(), which doesn't know how to check the where clause or requirement signature, it just looks at the inheritance clause.

@slavapestov
Copy link
Member

Done: #17851

If this turns into a source compat issue, we can hack compatibility in. But for now let's go with the simple fix.

@slavapestov
Copy link
Member

Update: on swift-5.0-branch and master, this no longer diagnoses and instead is fully supported

@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

3 participants