The problem is that your function is not really generic.
A generic type is actually a declaration of a family of related types: specifically, one type for each possible type satisfying the generic constraints. In your example, this declaration:
func currentTheme<T: Theme>() -> T {
return current_theme
}
can be thought of as declaring many functions, one for each T
that conforms to Theme
. The compiler will select the appropriate specific type based on the call site. For example, I (as the caller) am allowed to write this:
let x: Theme1 = currentTheme()
However, the implementation does not match that. That's because for all but one of the infinite possible conforming types this function is invalid and will not compile. If it could compile my runtime example would be gibberish and it shouldn't compile, but the rules of generics allow me to write exactly that code.
What you're trying to write, I think, is a function where the return type will definitely conform to Theme
, but you don't want to write down what specific concrete implementation it will be at the function definition site. This is presumably because you have some non-local knowledge about what the concrete type will be, likely in a different file covered by some compile-time guards.
In this case, you should simply declare a typealias
and use that as the return type. You can then keep the typealias
declared near the underlying variable you're returning.
Another possibility is that you are changing the current theme at runtime. In this case, you need to return the Theme
existential from this function.