diff options
-rw-r--r-- | compiler/parser/Lexer.x | 2 | ||||
-rw-r--r-- | compiler/parser/Parser.y | 39 | ||||
-rw-r--r-- | compiler/typecheck/TcErrors.lhs | 14 | ||||
-rw-r--r-- | testsuite/tests/annotations/should_fail/annfail08.stderr | 5 | ||||
-rw-r--r-- | testsuite/tests/deriving/should_fail/drvfail007.stderr | 1 | ||||
-rw-r--r-- | testsuite/tests/ghci.debugger/scripts/break003.stderr | 4 | ||||
-rw-r--r-- | testsuite/tests/ghci/scripts/Defer02.stderr | 8 | ||||
-rw-r--r-- | testsuite/tests/mdo/should_fail/mdofail005.stderr | 4 | ||||
-rw-r--r-- | testsuite/tests/parser/should_fail/ParserNoLambdaCase.stderr | 2 | ||||
-rw-r--r-- | testsuite/tests/parser/should_fail/readFail020.stderr | 3 | ||||
-rw-r--r-- | testsuite/tests/parser/should_fail/readFail040.stderr | 4 | ||||
-rw-r--r-- | testsuite/tests/rebindable/rebindable6.stderr | 3 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_fail/T2846b.stderr | 4 |
13 files changed, 83 insertions, 10 deletions
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x index 6d05bb9d6d..b4223c82d8 100644 --- a/compiler/parser/Lexer.x +++ b/compiler/parser/Lexer.x @@ -2144,6 +2144,8 @@ srcParseErr dflags buf len else ptext (sLit "parse error on input") <+> quotes (text token) $$ ppWhen (not th_enabled && token == "$") -- #7396 (text "Perhaps you intended to use TemplateHaskell") + $$ ppWhen (token == "<-") + (text "Perhaps this statement should be within a 'do' block?") where token = lexemeToString (offsetBytes (-len) buf) len th_enabled = xopt Opt_TemplateHaskell dflags diff --git a/compiler/parser/Parser.y b/compiler/parser/Parser.y index 2e1b777bb3..b6db3a882b 100644 --- a/compiler/parser/Parser.y +++ b/compiler/parser/Parser.y @@ -1577,6 +1577,37 @@ exp10 :: { LHsExpr RdrName } -- hdaume: core annotation | fexp { $1 } + -- parsing error messages go below here + | '\\' apat apats opt_asig '->' {% parseErrorSDoc (combineLocs $1 $5) $ text + "parse error in lambda: no expression after '->'" + } + | '\\' {% parseErrorSDoc (getLoc $1) $ text + "parse error: naked lambda expression '\'" + } + | 'let' binds 'in' {% parseErrorSDoc (combineLocs $1 $2) $ text + "parse error in let binding: missing expression after 'in'" + } + | 'let' binds {% parseErrorSDoc (combineLocs $1 $2) $ text + "parse error in let binding: missing required 'in'" + } + | 'let' {% parseErrorSDoc (getLoc $1) $ text + "parse error: naked let binding" + } + | 'if' exp optSemi 'then' exp optSemi 'else' {% hintIf (combineLocs $1 $5) "else clause empty" } + | 'if' exp optSemi 'then' exp optSemi {% hintIf (combineLocs $1 $5) "missing required else clause" } + | 'if' exp optSemi 'then' {% hintIf (combineLocs $1 $2) "then clause empty" } + | 'if' exp optSemi {% hintIf (combineLocs $1 $2) "missing required then and else clauses" } + | 'if' {% hintIf (getLoc $1) "naked if statement" } + | 'case' exp 'of' {% parseErrorSDoc (combineLocs $1 $2) $ text + "parse error in case statement: missing list after '->'" + } + | 'case' exp {% parseErrorSDoc (combineLocs $1 $2) $ text + "parse error in case statement: missing required 'of'" + } + | 'case' {% parseErrorSDoc (getLoc $1) $ text + "parse error: naked case statement" + } + optSemi :: { Bool } : ';' { True } | {- empty -} { False } @@ -2377,6 +2408,14 @@ hintMultiWayIf span = do unless mwiEnabled $ parseErrorSDoc span $ text "Multi-way if-expressions need MultiWayIf turned on" +-- Hint about if usage for beginners +hintIf :: SrcSpan -> String -> P (LHsExpr RdrName) +hintIf span msg = do + mwiEnabled <- liftM ((Opt_MultiWayIf `xopt`) . dflags) getPState + if mwiEnabled + then parseErrorSDoc span $ text $ "parse error in if statement" + else parseErrorSDoc span $ text $ "parse error in if statement: "++msg + -- Hint about explicit-forall, assuming UnicodeSyntax is on hintExplicitForall :: SrcSpan -> P () hintExplicitForall span = do diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs index 6be82c16ef..0ce397a5d7 100644 --- a/compiler/typecheck/TcErrors.lhs +++ b/compiler/typecheck/TcErrors.lhs @@ -1089,10 +1089,22 @@ mk_dict_err fam_envs ctxt (ct, (matches, unifiers, safe_haskell)) , nest 19 (ptext (sLit "to") <+> quotes (ppr ty2)) ] -- The nesting makes the types line up | null givens && null matches - = ptext (sLit "No instance for") <+> pprParendType pred + = ptext (sLit "No instance for") + <+> pprParendType pred + $$ if type_has_arrow pred + then nest 2 $ ptext (sLit "(maybe you haven't applied enough arguments to a function?)") + else empty + | otherwise = ptext (sLit "Could not deduce") <+> pprParendType pred + type_has_arrow (TyVarTy _) = False + type_has_arrow (AppTy t1 t2) = type_has_arrow t1 || type_has_arrow t2 + type_has_arrow (TyConApp _ ts) = or $ map type_has_arrow ts + type_has_arrow (FunTy _ _) = True + type_has_arrow (ForAllTy _ t) = type_has_arrow t + type_has_arrow (LitTy _) = False + drv_fixes = case orig of DerivOrigin -> [drv_fix] DerivOriginDC {} -> [drv_fix] diff --git a/testsuite/tests/annotations/should_fail/annfail08.stderr b/testsuite/tests/annotations/should_fail/annfail08.stderr index b2d119de68..0449033685 100644 --- a/testsuite/tests/annotations/should_fail/annfail08.stderr +++ b/testsuite/tests/annotations/should_fail/annfail08.stderr @@ -1,9 +1,12 @@ annfail08.hs:9:1: No instance for (Data.Data.Data (a0 -> a0)) + (maybe you haven't applied enough arguments to a function?) arising from an annotation In the annotation: {-# ANN f (id + 1) #-} annfail08.hs:9:15: - No instance for (Num (a0 -> a0)) arising from a use of ‘+’ + No instance for (Num (a0 -> a0)) + (maybe you haven't applied enough arguments to a function?) + arising from a use of ‘+’ In the annotation: {-# ANN f (id + 1) #-} diff --git a/testsuite/tests/deriving/should_fail/drvfail007.stderr b/testsuite/tests/deriving/should_fail/drvfail007.stderr index 183a5ff8d5..91cf8bfa38 100644 --- a/testsuite/tests/deriving/should_fail/drvfail007.stderr +++ b/testsuite/tests/deriving/should_fail/drvfail007.stderr @@ -1,6 +1,7 @@ drvfail007.hs:4:38: No instance for (Eq (Int -> Int)) + (maybe you haven't applied enough arguments to a function?) arising from the first field of ‘Foo’ (type ‘Int -> Int’) Possible fix: use a standalone 'deriving instance' declaration, diff --git a/testsuite/tests/ghci.debugger/scripts/break003.stderr b/testsuite/tests/ghci.debugger/scripts/break003.stderr index 5baf41bcdf..7a9c08ec2f 100644 --- a/testsuite/tests/ghci.debugger/scripts/break003.stderr +++ b/testsuite/tests/ghci.debugger/scripts/break003.stderr @@ -1,4 +1,6 @@ <interactive>:5:1: - No instance for (Show (t -> t1)) arising from a use of ‘print’ + No instance for (Show (t -> t1)) + (maybe you haven't applied enough arguments to a function?) + arising from a use of ‘print’ In a stmt of an interactive GHCi command: print it diff --git a/testsuite/tests/ghci/scripts/Defer02.stderr b/testsuite/tests/ghci/scripts/Defer02.stderr index cbd2f3b64d..4f58b02695 100644 --- a/testsuite/tests/ghci/scripts/Defer02.stderr +++ b/testsuite/tests/ghci/scripts/Defer02.stderr @@ -27,7 +27,9 @@ In an equation for ‘c’: c (C2 x) = True ../../typecheck/should_run/Defer01.hs:28:5: Warning: - No instance for (Num (a -> a)) arising from the literal ‘1’ + No instance for (Num (a -> a)) + (maybe you haven't applied enough arguments to a function?) + arising from the literal ‘1’ In the expression: 1 In an equation for ‘d’: d = 1 @@ -133,7 +135,9 @@ In the first argument of ‘c’, namely ‘(C2 True)’ In the first argument of ‘print’, namely ‘(c (C2 True))’ *** Exception: ../../typecheck/should_run/Defer01.hs:28:5: - No instance for (Num (a -> a)) arising from the literal ‘1’ + No instance for (Num (a -> a)) + (maybe you haven't applied enough arguments to a function?) + arising from the literal ‘1’ In the expression: 1 In an equation for ‘d’: d = 1 (deferred type error) diff --git a/testsuite/tests/mdo/should_fail/mdofail005.stderr b/testsuite/tests/mdo/should_fail/mdofail005.stderr index 548129117a..594fea2a19 100644 --- a/testsuite/tests/mdo/should_fail/mdofail005.stderr +++ b/testsuite/tests/mdo/should_fail/mdofail005.stderr @@ -1,2 +1,4 @@ -mdofail005.hs:11:14: parse error on input ‘<-’ +mdofail005.hs:11:14: + parse error on input ‘<-’ + Perhaps this statement should be within a 'do' block? diff --git a/testsuite/tests/parser/should_fail/ParserNoLambdaCase.stderr b/testsuite/tests/parser/should_fail/ParserNoLambdaCase.stderr index 147c8fef9c..5a3f1cc080 100644 --- a/testsuite/tests/parser/should_fail/ParserNoLambdaCase.stderr +++ b/testsuite/tests/parser/should_fail/ParserNoLambdaCase.stderr @@ -1,2 +1,2 @@ -ParserNoLambdaCase.hs:3:6: parse error on input ‘case’ +ParserNoLambdaCase.hs:3:5: parse error: naked lambda expression '' diff --git a/testsuite/tests/parser/should_fail/readFail020.stderr b/testsuite/tests/parser/should_fail/readFail020.stderr index 0e3bde41da..0c00cdc79b 100644 --- a/testsuite/tests/parser/should_fail/readFail020.stderr +++ b/testsuite/tests/parser/should_fail/readFail020.stderr @@ -1,2 +1,3 @@ -readFail020.hs:3:16: parse error on input ‘}’ +readFail020.hs:3:5: + parse error in let binding: missing required 'in' diff --git a/testsuite/tests/parser/should_fail/readFail040.stderr b/testsuite/tests/parser/should_fail/readFail040.stderr index 6cbb3ce525..728090b9ec 100644 --- a/testsuite/tests/parser/should_fail/readFail040.stderr +++ b/testsuite/tests/parser/should_fail/readFail040.stderr @@ -1,2 +1,4 @@ -readFail040.hs:7:11: parse error on input ‘<-’ +readFail040.hs:7:11: + parse error on input ‘<-’ + Perhaps this statement should be within a 'do' block? diff --git a/testsuite/tests/rebindable/rebindable6.stderr b/testsuite/tests/rebindable/rebindable6.stderr index a02563f3ca..b9ae82096b 100644 --- a/testsuite/tests/rebindable/rebindable6.stderr +++ b/testsuite/tests/rebindable/rebindable6.stderr @@ -1,6 +1,7 @@ rebindable6.hs:106:17: No instance for (HasSeq (IO a -> t0 -> IO b)) + (maybe you haven't applied enough arguments to a function?) arising from a do statement The type variable ‘t0’ is ambiguous Relevant bindings include @@ -24,6 +25,7 @@ rebindable6.hs:106:17: rebindable6.hs:107:17: No instance for (HasFail ([Prelude.Char] -> t1)) + (maybe you haven't applied enough arguments to a function?) arising from a do statement The type variable ‘t1’ is ambiguous Note: there is a potential instance available: @@ -42,6 +44,7 @@ rebindable6.hs:107:17: rebindable6.hs:108:17: No instance for (HasReturn (b -> t1)) + (maybe you haven't applied enough arguments to a function?) arising from a use of ‘return’ The type variable ‘t1’ is ambiguous Relevant bindings include diff --git a/testsuite/tests/typecheck/should_fail/T2846b.stderr b/testsuite/tests/typecheck/should_fail/T2846b.stderr index 34d24ae8f6..ccf4f149ee 100644 --- a/testsuite/tests/typecheck/should_fail/T2846b.stderr +++ b/testsuite/tests/typecheck/should_fail/T2846b.stderr @@ -1,5 +1,7 @@ T2846b.hs:5:5: - No instance for (Show (Num a0 => a0)) arising from a use of ‘show’ + No instance for (Show (Num a0 => a0)) + (maybe you haven't applied enough arguments to a function?) + arising from a use of ‘show’ In the expression: show ([1, 2, 3] :: [Num a => a]) In an equation for ‘f’: f = show ([1, 2, 3] :: [Num a => a]) |