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-4382] Raw value type alias in raw representable child is no longer recognised #46961

Closed
iby opened this issue Mar 28, 2017 · 11 comments
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@iby
Copy link

iby commented Mar 28, 2017

Previous ID SR-4382
Radar None
Original Reporter @iby
Type Bug
Status Resolved
Resolution Won't Do
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 3.1Regression
Assignee None
Priority Medium

md5: 489c9dccf042078477e3462cc0156ed5

is duplicated by:

  • SR-4416 Compile Error when inheriting protocol with associated Type

Issue Description:

The following declaration of RawValue in inheriting protocol used to work right before updating to 3.1.

@belkadan
Copy link
Contributor

This syntax was only ever meant to set a default, not constrain adopters. But it is a behavior change. cc @huonw, @slavapestov.

@iby
Copy link
Author

iby commented Mar 28, 2017

Good point. Is it possible though?

@belkadan
Copy link
Contributor

To constrain adopters? There's a Swift 4 feature for that, but it isn't finished yet.

@belkadan
Copy link
Contributor

You can get 90% of the way there by adding a requirement var rawValue: String, though.

@iby
Copy link
Author

iby commented Mar 28, 2017

Good point! Will give it a go.

@slavapestov
Copy link
Member

To set a new default in a refined protocol, use an associated type:

protocol Foo: RawRepresentable {
    associatedtype RawValue = String
}

I don't think the intent of the old behavior of typealiases that shadow a protocol was to set defaults or really do anything at all. It was unsound and unfortunately we had to break some marginally valid code in order to put this on a more logical foundation.

@belkadan
Copy link
Contributor

That just changes the default; it does not enforce it.

@slavapestov
Copy link
Member

I'm not sure I understand then. If you want to set a default, you can use 'associatedtype'. To constrain adopters, you can use a 'typealias'.

@belkadan
Copy link
Contributor

A typealias doesn't constrain adopters. It's just another default (by being another candidate).

@belkadan
Copy link
Contributor

@slavapestov, @DougGregor, and I talked some offline and realized that

  • it's not exactly clear what 3.0 was doing

  • it's not exactly clear what 3.1 is doing

  • master is trying to do the thing you want (a same-type constraint)

  • it's not exactly clear what the right behavior is.

But here's a dummy example that both 3.0 and 3.1 accept where the typealias is not picked as the associated type:

protocol BaseProto {
  associatedtype Assoc
}
extension BaseProto {
  var assoc: Assoc? { return nil }
}

protocol SubProto: BaseProto {
  typealias Assoc = String
}

extension SubProto {
  var assoc: String? { return "abc" }
}

struct Foo: SubProto {
  typealias Assoc = Int
}

func test1<X: BaseProto>(_ x: X) {
  print(X.Assoc.self, type(of: x.assoc))
}

func test2<X: SubProto>(_ x: X) {
  print(X.Assoc.self, type(of: x.assoc))
}

let foo = Foo()
print(Foo.Assoc.self, type(of: foo.assoc))
test1(foo)
test2(foo)

This outputs

Int Optional<String>
Int Optional<Int>
String Optional<String>

which is pretty weird but clearly has some semantics. I'm not exactly concerned about a contrived case like this, but it's possible that someone accidentally made the types not match up, and we shouldn't break working code in 4.0's 3-mode.

@belkadan
Copy link
Contributor

I think at this point we're going to stick with the new behavior, which treats this as a constraint on the associated type and suggests you explicitly use a same-type constraint instead.

@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