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-5833] Cannot convert non-generic subtype of generic type #48403

Open
ffried opened this issue Sep 4, 2017 · 1 comment
Open

[SR-5833] Cannot convert non-generic subtype of generic type #48403

ffried opened this issue Sep 4, 2017 · 1 comment
Labels
compiler The Swift compiler in itself feature A feature request or implementation improvement

Comments

@ffried
Copy link
Contributor

ffried commented Sep 4, 2017

Previous ID SR-5833
Radar None
Original Reporter @ffried
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, LanguageFeatureRequest
Assignee None
Priority Medium

md5: 66830de8198992693ebd5902cb0e0057

Issue Description:

Given the following code:

class Base<Some> {
    enum Kind { case a, b }

    init(kind: Kind) {}
}
class SubclassA: Base<Int> {}
class SubclassB: Base<String> {}

let kind = Base<Int>.Kind.a
_ = SubclassA(kind: kind)
_ = SubclassB(kind: kind)

The compiler emits the following:

s4_nongeneric_subtypes.swift:11:21: error: cannot convert value of type 'Base<Int>.Kind' to expected argument type 'Base<String>.Kind'
_ = SubclassB(kind: kind)
                    ^~~~

While this is basically correct, the nested enum Kind does not use the generic types of the outer type. So theoretically it could use used interchangeably.
Furthermore, accessing the nested type always requires specifying the generic type. E.g. let kind = Base.Kind.a results in an error.

It would be great if nested types, that don't reference the generic types of their outer type could be used interchangeably.

As a workaround, the following works:

extension Base.Kind {
   func toKind<T>() -> Base<T>.Kind {
      switch self {
         case .a: return .a
         case .b: return .b
      }
   }
}

let kind = Base<Int>.Kind.a
_ = SubclassA(kind: kind)
_ = SubclassB(kind: kind.toKind())
@belkadan
Copy link
Contributor

belkadan commented Sep 5, 2017

This would be a language change—although you're right that it's a relatively esoteric one—and would thus have to go through the Swift Evolution Process.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself feature A feature request or implementation improvement
Projects
None yet
Development

No branches or pull requests

2 participants