[Git][ghc/ghc][wip/t23703] Allow per constructor refinement of distinct-constructor-tables
Finley McIlwaine (@FinleyMcIlwaine)
gitlab at gitlab.haskell.org
Tue Sep 12 17:50:55 UTC 2023
Finley McIlwaine pushed to branch wip/t23703 at Glasgow Haskell Compiler / GHC
Commits:
50648a3c by Finley McIlwaine at 2023-09-12T10:50:41-07:00
Allow per constructor refinement of distinct-constructor-tables
Introduce `-fno-distinct-constructor-tables`. A distinct constructor table
configuration is built from the combination of flags given, in order. For
example, to create distinct constructor tables for all constructors except for a
specific few named `C1`,..., `CN`, pass `-fdistinct-contructor-tables` followed
by `fno-distinct-constructor-tables=C1,...,CN`. To only generate distinct
constuctor tables for a few specific constructors and no others, just pass
`-fdistinct-constructor-tables=C1,...,CN`.
The various configuations of these flags is included in the dynflags
fingerprints, which should result in the expected recompilation logic.
Adds a test that checks for distinct tables for various given or omitted
constructors.
Updates CountDepsAst and CountDepsParser tests to account for new dependencies.
Fixes #23703
- - - - -
24 changed files:
- compiler/GHC/Driver/Config/Stg/Debug.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Iface/Recomp/Flags.hs
- compiler/GHC/Stg/Debug.hs
- + compiler/GHC/Stg/Debug/Types.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.10.1-notes.rst
- docs/users_guide/debug-info.rst
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/rts/ipe/distinct-tables/ACon.out
- + testsuite/tests/rts/ipe/distinct-tables/AConBCon.out
- + testsuite/tests/rts/ipe/distinct-tables/BCon.out
- + testsuite/tests/rts/ipe/distinct-tables/CCon.out
- + testsuite/tests/rts/ipe/distinct-tables/Main.hs
- + testsuite/tests/rts/ipe/distinct-tables/Makefile
- + testsuite/tests/rts/ipe/distinct-tables/NoACon.out
- + testsuite/tests/rts/ipe/distinct-tables/NoBCon.out
- + testsuite/tests/rts/ipe/distinct-tables/NoBConCCon.out
- + testsuite/tests/rts/ipe/distinct-tables/NoCCon.out
- + testsuite/tests/rts/ipe/distinct-tables/X.hs
- + testsuite/tests/rts/ipe/distinct-tables/all.T
Changes:
=====================================
compiler/GHC/Driver/Config/Stg/Debug.hs
=====================================
@@ -10,5 +10,5 @@ import GHC.Driver.DynFlags
initStgDebugOpts :: DynFlags -> StgDebugOpts
initStgDebugOpts dflags = StgDebugOpts
{ stgDebug_infoTableMap = gopt Opt_InfoTableMap dflags
- , stgDebug_distinctConstructorTables = gopt Opt_DistinctConstructorTables dflags
+ , stgDebug_distinctConstructorTables = distinctConstructorTables dflags
}
=====================================
compiler/GHC/Driver/DynFlags.hs
=====================================
@@ -111,6 +111,7 @@ import GHC.Types.SrcLoc
import GHC.Unit.Module
import GHC.Unit.Module.Warnings
import GHC.Utils.CliOption
+import GHC.Stg.Debug.Types (StgDebugDctConfig(..))
import GHC.SysTools.Terminal ( stderrSupportsAnsiColors )
import GHC.UniqueSubdir (uniqueSubdir)
import GHC.Utils.Outputable
@@ -128,6 +129,7 @@ import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.Writer (WriterT)
+import qualified Data.Set as Set
import Data.Word
import System.IO
import System.IO.Error (catchIOError)
@@ -136,8 +138,6 @@ import System.FilePath (normalise, (</>))
import System.Directory
import GHC.Foreign (withCString, peekCString)
-import qualified Data.Set as Set
-
import qualified GHC.LanguageExtensions as LangExt
-- -----------------------------------------------------------------------------
@@ -457,7 +457,11 @@ data DynFlags = DynFlags {
-- 'Int' because it can be used to test uniques in decreasing order.
-- | Temporary: CFG Edge weights for fast iterations
- cfgWeights :: Weights
+ cfgWeights :: Weights,
+
+ -- | Configuration specifying which constructor names we should create
+ -- distinct info tables for
+ distinctConstructorTables :: StgDebugDctConfig
}
class HasDynFlags m where
@@ -702,7 +706,9 @@ defaultDynFlags mySettings =
reverseErrors = False,
maxErrors = Nothing,
- cfgWeights = defaultWeights
+ cfgWeights = defaultWeights,
+
+ distinctConstructorTables = None
}
type FatalMessager = String -> IO ()
=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -222,7 +222,6 @@ data GeneralFlag
| Opt_FastLlvm -- hidden flag
| Opt_NoTypeableBinds
- | Opt_DistinctConstructorTables
| Opt_InfoTableMap
| Opt_InfoTableMapWithFallback
| Opt_InfoTableMapWithStack
@@ -581,7 +580,6 @@ codeGenFlags = EnumSet.fromList
, Opt_DoTagInferenceChecks
-- Flags that affect debugging information
- , Opt_DistinctConstructorTables
, Opt_InfoTableMap
, Opt_InfoTableMapWithStack
, Opt_InfoTableMapWithFallback
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -261,6 +261,7 @@ import GHC.Utils.Outputable
import GHC.Settings
import GHC.CmmToAsm.CFG.Weight
import GHC.Core.Opt.CallerCC
+import GHC.Stg.Debug.Types
import GHC.SysTools.BaseDir ( expandToolDir, expandTopDir )
@@ -1796,6 +1797,10 @@ dynamic_flags_deps = [
-- Caller-CC
, make_ord_flag defGhcFlag "fprof-callers"
(HasArg setCallerCcFilters)
+ , make_ord_flag defGhcFlag "fdistinct-constructor-tables"
+ (OptPrefix setDistinctConstructorTables)
+ , make_ord_flag defGhcFlag "fno-distinct-constructor-tables"
+ (OptPrefix unSetDistinctConstructorTables)
------ Compiler flags -----------------------------------------------
, make_ord_flag defGhcFlag "fasm" (NoArg (setObjBackend ncgBackend))
@@ -2477,7 +2482,6 @@ fFlagsDeps = [
flagSpec "cmm-thread-sanitizer" Opt_CmmThreadSanitizer,
flagSpec "split-sections" Opt_SplitSections,
flagSpec "break-points" Opt_InsertBreakpoints,
- flagSpec "distinct-constructor-tables" Opt_DistinctConstructorTables,
flagSpec "info-table-map" Opt_InfoTableMap,
flagSpec "info-table-map-with-stack" Opt_InfoTableMapWithStack,
flagSpec "info-table-map-with-fallback" Opt_InfoTableMapWithFallback
@@ -3310,6 +3314,39 @@ setCallerCcFilters arg =
Right filt -> upd $ \d -> d { callerCcFilters = filt : callerCcFilters d }
Left err -> addErr err
+setDistinctConstructorTables :: String -> DynP ()
+setDistinctConstructorTables arg = do
+ let cs = parseDistinctConstructorTablesArg arg
+ upd $ \d ->
+ d { distinctConstructorTables =
+ (distinctConstructorTables d) `dctConfigPlus` cs
+ }
+
+unSetDistinctConstructorTables :: String -> DynP ()
+unSetDistinctConstructorTables arg = do
+ let cs = parseDistinctConstructorTablesArg arg
+ upd $ \d ->
+ d { distinctConstructorTables =
+ (distinctConstructorTables d) `dctConfigMinus` cs
+ }
+
+-- | Parse a string of comma-separated constructor names into a 'Set' of
+-- 'String's with one entry per constructor.
+parseDistinctConstructorTablesArg :: String -> Set.Set String
+parseDistinctConstructorTablesArg =
+ -- Ensure we insert the last constructor name built by the fold, if not
+ -- empty
+ uncurry insertNonEmpty
+ . foldr go ("", Set.empty)
+ where
+ go :: Char -> (String, Set.Set String) -> (String, Set.Set String)
+ go ',' (cur, acc) = ("", Set.insert cur acc)
+ go c (cur, acc) = (c : cur, acc)
+
+ insertNonEmpty :: String -> Set.Set String -> Set.Set String
+ insertNonEmpty "" = id
+ insertNonEmpty cs = Set.insert cs
+
setMainIs :: String -> DynP ()
setMainIs arg
| x:_ <- main_fn, isLower x -- The arg looked like "Foo.Bar.baz"
=====================================
compiler/GHC/Iface/Recomp/Flags.hs
=====================================
@@ -68,7 +68,7 @@ fingerprintDynFlags hsc_env this_mod nameio =
map (`gopt` dflags) [Opt_Ticky, Opt_Ticky_Allocd, Opt_Ticky_LNE, Opt_Ticky_Dyn_Thunk, Opt_Ticky_Tag]
-- Other flags which affect code generation
- codegen = map (`gopt` dflags) (EnumSet.toList codeGenFlags)
+ codegen = (map (`gopt` dflags) (EnumSet.toList codeGenFlags), distinctConstructorTables)
flags = ((mainis, safeHs, lang, cpp), (paths, prof, ticky, codegen, debugLevel, callerCcFilters))
=====================================
compiler/GHC/Stg/Debug.hs
=====================================
@@ -1,9 +1,13 @@
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TupleSections #-}
-- This module contains functions which implement
-- the -finfo-table-map and -fdistinct-constructor-tables flags
module GHC.Stg.Debug
( StgDebugOpts(..)
+ , StgDebugDctConfig(..)
+ , dctConfigPlus
+ , dctConfigMinus
, collectDebugInformation
) where
@@ -16,11 +20,14 @@ import GHC.Types.Tickish
import GHC.Core.DataCon
import GHC.Types.IPE
import GHC.Unit.Module
-import GHC.Types.Name ( getName, getOccName, occNameFS, nameSrcSpan)
+import GHC.Types.Name ( getName, getOccName, occNameFS, nameSrcSpan, occName, occNameString)
import GHC.Data.FastString
+import GHC.Stg.Debug.Types
import Control.Monad (when)
import Control.Monad.Trans.Reader
+import Data.Set (Set)
+import qualified Data.Set as Set
import GHC.Utils.Monad.State.Strict
import Control.Monad.Trans.Class
import GHC.Types.Unique.Map
@@ -29,13 +36,6 @@ import Control.Applicative
import qualified Data.List.NonEmpty as NE
import Data.List.NonEmpty (NonEmpty(..))
-data SpanWithLabel = SpanWithLabel RealSrcSpan LexicalFastString
-
-data StgDebugOpts = StgDebugOpts
- { stgDebug_infoTableMap :: !Bool
- , stgDebug_distinctConstructorTables :: !Bool
- }
-
data R = R { rOpts :: StgDebugOpts, rModLocation :: ModLocation, rSpan :: Maybe SpanWithLabel }
type M a = ReaderT R (State InfoTableProvMap) a
@@ -160,10 +160,11 @@ numberDataCon dc _ | isUnboxedTupleDataCon dc = return NoNumber
numberDataCon dc _ | isUnboxedSumDataCon dc = return NoNumber
numberDataCon dc ts = do
opts <- asks rOpts
- if stgDebug_distinctConstructorTables opts then do
- -- -fdistinct-constructor-tables is enabled. Add an entry to the data
- -- constructor map for this occurence of the data constructor with a unique
- -- number and a src span
+ if shouldMakeDistinctTable opts dc then do
+ -- -fdistinct-constructor-tables is enabled and we do want to make distinct
+ -- tables for this constructor. Add an entry to the data constructor map for
+ -- this occurence of the data constructor with a unique number and a src
+ -- span
env <- lift get
mcc <- asks rSpan
let
@@ -188,7 +189,8 @@ numberDataCon dc ts = do
Nothing -> NoNumber
Just res -> Numbered (fst (NE.head res))
else do
- -- -fdistinct-constructor-tables is not enabled
+ -- -fdistinct-constructor-tables is not enabled, or we do not want to make
+ -- distinct tables for this specific constructor
return NoNumber
selectTick :: [StgTickish] -> Maybe (RealSrcSpan, LexicalFastString)
@@ -198,6 +200,20 @@ selectTick = foldl' go Nothing
go _ (SourceNote rss d) = Just (rss, d)
go acc _ = acc
+-- | Descide whether a distinct info table should be made for a usage of a data
+-- constructor. We only want to do this if -fdistinct-constructor-tables was
+-- given and this constructor name was given, or no constructor names were
+-- given.
+shouldMakeDistinctTable :: StgDebugOpts -> DataCon -> Bool
+shouldMakeDistinctTable StgDebugOpts{..} dc =
+ case stgDebug_distinctConstructorTables of
+ All -> True
+ Only these -> Set.member dcStr these
+ AllExcept these -> Set.notMember dcStr these
+ None -> False
+ where
+ dcStr = occNameString . occName $ dataConName dc
+
{-
Note [Mapping Info Tables to Source Positions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Stg/Debug/Types.hs
=====================================
@@ -0,0 +1,102 @@
+module GHC.Stg.Debug.Types where
+
+import GHC.Prelude
+
+import GHC.Data.FastString
+import GHC.Types.SrcLoc
+import GHC.Utils.Binary (Binary)
+import qualified GHC.Utils.Binary as B
+
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+data SpanWithLabel = SpanWithLabel RealSrcSpan LexicalFastString
+
+data StgDebugOpts = StgDebugOpts
+ { stgDebug_infoTableMap :: !Bool
+ , stgDebug_distinctConstructorTables :: !StgDebugDctConfig
+ }
+
+-- | Configuration describing which constructors should be given distinct info
+-- tables for each usage.
+data StgDebugDctConfig =
+ -- | Create distinct constructor tables for each usage of any data
+ -- constructor.
+ --
+ -- This is the behavior if just @-fdistinct-constructor-tables@ is supplied.
+ All
+
+ -- | Create distinct constructor tables for each usage of only these data
+ -- constructors.
+ --
+ -- This is the behavior if @-fdistinct-constructor-tables=C1,...,CN@ is
+ -- supplied.
+ | Only !(Set String)
+
+ -- | Create distinct constructor tables for each usage of any data
+ -- constructor except these ones.
+ --
+ -- This is the behavior if @-fdistinct-constructor-tables@ and
+ -- @-fno-distinct-constructor-tables=C1,...,CN@ is given.
+ | AllExcept !(Set String)
+
+ -- | Do not create distinct constructor tables for any data constructor.
+ --
+ -- This is the behavior if no @-fdistinct-constructor-tables@ is given (or
+ -- @-fno-distinct-constructor-tables@ is given).
+ | None
+
+-- | Necessary for 'StgDebugDctConfig' to be included in the dynflags
+-- fingerprint
+instance Binary StgDebugDctConfig where
+ put_ bh All = B.putByte bh 0
+ put_ bh (Only cs) = do
+ B.putByte bh 1
+ B.put_ bh cs
+ put_ bh (AllExcept cs) = do
+ B.putByte bh 2
+ B.put_ bh cs
+ put_ bh None = B.putByte bh 3
+
+ get bh = do
+ h <- B.getByte bh
+ case h of
+ 0 -> pure All
+ 1 -> Only <$> B.get bh
+ 2 -> AllExcept <$> B.get bh
+ _ -> pure None
+
+-- | Given a distinct constructor tables configuration and a set of constructor
+-- names that we want to generate distinct info tables for, create a new
+-- configuration which includes those constructors.
+--
+-- If the given set is empty, that means the user has entered
+-- @-fdistinct-constructor-tables@ with no constructor names specified, and
+-- therefore we consider that an 'All' configuration.
+dctConfigPlus :: StgDebugDctConfig -> Set String -> StgDebugDctConfig
+dctConfigPlus cfg cs
+ | Set.null cs = All
+ | otherwise =
+ case cfg of
+ All -> All
+ Only cs' -> Only $ Set.union cs' cs
+ AllExcept cs' -> AllExcept $ Set.difference cs' cs
+ None -> Only cs
+
+-- | Given a distinct constructor tables configuration and a set of constructor
+-- names that we /do not/ want to generate distinct info tables for, create a
+-- new configuration which excludes those constructors.
+--
+-- If the given set is empty, that means the user has entered
+-- @-fno-distinct-constructor-tables@ with no constructor names specified, and
+-- therefore we consider that a 'None' configuration.
+dctConfigMinus :: StgDebugDctConfig -> Set String -> StgDebugDctConfig
+dctConfigMinus cfg cs
+ | Set.null cs = None
+ | otherwise =
+ case cfg of
+ All -> AllExcept cs
+ Only cs' -> Only $ Set.difference cs' cs
+ AllExcept cs' -> AllExcept $ Set.union cs' cs
+ None -> None
+
=====================================
compiler/ghc.cabal.in
=====================================
@@ -649,6 +649,7 @@ Library
GHC.Stg.BcPrep
GHC.Stg.CSE
GHC.Stg.Debug
+ GHC.Stg.Debug.Types
GHC.Stg.FVs
GHC.Stg.Lift
GHC.Stg.Lift.Analysis
=====================================
docs/users_guide/9.10.1-notes.rst
=====================================
@@ -54,6 +54,18 @@ Compiler
- Defaulting plugins can now propose solutions to entangled sets of type variables. This allows defaulting
of multi-parameter type classes. See :ghc-ticket:`23832`.
+- The :ghc-flag:`-fdistinct-constructor-tables
+ <-fdistinct-constructor-tables=⟨cs⟩>` flag may now be provided with a list of
+ constructor names for which distinct info tables should be generated. This
+ avoids the default behavior of generating a distinct info table for *every*
+ usage of *every* constructor, which often results in more information than is
+ desired and significantly increases the size of executables.
+
+- The :ghc-flag:`-fno-distinct-constructor-tables
+ <-fno-distinct-constructor-tables=⟨cs⟩>` flag is introduced, which allows
+ users to refine the set of constructors for which distinct info tables should
+ be generated.
+
GHCi
~~~~
=====================================
docs/users_guide/debug-info.rst
=====================================
@@ -368,7 +368,8 @@ to a source location. This lookup table is generated by using the ``-finfo-table
an info table to an approximate source position of where that
info table statically originated from. If you
also want more precise information about constructor info tables then you
- should also use :ghc-flag:`-fdistinct-constructor-tables`.
+ should also use :ghc-flag:`-fdistinct-constructor-tables
+ <-fdistinct-constructor-tables=⟨cs⟩>`.
The :ghc-flag:`-finfo-table-map` flag will increase the binary size by quite
a lot, depending on how big your project is. For compiling a project the
@@ -451,7 +452,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table
from the info table map and decrease the size of executables with info table
profiling information.
-.. ghc-flag:: -fdistinct-constructor-tables
+.. ghc-flag:: -fdistinct-constructor-tables=⟨cs⟩
:shortdesc: Generate a fresh info table for each usage
of a data constructor.
:type: dynamic
@@ -465,6 +466,41 @@ to a source location. This lookup table is generated by using the ``-finfo-table
each info table will correspond to the usage of a data constructor rather
than the data constructor itself.
+ :since: 9.10
+
+ The entries in the info table map resulting from this flag may significantly
+ increase the size of executables. However, generating distinct info tables
+ for *every* usage of *every* data constructor often results in more
+ information than necessary. Instead, we would like to generate these
+ distinct tables for some specific constructors. To do this, the names of the
+ constructors we are interested in may be supplied to this flag in a
+ comma-separated list. If no constructor names are supplied (i.e. just
+ ``-fdistinct-constructor-tables`` is given) then fresh info tables will be
+ generated for every usage of every constructor.
+
+ For example, to only generate distinct info tables for the ``Just`` and
+ ``Right`` constructors, use ``-fdistinct-constructor-tables=Just,Right``.
+
+.. ghc-flag:: -fno-distinct-constructor-tables=⟨cs⟩
+ :shortdesc: Avoid generating a fresh info table for each usage of a data
+ constructor.
+ :type: dynamic
+ :category: debugging
+
+ :since: 9.10
+
+ Use this flag to refine the set of data constructors for which distinct info
+ tables are generated (as specified by
+ :ghc-flag:`-fdistinct-constructor-tables
+ <-fdistinct-constructor-tables=⟨cs⟩>`).
+ If no constructor names are given
+ (i.e. just ``-fno-distinct-constructor-tables`` is given) then no distinct
+ info tables will be generated for any usages of any data constructors.
+
+ For example, to generate distinct constructor tables for all data
+ constructors except those named ``MyConstr``, pass both
+ ``-fdistinct-constructor-tables`` and
+ ``-fno-distinct-constructor-tables=MyConstr``.
Querying the Info Table Map
---------------------------
=====================================
testsuite/tests/count-deps/CountDepsAst.stdout
=====================================
@@ -118,6 +118,7 @@ GHC.Runtime.Heap.Layout
GHC.Settings
GHC.Settings.Config
GHC.Settings.Constants
+GHC.Stg.Debug.Types
GHC.Stg.InferTags.TagSig
GHC.StgToCmm.Types
GHC.SysTools.Terminal
=====================================
testsuite/tests/count-deps/CountDepsParser.stdout
=====================================
@@ -132,6 +132,7 @@ GHC.Runtime.Heap.Layout
GHC.Settings
GHC.Settings.Config
GHC.Settings.Constants
+GHC.Stg.Debug.Types
GHC.Stg.InferTags.TagSig
GHC.StgToCmm.Types
GHC.SysTools.Terminal
=====================================
testsuite/tests/rts/ipe/distinct-tables/ACon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_3_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA1", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA2", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/AConBCon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_3_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA1", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA2", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_3_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/BCon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_Main_3_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/CCon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "cafC1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "cafC2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/Main.hs
=====================================
@@ -0,0 +1,37 @@
+module Main where
+
+import GHC.InfoProv
+import qualified X
+
+main = do
+ printIp =<< whereFrom cafA1
+ printIp =<< whereFrom cafA2
+ printIp =<< whereFrom cafB1
+ printIp =<< whereFrom cafB2
+ printIp =<< whereFrom cafC1
+ printIp =<< whereFrom cafC2
+ printIp =<< whereFrom (ACon ())
+ printIp =<< whereFrom cafXA
+ printIp =<< whereFrom X.cafXA1
+ printIp =<< whereFrom X.cafXA2
+ printIp =<< whereFrom (X.ACon ())
+ printIp =<< whereFrom (BCon cafA1)
+ printIp =<< whereFrom (CCon (cafA1, BCon (ACon ())))
+ where
+ -- Get rid of the src file path since it makes test output difficult to diff
+ -- on Windows
+ printIp = print . stripIpSrc
+ stripIpSrc (Just ip) = ip { ipSrcFile = "" }
+
+data A = ACon ()
+data B = BCon A
+data C = CCon (A, B)
+
+cafA1 = ACon ()
+cafA2 = ACon ()
+cafB1 = BCon cafA1
+cafB2 = BCon cafA2
+cafC1 = CCon (cafA1, cafB1)
+cafC2 = CCon (cafA2, cafB2)
+
+cafXA = X.ACon ()
=====================================
testsuite/tests/rts/ipe/distinct-tables/Makefile
=====================================
@@ -0,0 +1,33 @@
+TOP=../../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+# This test runs ghc with various combinations of
+# -f{no-}distinct-constructor-tables for different constructors and checks that
+# whereFrom finds (or fails to find) their provenance appropriately.
+
+distinct_tables:
+ @$$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables=ACon Main.hs ; \
+ ACon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables=BCon Main.hs ; \
+ BCon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables=CCon Main.hs ; \
+ CCon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables=ACon,BCon Main.hs ; \
+ AConBCon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables -fno-distinct-constructor-tables=ACon Main.hs ; \
+ NoACon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables -fno-distinct-constructor-tables=BCon Main.hs ; \
+ NoBCon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables -fno-distinct-constructor-tables=CCon Main.hs ; \
+ NoCCon="$$(./Main)" ; \
+ $$TEST_HC $$TEST_HC_OPTS -finfo-table-map -fdistinct-constructor-tables -fno-distinct-constructor-tables=BCon,CCon Main.hs ; \
+ NoBConCCon="$$(./Main)" ; \
+ echo "$$ACon" | diff --strip-trailing-cr ACon.out - && \
+ echo "$$BCon" | diff --strip-trailing-cr BCon.out - && \
+ echo "$$CCon" | diff --strip-trailing-cr CCon.out - && \
+ echo "$$AConBCon" | diff --strip-trailing-cr AConBCon.out - && \
+ echo "$$NoACon" | diff --strip-trailing-cr NoACon.out - && \
+ echo "$$NoBCon" | diff --strip-trailing-cr NoBCon.out - && \
+ echo "$$NoCCon" | diff --strip-trailing-cr NoCCon.out - && \
+ echo "$$NoBConCCon" | diff --strip-trailing-cr NoBConCCon.out -
=====================================
testsuite/tests/rts/ipe/distinct-tables/NoACon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "cafC1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "cafC2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "X", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_Main_3_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/NoBCon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "cafC1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "34:1-27"}
+InfoProv {ipName = "CCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "cafC2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "35:1-27"}
+InfoProv {ipName = "ACon_Main_3_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA1", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA2", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_Main_2_con_info", ipDesc = "2", ipTyDesc = "C", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "19:34-38"}
=====================================
testsuite/tests/rts/ipe/distinct-tables/NoBConCCon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_3_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA1", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA2", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/NoCCon.out
=====================================
@@ -0,0 +1,13 @@
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "30:1-15"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "cafA2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "31:1-15"}
+InfoProv {ipName = "BCon_Main_0_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB1", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "32:1-18"}
+InfoProv {ipName = "BCon_Main_1_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "cafB2", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "33:1-18"}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
+InfoProv {ipName = "ACon_Main_3_con_info", ipDesc = "2", ipTyDesc = "A", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "13:17-35"}
+InfoProv {ipName = "ACon_Main_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "37:1-17"}
+InfoProv {ipName = "ACon_X_0_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA1", ipMod = "X", ipSrcFile = "", ipSrcSpan = "6:1-16"}
+InfoProv {ipName = "ACon_X_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "cafXA2", ipMod = "X", ipSrcFile = "", ipSrcSpan = "7:1-16"}
+InfoProv {ipName = "ACon_Main_1_con_info", ipDesc = "2", ipTyDesc = "X", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "17:17-37"}
+InfoProv {ipName = "BCon_Main_3_con_info", ipDesc = "2", ipTyDesc = "B", ipLabel = "main", ipMod = "Main", ipSrcFile = "", ipSrcSpan = "18:17-38"}
+InfoProv {ipName = "CCon_con_info", ipDesc = "2", ipTyDesc = "", ipLabel = "", ipMod = "Main", ipSrcFile = "", ipSrcSpan = ""}
=====================================
testsuite/tests/rts/ipe/distinct-tables/X.hs
=====================================
@@ -0,0 +1,7 @@
+module X where
+
+-- A type with the same constructor name as 'Main.ACon'
+data X = ACon ()
+
+cafXA1 = ACon ()
+cafXA2 = ACon ()
=====================================
testsuite/tests/rts/ipe/distinct-tables/all.T
=====================================
@@ -0,0 +1,21 @@
+test(
+ 'distinct_tables',
+ [
+ extra_files([
+ # Source files
+ 'Main.hs',
+ 'X.hs',
+
+ # Expected output files
+ 'ACon.out',
+ 'BCon.out',
+ 'CCon.out',
+ 'AConBCon.out',
+ 'NoACon.out',
+ 'NoBCon.out',
+ 'NoCCon.out',
+ 'NoBConCCon.out'
+ ]),
+ ignore_stdout
+ ]
+ , makefile_test, [])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/50648a3c29079bb64477f7b8112eeec3c23cdaff
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/50648a3c29079bb64477f7b8112eeec3c23cdaff
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230912/773d1f42/attachment-0001.html>
More information about the ghc-commits
mailing list