[commit: ghc] master: zonkCt tries to maintain the canonical form of a Ct. (07292e9)
git at git.haskell.org
git at git.haskell.org
Sun Feb 12 01:08:54 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/07292e958cb0c08705d9a694f09d9621058b16e6/ghc
>---------------------------------------------------------------
commit 07292e958cb0c08705d9a694f09d9621058b16e6
Author: Christiaan Baaij <christiaan.baaij at gmail.com>
Date: Sat Feb 11 19:21:52 2017 -0500
zonkCt tries to maintain the canonical form of a Ct.
For example,
- a CDictCan should stay a CDictCan;
- a CTyEqCan should stay a CTyEqCan (if the LHS stays as a variable.).
- a CHoleCan should stay a CHoleCan
Why? For CDicteqCan see Trac #11525.
Test Plan: Validate
Reviewers: austin, adamgundry, simonpj, goldfire, bgamari
Reviewed By: simonpj, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D3105
>---------------------------------------------------------------
07292e958cb0c08705d9a694f09d9621058b16e6
compiler/typecheck/TcMType.hs | 40 +++++++++++++++++++++-
testsuite/tests/typecheck/should_compile/T11525.hs | 26 ++++++++++++++
.../{T11462_Plugin.hs => T11525_Plugin.hs} | 2 +-
testsuite/tests/typecheck/should_compile/all.T | 3 ++
4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/compiler/typecheck/TcMType.hs b/compiler/typecheck/TcMType.hs
index d9105b3..56cc711 100644
--- a/compiler/typecheck/TcMType.hs
+++ b/compiler/typecheck/TcMType.hs
@@ -1355,12 +1355,50 @@ zonkSimples cts = do { cts' <- mapBagM zonkCt' cts
zonkCt' :: Ct -> TcM Ct
zonkCt' ct = zonkCt ct
+{- Note [zonkCt behaviour]
+zonkCt tries to maintain the canonical form of a Ct. For example,
+ - a CDictCan should stay a CDictCan;
+ - a CTyEqCan should stay a CTyEqCan (if the LHS stays as a variable.).
+ - a CHoleCan should stay a CHoleCan
+
+Why?, for example:
+- For CDictCan, the @TcSimplify.expandSuperClasses@ step, which runs after the
+ simple wanted and plugin loop, looks for @CDictCan at s. If a plugin is in use,
+ constraints are zonked before being passed to the plugin. This means if we
+ don't preserve a canonical form, @expandSuperClasses@ fails to expand
+ superclasses. This is what happened in Trac #11525.
+
+- For CHoleCan, once we forget that it's a hole, we can never recover that info.
+
+NB: we do not expect to see any CFunEqCans, because zonkCt is only
+called on unflattened constraints.
+NB: Constraints are always re-flattened etc by the canonicaliser in
+ at TcCanonical@ even if they come in as CDictCan. Only canonical constraints that
+are actually in the inert set carry all the guarantees. So it is okay if zonkCt
+creates e.g. a CDictCan where the cc_tyars are /not/ function free.
+-}
zonkCt :: Ct -> TcM Ct
zonkCt ct@(CHoleCan { cc_ev = ev })
= do { ev' <- zonkCtEvidence ev
; return $ ct { cc_ev = ev' } }
+zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args })
+ = do { ev' <- zonkCtEvidence ev
+ ; args' <- mapM zonkTcType args
+ ; return $ ct { cc_ev = ev', cc_tyargs = args' } }
+zonkCt ct@(CTyEqCan { cc_ev = ev, cc_tyvar = tv, cc_rhs = rhs })
+ = do { ev' <- zonkCtEvidence ev
+ ; tv_ty' <- zonkTcTyVar tv
+ ; case getTyVar_maybe tv_ty' of
+ Just tv' -> do { rhs' <- zonkTcType rhs
+ ; return ct { cc_ev = ev'
+ , cc_tyvar = tv'
+ , cc_rhs = rhs' } }
+ Nothing -> return (mkNonCanonical ev') }
zonkCt ct
- = do { fl' <- zonkCtEvidence (cc_ev ct)
+ = ASSERT( not (isCFunEqCan ct) )
+ -- We do not expect to see any CFunEqCans, because zonkCt is only called on
+ -- unflattened constraints.
+ do { fl' <- zonkCtEvidence (cc_ev ct)
; return (mkNonCanonical fl') }
zonkCtEvidence :: CtEvidence -> TcM CtEvidence
diff --git a/testsuite/tests/typecheck/should_compile/T11525.hs b/testsuite/tests/typecheck/should_compile/T11525.hs
new file mode 100644
index 0000000..406bf5f
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T11525.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE DataKinds, TypeOperators, KindSignatures, TypeFamilies,
+ ConstraintKinds, FlexibleContexts #-}
+{-# OPTIONS_GHC -fplugin T11525_Plugin #-}
+module T11525 where
+
+import GHC.TypeLits
+import Data.Proxy
+
+truncateB :: KnownNat a => Proxy (a + b) -> Proxy a
+truncateB Proxy = Proxy
+
+class Bus t where
+ type AddrBits t :: Nat
+
+data MasterOut b = MasterOut
+ { adr :: Proxy (AddrBits b)
+ }
+
+type WiderAddress b b' k = ( KnownNat (AddrBits b)
+ , AddrBits b' ~ (AddrBits b + k)
+ )
+
+narrowAddress' :: (WiderAddress b b' k)
+ => MasterOut b'
+ -> MasterOut b
+narrowAddress' m = MasterOut { adr = truncateB (adr m) }
diff --git a/testsuite/tests/typecheck/should_compile/T11462_Plugin.hs b/testsuite/tests/typecheck/should_compile/T11525_Plugin.hs
similarity index 91%
copy from testsuite/tests/typecheck/should_compile/T11462_Plugin.hs
copy to testsuite/tests/typecheck/should_compile/T11525_Plugin.hs
index 5d98395..bc1ffc4 100644
--- a/testsuite/tests/typecheck/should_compile/T11462_Plugin.hs
+++ b/testsuite/tests/typecheck/should_compile/T11525_Plugin.hs
@@ -1,4 +1,4 @@
-module T11462_Plugin(plugin) where
+module T11525_Plugin(plugin) where
import TcRnMonad ( TcPlugin(..), TcPluginResult(..) )
import Plugins ( defaultPlugin, Plugin(..), CommandLineOption )
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T
index 7d2e3c6..286ebbb 100644
--- a/testsuite/tests/typecheck/should_compile/all.T
+++ b/testsuite/tests/typecheck/should_compile/all.T
@@ -536,3 +536,6 @@ test('T11723', normal, compile, [''])
test('T12987', normal, compile, [''])
test('T11736', normal, compile, [''])
test('T13248', expect_broken(13248), compile, [''])
+test('T11525', [unless(have_dynamic(), expect_broken(10301))], multi_compile,
+ ['', [('T11525_Plugin.hs', '-package ghc'), ('T11525.hs', '')],
+ '-dynamic'])
More information about the ghc-commits
mailing list