Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : ghc-7.6

http://hackage.haskell.org/trac/ghc/changeset/c41ca7980664c73cfbd27b0d9f9c081ecf7dc25c

>---------------------------------------------------------------

commit c41ca7980664c73cfbd27b0d9f9c081ecf7dc25c
Author: Simon Peyton Jones <simo...@microsoft.com>
Date:   Tue Nov 6 15:55:39 2012 +0000

    Fix the instantiation of data constructors in the GHCi debugger
    
    This bug caused Trac #7386, because in the (rather tricky) "type
    inference" (aka run time type reconstruction) done by the GHCi
    debugger, we were failing to instantiate a data type family
    correctly.  When that code was written we didn't *have* data
    families.
    
    I wrote Note [Constructor arg types] to explain the new scheme.

>---------------------------------------------------------------

 compiler/ghci/RtClosureInspect.hs |   39 ++++++++++++++++++++++++++++++++----
 1 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/compiler/ghci/RtClosureInspect.hs 
b/compiler/ghci/RtClosureInspect.hs
index f06d120..dcb35cc 100644
--- a/compiler/ghci/RtClosureInspect.hs
+++ b/compiler/ghci/RtClosureInspect.hs
@@ -749,7 +749,7 @@ cvObtainTerm hsc_env max_depth force old_ty hval = runTR 
hsc_env $ do
                         -- In such case, we return a best approximation:
                         --  ignore the unpointed args, and recover the pointeds
                         -- This preserves laziness, and should be safe.
-                      traceTR (text "Nothing" <+> ppr dcname)
+                      traceTR (text "Not constructor" <+> ppr dcname)
                        let dflags = hsc_dflags hsc_env
                            tag = showPpr dflags dcname
                        vars     <- replicateM (length$ elems$ ptrs clos) 
@@ -758,7 +758,7 @@ cvObtainTerm hsc_env max_depth force old_ty hval = runTR 
hsc_env $ do
                                               | (i, tv) <- zip [0..] vars]
                        return (Term my_ty (Left ('<' : tag ++ ">")) a subTerms)
           Just dc -> do
-            traceTR (text "Just" <+> ppr dc)
+            traceTR (text "Is constructor" <+> (ppr dc $$ ppr my_ty))
             subTtypes <- getDataConArgTys dc my_ty
             subTerms <- extractSubTerms (\ty -> go (pred max_depth) ty ty) 
clos subTtypes
             return (Term my_ty (Right dc) a subTerms)
@@ -936,14 +936,16 @@ getDataConArgTys :: DataCon -> Type -> TR [Type]
 -- not be fully known.  Moreover, the arg types might involve existentials;
 -- if so, make up fresh RTTI type variables for them
 getDataConArgTys dc con_app_ty
-  = do { (_, ex_tys, _) <- instTyVars ex_tvs
+  = do { (_, ex_tys, ex_subst) <- instTyVars ex_tvs
        ; let UnaryRep rep_con_app_ty = repType con_app_ty
+       ; traceTR (text "getDataConArgTys 1" <+> (ppr con_app_ty $$ ppr 
rep_con_app_ty))
        ; ty_args <- case tcSplitTyConApp_maybe rep_con_app_ty of
                        Just (tc, ty_args) | dataConTyCon dc == tc
                           -> ASSERT( univ_tvs `equalLength` ty_args) 
                               return ty_args
-                      _   -> do { (_, ty_args, subst) <- instTyVars univ_tvs
-                                ; let res_ty = substTy subst (dataConOrigResTy 
dc)
+                      _   -> do { (_, ty_args, univ_subst) <- instTyVars 
univ_tvs
+                                ; let res_ty = substTy ex_subst (substTy 
univ_subst (dataConOrigResTy dc))
+                                   -- See Note [Constructor arg types]
                                  ; addConstraint rep_con_app_ty res_ty
                                  ; return ty_args }
                -- It is necessary to check dataConTyCon dc == tc
@@ -951,11 +953,38 @@ getDataConArgTys dc con_app_ty
                -- newtype and tcSplitTyConApp has not removed it. In
                -- that case, we happily give up and don't match
        ; let subst = zipTopTvSubst (univ_tvs ++ ex_tvs) (ty_args ++ ex_tys)
+       ; traceTR (text "getDataConArgTys 2" <+> (ppr rep_con_app_ty $$ ppr 
ty_args $$ ppr subst))
        ; return (substTys subst (dataConRepArgTys dc)) }
   where
     univ_tvs = dataConUnivTyVars dc
     ex_tvs   = dataConExTyVars dc
 
+{- Note [Constructor arg types]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider a GADT (cf Trac #7386)
+   data family D a b
+   data instance D [a] b where
+     MkT :: b -> D [a] (Maybe b)
+
+In getDataConArgTys
+* con_app_ty is the known type (from outside) of the constructor application, 
+  say D [Int] Bool
+
+* The data constructor MkT has a (representation) dataConTyCon = DList,
+  say where
+    data DList a b where
+      MkT :: b -> DList a (Maybe b)
+
+So the dataConTyCon of the data constructor, DList, differs from 
+the "outside" type, D. So we can't straightforwardly decompose the
+"outside" type, and we end up in the "_" branch of the case.
+
+Then we match the dataConOrigResTy of the data constructor against the
+outside type, hoping to get a substituion that tells how to instantiate
+the *representation* type constructor.   This looks a bit delicate to
+me, but it seems to work.
+-}
+
 -- Soundness checks
 --------------------
 {-



_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to