diff options
author | Austin Seipp <aseipp@pobox.com> | 2013-08-18 23:01:57 -0500 |
---|---|---|
committer | Austin Seipp <aseipp@pobox.com> | 2013-08-18 23:01:57 -0500 |
commit | 96adf0e99b1a6595ee40ef9c05263a4fe73eb7c5 (patch) | |
tree | a80ec98ad604ad4428661b7c07163d09595b0c7c /compiler/parser/Parser.y.pp | |
parent | 5d77d8d4e007a6f332558620b3d62749afa00e24 (diff) | |
download | haskell-96adf0e99b1a6595ee40ef9c05263a4fe73eb7c5.tar.gz |
Improve error when using forall with UnicodeSyntax
Fixes Trac #7901.
'∀' is neither upper nor lowercase, unlike the 'f' in 'forall', so when
explicit forall is not enabled, it creates a parse error before reaching
the '.', which is where we give a nice message for ascii 'forall'.
Therefore, we make '∀' into a token as long as UnicodeSyntax is enabled,
which is safe because its caselessness means it can never be mistaken
for a symbol, and check extensions in the parser when the 'forall' rule
is used.
Authored-by: Paul Cavallaro <ptc@fb.com>
Authored-by: Anders Papitto <anderspapitto@gmail.com>
Signed-off-by: Austin Seipp <aseipp@pobox.com>
Diffstat (limited to 'compiler/parser/Parser.y.pp')
-rw-r--r-- | compiler/parser/Parser.y.pp | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp index 384fb537bf..9d087068bf 100644 --- a/compiler/parser/Parser.y.pp +++ b/compiler/parser/Parser.y.pp @@ -1050,7 +1050,8 @@ strict_mark :: { Located HsBang } -- A ctype is a for-all type ctype :: { LHsType RdrName } - : 'forall' tv_bndrs '.' ctype { LL $ mkExplicitHsForAllTy $2 (noLoc []) $4 } + : 'forall' tv_bndrs '.' ctype {% hintExplicitForall (getLoc $1) >> + return (LL $ mkExplicitHsForAllTy $2 (noLoc []) $4) } | context '=>' ctype { LL $ mkImplicitHsForAllTy $1 $3 } -- A type of form (context => type) is an *implicit* HsForAllTy | ipvar '::' type { LL (HsIParamTy (unLoc $1) $3) } @@ -1068,7 +1069,8 @@ ctype :: { LHsType RdrName } -- to 'field' or to 'Int'. So we must use `ctype` to describe the type. ctypedoc :: { LHsType RdrName } - : 'forall' tv_bndrs '.' ctypedoc { LL $ mkExplicitHsForAllTy $2 (noLoc []) $4 } + : 'forall' tv_bndrs '.' ctypedoc {% hintExplicitForall (getLoc $1) >> + return (LL $ mkExplicitHsForAllTy $2 (noLoc []) $4) } | context '=>' ctypedoc { LL $ mkImplicitHsForAllTy $1 $3 } -- A type of form (context => type) is an *implicit* HsForAllTy | ipvar '::' type { LL (HsIParamTy (unLoc $1) $3) } @@ -2240,4 +2242,15 @@ hintMultiWayIf span = do mwiEnabled <- liftM ((Opt_MultiWayIf `xopt`) . dflags) getPState unless mwiEnabled $ parseErrorSDoc span $ text "Multi-way if-expressions need -XMultiWayIf turned on" + +-- Hint about explicit-forall, assuming UnicodeSyntax is on +hintExplicitForall :: SrcSpan -> P () +hintExplicitForall span = do + forall <- extension explicitForallEnabled + rulePrag <- extension inRulePrag + unless (forall || rulePrag) $ parseErrorSDoc span $ vcat + [ text "Illegal symbol '∀' in type" + , text "Perhaps you intended -XRankNTypes or similar flag" + , text "to enable explicit-forall syntax: ∀ <tvs>. <type>" + ] } |