Advice Needed for Making Use of Generics/Opaques/Existentials

Hello Swift community.

I am trying to make use of generics/opaque/existential in an architecture built using protocols, but getting conformance errors here and there.

I can't figure out what is the core issue here, and can't find other examples to fix.

Let me try to explain what is going on:

I have a base class that contains some basic functionality all new instances can make use.

class FooUnit: FooContainable {
  let a: A

  init(a: A) {
    self.a = a
  }

  func doThisCommonThing() {
  // Stuff
  }
}

And it conforms to this protocol:

protocol FooContainable: AnyObject {
  var y: XCUIApplication { get }
 
  func createFoo<T: Foo>() -> T
}

extension FooContainable {
  func createFoo<T: Foo>() -> {
    let z = T(a: A) // Initiates `TFoo`

    return z
  }
}

The Foo here is just a type alias combining 2 protocols, which is all the new classes inherit:

typealias Foo = FooUnit & FooTestable
protocol FooTestable: SomeUnrelatedProtocol {
  var x: Element { get }
}

An example from of how these protocols used in codebase:

final class FirstFoo: Foo {
    var x: Element {
        application.otherElements["Q_View"]
    }

    func doThis() -> FirstFoo {
       // Stuff
      return self
    }

    func returnSecondFoo() -> SecondFoo {
        return createFoo() // Initiates and Returns `SecondFoo`
    }
}

And this Foo classes used like this:

final class SomeClass {
    func doThat() {
        FirstFoo(a: A)
            .doThis()
            .returnSecondFoo()
            .doSomethingFromSecondFoo()
    }
}

Now coming to my issue.

I want to create a function with generic/opaque/existential return type:

final class ThirdFoo: Foo {
    var x: Element {
        application.otherElements["E_View"]
    }

    func doElse<T: Flow>() -> T {
       // Stuff
      return createFoo() // Initiate and Return Caller's `Foo`
    }
}

But unfortunately I can't achieve this and get this complaint:

final class SomeClass {
    func doThat() {
        FirstFoo(a: A)
            .returnThirdFoo()
            .doSomethingFromThirdFooThatReturnsT()  // Instance method 'doElse()' requires that 'FooUnit' conform to 'FooTestable'
    }
}

I am a bit lost and seek advice where am I doing wrong.

Thanks for any suggestions!

It's hard for us to see because the code is neither compileable nor self-contained (e.g. the XCUIApplication dependency). I'd recommend make it much simpler and compilable up to the point that shows the single compilation error you are talking about.

Here is a snippet you can put into Playground and get the same error message:

class FooUnit: FooContainable {
    var application: Int
    
    init(application: Int) {
        self.application = application
    }
    
    func doThisCommonThing() {
        // Stuff
    }
}

protocol FooTestable: BooTestable {
    var fooEntryPoint: Double { get }
    
    func doFooStuff()
}

extension FooTestable {
    func doFooStuff() { }
}

protocol BooTestable: AnyObject {
    var application: Int { get }
    
    init(application: Int)
}

protocol FooContainable: AnyObject {
    var application: Int { get }
    
    func createFoo<T: Foo>() -> T
}

extension FooContainable {
    func createFoo<T: Foo>() -> T {
        let z = T(application: application) // Initiates `TFoo`
        
        return z
    }
}

typealias Foo = FooUnit & FooTestable

final class FirstFoo: Foo {
    var fooEntryPoint: Double {
        13
    }
    
    func doThis() -> FirstFoo {
        // Stuff
        return self
    }
    
    func returnSecondFoo() -> SecondFoo {
        return createFoo() // Initiates and Returns `SecondFoo`
    }
}


final class SecondFoo: Foo {
    var fooEntryPoint: Double {
        14
    }
    
    func returnFirstFoo() -> FirstFoo {
        return createFoo()
    }
    
    func returnThirdFoo() -> ThirdFoo {
        return createFoo()
    }
}

final class ThirdFoo: Foo {
    var fooEntryPoint: Double {
        15
    }
    
    func doElse<T: Foo>() -> T {
        return createFoo() // Initiate and Return Caller's `Foo`
    }
}

final class SomeClass {
    func doThat() {
        FirstFoo(application: 13)
            .doThis()
            .returnSecondFoo()
            .returnThirdFoo()
            .doElse()      // Instance method 'doElse()' requires that 'FooUnit' conform to 'FooTestable'
    }
}