I have a problem with generics in swift. Let's expose my code.

```

protocol FooProtocol {
    associatedtype T
}

protocol Fooable { }
extension Int : Fooable { }
extension String: Fooable { }

class AnyFoo<T>: FooProtocol {
    init<P: FooProtocol>(p: P) where P.T == T { }
}

class FooIntImpClass: FooProtocol {
    typealias T = Int
}

class FooStringImpClass: FooProtocol {
    typealias T = String
}

func createOne(isInt: Bool) -> AnyFoo<Fooable> {
    if isInt {
        let anyFoo = AnyFoo(p: FooIntImpClass())
          return anyFoo
    } else {
        let anyFoo = AnyFoo(p: FooStringImpClass())
        return anyFoo
    }
}

func createTwo<F: Fooable>(isInt: Bool) -> AnyFoo<F> {
    if isInt {
        let anyFoo = AnyFoo(p: FooIntImpClass())
          return anyFoo
    } else {
        let anyFoo = AnyFoo(p: FooStringImpClass())
        return anyFoo
    }
}

```

`createOne` got an error 

> 
> Cannot convert return expression of type 'AnyFoo' (aka 'AnyFoo') to return type 'AnyFoo'
> 
> 
> 

`createTwo` got an error

> 
> Cannot convert return expression of type 'AnyFoo' (aka 'AnyFoo') to return type 'AnyFoo'
> 
> 
> 

Why is this happening. I'm returning the correct value.

And What is the difference with the `createOne` and `createTwo`
['https://Stackoverflow.com/questions/62405675', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/6239013/']
EDIT to respond to the edit to the question:

`createTwo` doesn't work because you have the same misconception as I said in my original answer. `createTwo` decided on its own that `F` should be either `String` or `Int`, rather than "any type that conforms to `Fooable`".

For `createOne`, you have another common misconception. **Generic classes are invariant**. `AnyFoo<String>` is not a kind of `AnyFoo<Fooable>`. In fact, they are totally unrelated types! See [here](https://stackoverflow.com/questions/41976844/swift-generic-coercion-misunderstanding) for more details.

Basically, what you are trying to do violates type safety, and you redesign your APIs and pick another different approach.

---

Original answer (for initial revision of question)

You seem to be having a common misconception of generics. **Generic parameters are decided by the caller, not the callee.**

In `createOne`, you are returning `anyFoo`, which is of type `AnyFoo<Int>`, not `AnyFoo<P>`. The method (callee) have decided, on its own, that `P` should be `Int`. This shouldn't happen, because the *caller* decides what generic parameters should be. If the callee is generic, it must be able to work with *any* type (within constraints). Anyway, `P` can't be `Int` here anyway, since `P: FooProtocol`.

Your `createOne` method should not be generic at all, as it only works with `Int`:

```
func createOne() -> AnyFoo<Int> {
    let anyFoo = AnyFoo(p: FooImpClass())
    return anyFoo
}

```
Is the following what you tried to achieve? (compiled & tested with Xcode 11.4)

```
func createOne() -> some FooProtocol {
    let anyFoo = AnyFoo(p: FooImpClass())
    return anyFoo
}

```