Better handle free vars and unknown types in abstract defs
Fixes #10699
I broke out the rescue blocks into one for each side, removing the logic that always just defaulted to true if there was a type lookup error. It'll now properly throw an error if one side has a type that doesn't resolve. E.g. example one in the originally issue. This PR does NOT handle the case where both side are invalid types, but could change this as a follow up if we wanted too.
A type is assumed to be resolvable if it is a free var, global, is a generic type var, or is not a Path. This handles the second example in the original issue. It's still not super strict, as as it stands, the logic allows using a diff free var name, or really even just def foo(x) to satisfy abstract def foo(x : U) : U forall U. This satisfies my use case at least by ensuring at least one T.class overload exists.
EDIT: ~Moving this to a draft, abstract def get_env(type : Int32) shouldn't be valid given abstract def get_env(type : T.class) : T forall T.~
just
def foo(x)to satisfyabstract def foo(x : U) : U forall U
IMO this should be legal with or without a return type in the abstract def, same goes for more specific pairs like def foo(x : Indexable) versus abstract def foo(x : Array(T)) forall T. As it stands right now, this PR now forbids those.
I reverted 9e97b5b854577f703d7fcbbfa253cce38f374d37, but kept the specs/added a few more. This bring it back with behavior that exists on master. Ultimately I think we'd want to prevent def transform(x : Int32) : Int32 from being considered valid for abstract def transform(x : Array(T)) forall T. But that can be a follow up at some point as it was already considered valid even before this PR.
This implementation seems way too complicated to be good 😢
Technically, formatting a list of generic arguments doesn't seem much different from formatting other lists of elements. Maybe we could reuse the existing format_literal_elements helper?
That should also fix some edge cases. For example, the rule to add a trailing comma when the type vars span multiple lines does not match with the rule for array literals. There, we don't add a trailing comma if the end delimiter is on the same line.
Is this comment meant for #16430 instead...?