Multiple errors with static types

Definitely, and I'd say that if I was in your specific situation (given my, admittedly, very limited understanding of it) I would not use Error to represent the scenarios you mentioned, if the potential "erroneous" outcomes carry business logic meaning.

For example, in this hypothetical

I 100% agree that crashing is unacceptable, and given the fact that a specific decision must be made if either the game allocates too much terrain at once, or it doesn't, I would represent the outcome with a specific return type, not an error, for example (sorry if the code looks silly):

enum TerrainAllocationOutcome {
  case aboutRight(Terrain)
  case tooMuch(New, Old)
}

func allocateTerrain() -> TerrainAllocationOutcome { ... }

But the allocateTerrain might also actually throw, because something else, unexpected and undesirable, could happen, related to its internals, that can only be logged and recovered by trying again. If this was the case, then one could be tempted to also represent the tooMuch with an Error, but that wouldn't be great design to me, because it would mix up in the Error case things that require specific business logic and things that are only logged and retried, making the Success/Error boundary not meaningful.

On a side note, there is also a similar problem when implementing web APIs that give some HTTP error codes some business logic significance, mixing up actual errors with things that are not errors at all, making modeling harder and removing much of the utility of remote logging systems.

That's also why I suggested using Result, that allows to fully model a function outcome with types, and can be manipulated with generic functions.

To be clear, I agree with the need to be pedantic with the outcomes of functions, and I agree that the error handling model could be more powerful without sacrificing usability for people that use errors in a different way. I'm just saying that the current error model implemented in Swift doesn't support very well approaches where errors have business logic significance, and need precise handling at various levels of a call stack, so alternative approaches must be sought (at least for now), like a different way of modeling "error outcomes".