Constrain protocol usage outside the module

I've thought about this. At first blush it appears that this is a rather large difficulty but it needn't be. If you'll recall, we recently had a proposal to model enum cases with associated types as functions rather than tuples. So here the behavior would fall out naturally: it should work like overload resolution. So, say you have

Result<T, U> where U : Error

Then anything comforming to Error would be promoted to case u(U) and everything else to case t(T) just as it would work if you had a function with two overloads constrained analogously.

If, as you show above, you've got a scenario with two entirely unconstrained generic types, then you've got an ambiguity in overload resolution, which we've got the diagnostics to deal with.

In the concrete context you could simply specify the left and right types: let x: Either<Int, String> = myString. In the generic context you could "manually promote" to resolve the ambiguity if nothing else will do, but generally whether something is promoted to the left case or the right case would be unambiguous when you "plumb through" the generic parameters:

func f<T, U>(_ t: T, _ u: U) -> Either<T, U> {
  return t.isAwesome ? t : u
}

Here, the first argument, if returned, is always promoted to the left case, and the second to the right case, because that's how I've declared the return type.