# Initialization error when forwarding the initializers required by protocol ExpressibleByArrayLiteral or ExpressibleByDictionaryLiteral

**URL:** <https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705>\
**Category:** Using Swift\
**Tags:** literals, extensions, protocols\
**Created:** [October 10, 2019, 8:14pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705 "2019-10-10T20:14:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ylorn](https://avatars.discourse-cdn.com/v4/letter/y/13edae/32.png) [@ylorn](https://forums.swift.org/u/ylorn)\
**Post date:** [October 10, 2019, 8:14pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705/1 "2019-10-10T20:14:02Z")

</div>

I am exploring the possibility to have a protocol that can be initialized with basic type literals if its `associatedtype` is expressible by the required type.

```swift
public protocol WrappedValueLiteralExpressible {
    associatedtype WrappedValue
    var value: WrappedValue { get }
    init(value: WrappedValue)
}

```

For `ExpressibleByBooleanLiteral`, `ExpressibleByIntegerLiteral`, `ExpressibleByFloatLiteral`, `ExpressibleByUnicodeScalarLiteral`, `ExpressibleByExtendedGraphemeClusterLiteral`, `ExpressibleByStringLiteral`, the following extensions work fine:

```swift
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByBooleanLiteral {
    public init(booleanLiteral value: WrappedValue.BooleanLiteralType) {
        self.init(value: WrappedValue(booleanLiteral: value))
    }
}

extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByIntegerLiteral {
    public init(integerLiteral value: WrappedValue.IntegerLiteralType) {
        self.init(value: WrappedValue(integerLiteral: value))
    }
}

extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByFloatLiteral {
    public init(floatLiteral value: WrappedValue.FloatLiteralType) {
        self.init(value: WrappedValue(floatLiteral: value))
    }
}

extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByUnicodeScalarLiteral {
    public init(unicodeScalarLiteral value: WrappedValue.UnicodeScalarLiteralType) {
        self.init(value: WrappedValue(unicodeScalarLiteral: value))
    }
}

extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByExtendedGraphemeClusterLiteral {
    public init(extendedGraphemeClusterLiteral value: WrappedValue.ExtendedGraphemeClusterLiteralType) {
        self.init(value: WrappedValue(extendedGraphemeClusterLiteral: value))
    }
}

extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByStringLiteral {
    public init(stringLiteral value: WrappedValue.StringLiteralType) {
        self.init(value: WrappedValue(stringLiteral: value))
    }
}

```

However, for `ExpressibleByArrayLiteral` and `ExpressibleByDictionaryLiteral`, a compiling error

> Non-nominal type 'Self.WrappedValue' does not support explicit initialization

will prompt with following extension:

```swift
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByArrayLiteral {
    public init(arrayLiteral elements: WrappedValue.ArrayLiteralElement...) {
        self.init(value: WrappedValue(arrayLiteral: elements))
    }
}

extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByDictionaryLiteral {
    public init(arrayLiteral elements: (WrappedValue.Key, WrappedValue.Value)...) {
        self.init(value: WrappedValue(dictionaryLiteral: elements))
    }
}

```

This is where I got confused. If `WrappedValue` conforms to `ExpressibleByArrayLiteral`, then the required initializer (`init(arrayLiteral elements: Self.ArrayLiteralElement...)`) must be sufficient to initialize an instance of type `WrappedValue`, and that instance is all it needs to initialize an instance of any type that conforms to protocol `WrappedValueLiteralExpressible`.

So why is there that error, and how does error get generated?

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [October 10, 2019, 8:30pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705/2 "2019-10-10T20:30:48Z")

</div>

The diagnostic is a bit better on master (thanks to @owenv):

> error: cannot pass array of type '[Self.WrappedValue.ArrayLiteralElement]' as variadic arguments of type 'Self.WrappedValue.ArrayLiteralElement'

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [October 10, 2019, 8:31pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705/3 "2019-10-10T20:31:20Z")

</div>

This is the well-known variadic forwarding issue. A minimal example of your situation is:

```swift
struct Foo<T> {
  var base: T
}

extension Foo: ExpressibleByArrayLiteral where T: ExpressibleByArrayLiteral {
  init(arrayLiteral elements: T.ArrayLiteralElement...) {
    // Cannot invoke 'init' with an argument list of type '(arrayLiteral: [T.ArrayLiteralElement])'
    base = T.init(arrayLiteral: elements)
  }
}

```

Here are some previous threads about the topic:

• [[Idea] Passing an Array to Variadic Functions](https://forums.swift.org/t/idea-passing-an-array-to-variadic-functions/2240) (55 comments, April 2016)  
• [[Discussion] Variadics as an Attribute ](https://forums.swift.org/t/discussion-variadics-as-an-attribute/5186) (7 comments, February 2017)  
• [Explicit array splat for variadic functions](https://forums.swift.org/t/explicit-array-splat-for-variadic-functions/11326) (29 comments, March 2018)  
• [Variadic Parameters that Accept Array Inputs](https://forums.swift.org/t/variadic-parameters-that-accept-array-inputs/12711) (52 comments, May 2018)  
• [Another attempt at passing arrays as varargs (with implementation)](https://forums.swift.org/t/another-attempt-at-passing-arrays-as-varargs-with-implementation/26718) (126 comments, July 2019)  
• [Yet another varargs “splat” proposal](https://forums.swift.org/t/yet-another-varargs-splat-proposal/28649) (9 comments, September 2019)

---

<div class="post-metadata">

**Author:** ![ylorn](https://avatars.discourse-cdn.com/v4/letter/y/13edae/32.png) [@ylorn](https://forums.swift.org/u/ylorn)\
**Post date:** [October 10, 2019, 9:29pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705/4 "2019-10-10T21:29:57Z")

</div>

This is interesting, so the literal parameter `elements` actually gets converted to an `Array` before initialization.

I was wondering if the following change makes more sense to `ExpressibleByArrayLiteral`.

```swift
public protocol ExpressibleByArrayLiteral {
    associatedtype ArrayLiteralElement
    init(array: [ArrayLiteralElement])
}

public extension ExpressibleByArrayLiteral {
    init(arrayLiteral elements: ArrayLiteralElement...) {
        self.init(array: elements)
    }
}

```

So that any type conforms to `ExpressibleByArrayLiteral` only needs to implement `init(array: [ArrayLiteralElement])`, and get the literal initialization for free.

---

<div class="post-metadata">

**Author:** ![owenv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/owenv/32/6137_2.png) [@owenv](https://forums.swift.org/u/owenv)\
**Post date:** [October 10, 2019, 9:43pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705/5 "2019-10-10T21:43:17Z")

</div>

Normally, to add the new protocol requirement `init(array: [ArrayLiteralElement])` in an ABI stable way, you would need to provide a default implementation. Because the compiler has special knowledge of `ExpressibleByArrayLiteral` and due to some implementation details of variadic arguments, it _might_ be viable in this case though.

That said, I think it would be better to spend time on a more general-purpose solution to varargs forwarding, instead of just working around it in this one case. The feature is 90% implemented, I just don't think it's likely to move forward until the details of tuple splatting have been sorted out.

---

<div class="post-metadata">

**Author:** ![ylorn](https://avatars.discourse-cdn.com/v4/letter/y/13edae/32.png) [@ylorn](https://forums.swift.org/u/ylorn)\
**Post date:** [October 10, 2019, 9:54pm UTC](https://forums.swift.org/t/initialization-error-when-forwarding-the-initializers-required-by-protocol-expressiblebyarrayliteral-or-expressiblebydictionaryliteral/29705/6 "2019-10-10T21:54:47Z")

</div>

Yes, I agree. Have been reading through the threads @Nevin posted, a lot of good stuff there.

Thanks for these.
