Skip to content

Conversation

@dolio
Copy link
Contributor

@dolio dolio commented Dec 8, 2025

This seems like an erroneous case that wasn't noticed, but can occur in some situations, like an existential vs. universal mismatch. If at least one argument type wasn't peeled, then it doesn't make sense to suggest that the function is under-applied. So just guard against it.

from https://unisoncomputing.slack.com/archives/CLGTK464E/p1764610297238729

This seems like an erroneous case that wasn't noticed, but can occur
in some situations, like an existential vs. universal mismatch. If at
least one argument type wasn't peeled, then it doesn't make sense to
suggest that the function is under-applied. So just guard against it.
(_, Just (Right {})) -> pure $ Mismatch ft et fl el mismatchSite n (Just SuperfluousDelay)
(Just needArgs, _) -> pure $ FunctionUnderApplied ft et fl el mismatchSite n (lowerType <$> needArgs)
(Just needArgs, _)
| not (null needArgs) -> pure $ FunctionUnderApplied ft et fl el mismatchSite n (lowerType <$> needArgs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm way out of my element but I'm curious: is there anything that should be preventing mayNeedArgs from being Just for this case, instead checking here whether needArgs is empty? Is the place that is producing that Just misdiagnosing the error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that a Nothing means that no amount of argument dropping allows for a subtyping relationship to exist. So, it indicates a complete mismatch, like Int vs String or something.

I'm not quite certain how the subtyping check succeeds in the test when it apparently failed in the type checker. Maybe some context is lost by the time it is in the error parser. I didn't actually write this case or study it very closely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick glance at findUnderApplication implies it should probably return Maybe (NonEmpty (Type v a)) or w/e; looks like it's unifying the type var with the last arg and is falsely reporting an under-application;

What you've written here is equivalent behaviour since it's only used in this one spot; but findUnderApplication should probably just should have a top-level guard which asserts there are actually args in it then return the NonEmpty

Copy link
Member

@ChrisPenner ChrisPenner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would likely be preferable to change findUnderApplication itself so we don't accidentally copy-pasta this error somewhere else, but the end result is the same 👍🏼

Thanks for handling this one!

@aryairani
Copy link
Contributor

Not sure whether to merge this yet or @dolio did you want to do this?

Would likely be preferable to change findUnderApplication itself so we don't accidentally copy-pasta this error somewhere else, but the end result is the same 👍🏼

@dolio
Copy link
Contributor Author

dolio commented Dec 9, 2025

I'm uncertain of the exact suggestion there. findUnderApplication is just a locally defined loop that I think is only used for that one thing. It just happens that the (totally natural) base case allows for this one vacuous error to happen.

@aryairani aryairani merged commit a7ac21b into trunk Dec 9, 2025
31 checks passed
@aryairani aryairani deleted the topic/underapply-error branch December 9, 2025 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants