Skip to content

Commit 71f25f8

Browse files
committed
First attempt at a better over-application error.
1 parent 142863d commit 71f25f8

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

parser-typechecker/src/Unison/PrintError.hs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,35 @@ renderTypeError e env src = case e of
275275
"need to have the same type."
276276
]
277277
NotFunctionApplication {..} ->
278-
mconcat
279-
[ "This looks like a function call, but with a ",
280-
style Type1 (renderType' env ft),
281-
" where the function should be. Are you missing an operator?\n\n",
282-
annotatedAsStyle Type1 src f,
283-
debugSummary note
284-
]
278+
case Type.arity ft of
279+
0 ->
280+
mconcat
281+
[ "It looks like this expression is being called like a function:\n\n",
282+
annotatedAsStyle ErrorSite src f,
283+
"\n\nbut the thing being applied has the type:\n\n",
284+
style Type2 (renderType' env ft),
285+
"\n\nWhich doesn't expect any arguments.",
286+
"\n\n",
287+
debugSummary note
288+
]
289+
arity ->
290+
mconcat
291+
[ "It looks like this function call\n\n",
292+
annotatedAsStyle Type2 src f,
293+
"\n\nis being applied to ",
294+
Pr.blue $ Pr.shown (length args),
295+
" arguments, but it has the type\n\n",
296+
style Type2 (renderType' env ft),
297+
"\n\nwhich only accepts only ",
298+
Pr.blue $ Pr.shown arity,
299+
maybePlural " argument" arity <> ".\n\n",
300+
"Did you apply the function to too many arguments? \n\n",
301+
debugSummary note
302+
]
303+
where
304+
maybePlural word n
305+
| n == 1 = word
306+
| otherwise = word <> "s"
285307
FunctionApplication {..} ->
286308
let fte = Type.removePureEffects False ft
287309
fteFreeVars = Set.map TypeVar.underlying $ ABT.freeVars fte

parser-typechecker/src/Unison/Typechecker/TypeError.hs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ data TypeError v loc
5858
| NotFunctionApplication
5959
{ f :: C.Term v loc,
6060
ft :: C.Type v loc,
61-
note :: C.ErrorNote v loc
61+
note :: C.ErrorNote v loc,
62+
args :: [C.Term v loc]
6263
}
6364
| AbilityCheckFailure
6465
{ ambient :: [C.Type v loc],
@@ -321,15 +322,15 @@ applyingNonFunction :: (Var v) => Ex.ErrorExtractor v loc (TypeError v loc)
321322
applyingNonFunction = do
322323
_ <- Ex.typeMismatch
323324
n <- Ex.errorNote
324-
(f, ft) <- Ex.unique $ do
325+
(f, ft, args) <- Ex.unique $ do
325326
Ex.pathStart
326-
(arity0Type, _arg, _argNum) <- Ex.inSynthesizeApp
327+
_synthApp <- Ex.inSynthesizeApp
327328
(_, f, ft, args) <- Ex.inFunctionCall
328329
let expectedArgCount = Type.arity ft
329330
foundArgCount = length args
330331
-- unexpectedArgLoc = ABT.annotation arg
331-
whenM (expectedArgCount < foundArgCount) $ pure (f, arity0Type)
332-
pure $ NotFunctionApplication f (Type.cleanup ft) n
332+
whenM (expectedArgCount < foundArgCount) $ pure (f, ft, args)
333+
pure $ NotFunctionApplication f (Type.cleanup ft) n args
333334

334335
-- | Want to collect this info:
335336
-- The `n`th argument to `f` is `foundType`, but I was expecting `expectedType`.

0 commit comments

Comments
 (0)