summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/parser/Lexer.x2
-rw-r--r--compiler/parser/Parser.y39
-rw-r--r--compiler/typecheck/TcErrors.lhs14
-rw-r--r--testsuite/tests/annotations/should_fail/annfail08.stderr5
-rw-r--r--testsuite/tests/deriving/should_fail/drvfail007.stderr1
-rw-r--r--testsuite/tests/ghci.debugger/scripts/break003.stderr4
-rw-r--r--testsuite/tests/ghci/scripts/Defer02.stderr8
-rw-r--r--testsuite/tests/mdo/should_fail/mdofail005.stderr4
-rw-r--r--testsuite/tests/parser/should_fail/ParserNoLambdaCase.stderr2
-rw-r--r--testsuite/tests/parser/should_fail/readFail020.stderr3
-rw-r--r--testsuite/tests/parser/should_fail/readFail040.stderr4
-rw-r--r--testsuite/tests/rebindable/rebindable6.stderr3
-rw-r--r--testsuite/tests/typecheck/should_fail/T2846b.stderr4
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])