X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcSimplify.lhs;h=d8c31946592fd58dcb4b8cc71b574a81045545df;hb=55d04fc7a6fbd58358f284bd84648dad09046f60;hp=bfaf629d9d2d1876a8e75cdf0526206c70293fc1;hpb=b58e1155b0ec79ec6983c3e9a42880d511b7bc10;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcSimplify.lhs b/ghc/compiler/typecheck/TcSimplify.lhs index bfaf629..d8c3194 100644 --- a/ghc/compiler/typecheck/TcSimplify.lhs +++ b/ghc/compiler/typecheck/TcSimplify.lhs @@ -7,7 +7,8 @@ \begin{code} module TcSimplify ( - tcSimplifyInfer, tcSimplifyInferCheck, tcSimplifyCheck, + tcSimplifyInfer, tcSimplifyInferCheck, tcSimplifyCheck, + tcSimplifyRestricted, tcSimplifyToDicts, tcSimplifyIPs, tcSimplifyTop, tcSimplifyThetas, tcSimplifyCheckThetas, @@ -323,6 +324,15 @@ URK! Let's not do this. So this is illegal: f :: Int -> Int f x = x + ?y +There's a nasty corner case when the monomorphism restriction bites: + + f = x + ?y + +The argument above suggests that we must generalise over the ?y parameter, +but the monomorphism restriction says that we can't. The current +implementation chooses to let the monomorphism restriction 'win' in this +case, but it's not clear what the Right Thing is. + BOTTOM LINE: you *must* quantify over implicit parameters. @@ -479,33 +489,45 @@ tcSimplifyCheck TcDictBinds) -- Bindings tcSimplifyCheck doc qtvs givens wanted_lie - = checkLoop doc qtvs givens (lieToList wanted_lie) `thenTc` \ (frees, binds, irreds) -> + = checkLoop doc qtvs givens (lieToList wanted_lie) try `thenTc` \ (frees, binds, irreds) -> -- Complain about any irreducible ones complainCheck doc givens irreds `thenNF_Tc_` -- Done returnTc (mkLIE frees, binds) + where + -- When checking against a given signature we always reduce + -- until we find a match against something given, or can't reduce + try qtvs inst | isFree qtvs inst = Free + | otherwise = ReduceMe -checkLoop doc qtvs givens wanteds - = -- Step 1 +tcSimplifyRestricted doc qtvs givens wanted_lie + = checkLoop doc qtvs givens (lieToList wanted_lie) try `thenTc` \ (frees, binds, irreds) -> + + -- Complain about any irreducible ones + complainCheck doc givens irreds `thenNF_Tc_` + + -- Done + returnTc (mkLIE frees, binds) + where + try qtvs inst | not (tyVarsOfInst inst `intersectsVarSet` qtvs) = Free + | otherwise = ReduceMe + +checkLoop doc qtvs givens wanteds try_me + = -- Step 1 zonkTcTyVarsAndFV qtvs `thenNF_Tc` \ qtvs' -> mapNF_Tc zonkInst givens `thenNF_Tc` \ givens' -> mapNF_Tc zonkInst wanteds `thenNF_Tc` \ wanteds' -> - let - -- When checking against a given signature we always reduce - -- until we find a match against something given, or can't reduce - try_me inst | isFree qtvs' inst = Free - | otherwise = ReduceMe - in + -- Step 2 - reduceContext doc try_me givens' wanteds' `thenTc` \ (no_improvement, frees, binds, irreds) -> + reduceContext doc (try_me qtvs') givens' wanteds' `thenTc` \ (no_improvement, frees, binds, irreds) -> -- Step 3 if no_improvement then returnTc (frees, binds, irreds) else - checkLoop doc qtvs givens' (irreds ++ frees) `thenTc` \ (frees1, binds1, irreds1) -> + checkLoop doc qtvs givens' (irreds ++ frees) try_me `thenTc` \ (frees1, binds1, irreds1) -> returnTc (frees1, binds `AndMonoBinds` binds1, irreds1) complainCheck doc givens irreds