Allow using protocols with concrete associated types as non-generic variable types


(Austin Feight) #1

The following code won't compile for reasons we're familiar with:

protocol Value {
  associatedType ValueType
  var value: ValueType { get set }
}

struct ValueHolder {
  var value: Value // Protocol 'Value' can only be used as a generic
constraint because it has Self or associated type requirements
}

But then when I make that associated type concrete in a more sub-protocol,
the compiler still complains, even when it should no longer have associated
type requirements, because ValueType can only be Int.

protocol IntValue: Value {
  associatedType ValueType = Int
  var value: Int { get set }
}

struct ValueHolder {
  var value: IntValue // Protocol 'IntValue' can only be used as a
generic constraint because it has Self or associated type requirements
}

or at least - that's what I'm trying to achieve with `associatedType
ValueType = Int`. Similarly I tried `typealias ValueType = Int`, with the
same result.

Would this be considered a compiler bug? Or is IntValue's ValueType
shadowing Value's ValueType, and they're both still independent? I don't
believe the latter case is correct because even when the original
declaration ValueType is concrete, the compiler still complains:

protocol IntValue {
  associatedType ValueType = Int
  var value: Int { get set }
}

struct ValueHolder {
  var value: IntValue // Protocol 'IntValue' can only be used as a
generic constraint because it has Self or associated type requirements
}

Trying to figure out where this proposal would fall, or if it's been
discussed already - I wasn't able to find anything similar.

Cheers,
*Austin Feight *| Chief Shipping Officer

150 E. 52nd Street, 22nd Floor, New York, NY 10022
www.chexology.com <http://www.coatchex.com/> | www.austindfeight.com


(Xiaodi Wu) #2

When you write `associatedtype P = Q`, you are not constraining P but
providing a default value. This is one reason why Swift 3 adopted
associatedtype instead of typealias inside protocols.

You can write this:

protocol R {
typealias Q = Int
}

struct S : R {

}

let foo: R = S()

You are correct that, if R refined a protocol P with an associated type
requirement Q, the typealias in R does not get rid of the associated type
requirement. This is not a bug.

Consider: any method requirements on P can require a return value of P.Q.
Conforming types such as S can implement them even if P provides a default
implementation, and they may do so in a way that causes P.Q to be a
different type than R.Q.

···

On Mon, Apr 24, 2017 at 14:44 Austin Feight via swift-evolution < swift-evolution@swift.org> wrote:

The following code won't compile for reasons we're familiar with:

protocol Value {
  associatedType ValueType
  var value: ValueType { get set }
}

struct ValueHolder {
  var value: Value // Protocol 'Value' can only be used as a generic constraint because it has Self or associated type requirements
}

But then when I make that associated type concrete in a more sub-protocol,
the compiler still complains, even when it should no longer have associated
type requirements, because ValueType can only be Int.

protocol IntValue: Value {
  associatedType ValueType = Int
  var value: Int { get set }
}

struct ValueHolder {
  var value: IntValue // Protocol 'IntValue' can only be used as a generic constraint because it has Self or associated type requirements
}

or at least - that's what I'm trying to achieve with `associatedType
ValueType = Int`. Similarly I tried `typealias ValueType = Int`, with the
same result.

Would this be considered a compiler bug? Or is IntValue's ValueType
shadowing Value's ValueType, and they're both still independent? I don't
believe the latter case is correct because even when the original
declaration ValueType is concrete, the compiler still complains:

protocol IntValue {
  associatedType ValueType = Int
  var value: Int { get set }
}

struct ValueHolder {
  var value: IntValue // Protocol 'IntValue' can only be used as a generic constraint because it has Self or associated type requirements
}

Trying to figure out where this proposal would fall, or if it's been
discussed already - I wasn't able to find anything similar.

Cheers,
*Austin Feight *| Chief Shipping Officer

150 E. 52nd Street, 22nd Floor, New York, NY 10022
www.chexology.com <http://www.coatchex.com/> | www.austindfeight.com
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution