Can protocol extension methods be used as generic specialization hints?

suppose i have a protocol with a generic requirement like:

protocol BSONDocumentDecodable
{
    associatedtype CodingKeys

    init(bson:BSON.DocumentDecoder<CodingKeys,
        some RandomAccessCollection<UInt8>>) throws
}
extension BSONDocumentDecodable
{
    @inlinable public
    init(bson:BSON.DocumentView<some RandomAccessCollection<UInt8>>) throws
    {
        try self.init(bson: try BSON.DocumentDecoder.init(parsing: bson))
    }
}

this will have quite terrible performance unless the witness is @inlinable all the way through. so instead of making the witness inlinable, i might do something like:

import BSON

extension MyModel:BSONDocumentDecodable
{
    public
    init(bson:BSON.DocumentDecoder<CodingKeys,
        some RandomAccessCollection<UInt8>>) throws
    {
        // some very long implementation
    }
}
extension MyModel:BSONDocumentDecodable
{
    public
    init(buffer:UnsafeRawBufferPointer) throws
    {
        try self.init(bson: BSON.DocumentView.init(slice: buffer))
    }
    public
    init(buffer:ArraySlice<UInt8>) throws
    {
        try self.init(bson: BSON.DocumentView.init(slice: buffer))
    }
    public
    init(buffer:[UInt8]) throws
    {
        try self.init(buffer: buffer[...])
    }
}

now MyModel has three non-generic entrypoints. my question is then:

  1. can the init(buffer:) shims be moved to an extension on the BSONDocumentDecodable protocol itself, and still produce the desired specialization?

  2. if so, do the init(buffer:) shims themselves need to be @inlinable?

1 Like