This fix is much better than #133, as it accounts for constraints (as demonstrated by the modified rank2 test case).
In addition to that, it fixes a problem with -c which made all polymorphic definitions unsafe. This grammar used to be accepted:
{
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
module Main where
import System.IO
import Data.Char
}
%name calc
%tokentype { Token }
%token tok { Token }
%monad { IO } { (>>=) } { return }
%%
a :: { Bool }
: n { $1 }
n :: { a }
: { (0::Int) }
{
main = calc [] >>= print
data Token = Token
lexer :: String -> [Token]
lexer _ = []
happyError tokens = ioError (userError "parse error")
}
It unsafeCoerce-d 0::Int to Bool and printed False.
With this patch it's rejected:
tests/rank2.hs:33:34: error: Not in scope: type variable ‘a’
|
33 | newtype HappyWrap5 = HappyWrap5 (a)
|
Polymorphism with -c now requires explicit forall. If we add it like so:
n :: { forall a. a }
: { (0::Int) }
We now get a proper error:
tests/rank2.hs:99:20: error:
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
a type expected by the context:
forall a. a
at tests/rank2.hs:(98,22)-(100,9)
• In the first argument of ‘happyIn5’, namely ‘((0 :: Int))’
In the expression: happyIn5 ((0 :: Int))
In an equation for ‘happyReduction_2’:
happyReduction_2 = happyIn5 ((0 :: Int))
|
99 | ((0::Int)
|
Fix #137
This fix is much better than #133, as it accounts for constraints (as demonstrated by the modified
rank2
test case).In addition to that, it fixes a problem with
-c
which made all polymorphic definitions unsafe. This grammar used to be accepted:It
unsafeCoerce
-d0::Int
toBool
and printedFalse
.With this patch it's rejected:
Polymorphism with
-c
now requires explicitforall
. If we add it like so:We now get a proper error: