diff options
| author | Simon Peyton Jones <simonpj@microsoft.com> | 2014-12-13 22:47:01 +0000 |
|---|---|---|
| committer | Simon Peyton Jones <simonpj@microsoft.com> | 2014-12-15 10:06:55 +0000 |
| commit | fbb42b2ea42b6467135f26db47d9c296e7ad75a3 (patch) | |
| tree | 1caff6c78d38545b8692176b707c049a34cd36e3 /compiler | |
| parent | 71105aea894d9c39c35248865907207e169f819d (diff) | |
| download | haskell-fbb42b2ea42b6467135f26db47d9c296e7ad75a3.tar.gz | |
Pattern-synonym matcher and builder Ids must be *LocalIds*
This easy-to-make mistake meant that pattern-synonym matcher and
builder Ids weren't being treated as locally defined by the simpplier.
That meant that we never looked up them up in the environment, got an
out-of-date unfolding, which made the Simplifier fall into an infinite
loop. This was the cause of Trac #98587, but it was quite tricky to
find!
In a separate patch I'll make Lint check for locally-bound GlobalIds,
since they are always an error.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/basicTypes/Id.hs | 5 | ||||
| -rw-r--r-- | compiler/typecheck/TcPatSyn.hs | 7 |
2 files changed, 9 insertions, 3 deletions
diff --git a/compiler/basicTypes/Id.hs b/compiler/basicTypes/Id.hs index fa34a4fd78..ccd6c9b494 100644 --- a/compiler/basicTypes/Id.hs +++ b/compiler/basicTypes/Id.hs @@ -314,6 +314,7 @@ We use mkExportedLocalId for things like - Dictionary functions (DFunId) - Wrapper and matcher Ids for pattern synonyms - Default methods for classes + - Pattern-synonym matcher and builder Ids - etc They marked as "exported" in the sense that they should be kept alive @@ -329,7 +330,9 @@ of reasons: dependency analysis (e.g. CoreFVs.exprFreeVars). * Look them up in the current substitution when we come across - occurrences of them (in Subst.lookupIdSubst) + occurrences of them (in Subst.lookupIdSubst). Lacking this we + can get an out-of-date unfolding, which can in turn make the + simplifier go into an infinite loop (Trac #9857) * Ensure that for dfuns that the specialiser does not float dict uses above their defns, which would prevent good simplifications happening. diff --git a/compiler/typecheck/TcPatSyn.hs b/compiler/typecheck/TcPatSyn.hs index 9cc49111ac..65339818fe 100644 --- a/compiler/typecheck/TcPatSyn.hs +++ b/compiler/typecheck/TcPatSyn.hs @@ -26,6 +26,7 @@ import Outputable import FastString import Var import Id +import IdInfo( IdDetails(..) ) import TcBinds import BasicTypes import TcSimplify @@ -254,7 +255,8 @@ tcPatSynMatcher (L loc name) lpat ; let matcher_tau = mkFunTys [pat_ty, cont_ty, fail_ty] res_ty matcher_sigma = mkSigmaTy (res_tv:univ_tvs) req_theta matcher_tau - matcher_id = mkVanillaGlobal matcher_name matcher_sigma + matcher_id = mkExportedLocalId VanillaId matcher_name matcher_sigma + -- See Note [Exported LocalIds] in Id cont_dicts = map nlHsVar prov_dicts cont' = mkLHsWrap (mkWpLet prov_ev_binds) $ @@ -326,7 +328,8 @@ mkPatSynBuilderId dir (L _ name) qtvs theta arg_tys pat_ty | otherwise = do { builder_name <- newImplicitBinder name mkDataConWorkerOcc ; let builder_sigma = mkSigmaTy qtvs theta (mkFunTys builder_arg_tys pat_ty) - builder_id = mkVanillaGlobal builder_name builder_sigma + builder_id = mkExportedLocalId VanillaId builder_name builder_sigma + -- See Note [Exported LocalIds] in Id ; return (Just (builder_id, need_dummy_arg)) } where builder_arg_tys | need_dummy_arg = [voidPrimTy] |
