never executed always true always false
    1 
    2 {-# LANGUAGE TypeFamilies #-}
    3 
    4 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
    5 
    6 {-
    7 (c) The University of Glasgow 2006
    8 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
    9 
   10 
   11 Pattern-matching constructors
   12 -}
   13 
   14 module GHC.HsToCore.Match.Constructor ( matchConFamily, matchPatSyn ) where
   15 
   16 import GHC.Prelude
   17 
   18 import {-# SOURCE #-} GHC.HsToCore.Match ( match )
   19 
   20 import GHC.Hs
   21 import GHC.HsToCore.Binds
   22 import GHC.Core.ConLike
   23 import GHC.Types.Basic ( Origin(..) )
   24 import GHC.Tc.Utils.TcType
   25 import GHC.Core.Multiplicity
   26 import GHC.HsToCore.Monad
   27 import GHC.HsToCore.Utils
   28 import GHC.Core ( CoreExpr )
   29 import GHC.Core.Make ( mkCoreLets )
   30 import GHC.Utils.Misc
   31 import GHC.Types.Id
   32 import GHC.Types.Name.Env
   33 import GHC.Types.FieldLabel ( flSelector )
   34 import GHC.Types.SrcLoc
   35 import GHC.Utils.Outputable
   36 import GHC.Utils.Panic
   37 import GHC.Utils.Panic.Plain
   38 import Control.Monad(liftM)
   39 import Data.List (groupBy)
   40 import Data.List.NonEmpty (NonEmpty(..))
   41 
   42 {-
   43 We are confronted with the first column of patterns in a set of
   44 equations, all beginning with constructors from one ``family'' (e.g.,
   45 @[]@ and @:@ make up the @List@ ``family'').  We want to generate the
   46 alternatives for a @Case@ expression.  There are several choices:
   47 \begin{enumerate}
   48 \item
   49 Generate an alternative for every constructor in the family, whether
   50 they are used in this set of equations or not; this is what the Wadler
   51 chapter does.
   52 \begin{description}
   53 \item[Advantages:]
   54 (a)~Simple.  (b)~It may also be that large sparsely-used constructor
   55 families are mainly handled by the code for literals.
   56 \item[Disadvantages:]
   57 (a)~Not practical for large sparsely-used constructor families, e.g.,
   58 the ASCII character set.  (b)~Have to look up a list of what
   59 constructors make up the whole family.
   60 \end{description}
   61 
   62 \item
   63 Generate an alternative for each constructor used, then add a default
   64 alternative in case some constructors in the family weren't used.
   65 \begin{description}
   66 \item[Advantages:]
   67 (a)~Alternatives aren't generated for unused constructors.  (b)~The
   68 STG is quite happy with defaults.  (c)~No lookup in an environment needed.
   69 \item[Disadvantages:]
   70 (a)~A spurious default alternative may be generated.
   71 \end{description}
   72 
   73 \item
   74 ``Do it right:'' generate an alternative for each constructor used,
   75 and add a default alternative if all constructors in the family
   76 weren't used.
   77 \begin{description}
   78 \item[Advantages:]
   79 (a)~You will get cases with only one alternative (and no default),
   80 which should be amenable to optimisation.  Tuples are a common example.
   81 \item[Disadvantages:]
   82 (b)~Have to look up constructor families in TDE (as above).
   83 \end{description}
   84 \end{enumerate}
   85 
   86 We are implementing the ``do-it-right'' option for now.  The arguments
   87 to @matchConFamily@ are the same as to @match@; the extra @Int@
   88 returned is the number of constructors in the family.
   89 
   90 The function @matchConFamily@ is concerned with this
   91 have-we-used-all-the-constructors? question; the local function
   92 @match_cons_used@ does all the real work.
   93 -}
   94 
   95 matchConFamily :: NonEmpty Id
   96                -> Type
   97                -> NonEmpty (NonEmpty EquationInfo)
   98                -> DsM (MatchResult CoreExpr)
   99 -- Each group of eqns is for a single constructor
  100 matchConFamily (var :| vars) ty groups
  101   = do let mult = idMult var
  102            -- Each variable in the argument list correspond to one column in the
  103            -- pattern matching equations. Its multiplicity is the context
  104            -- multiplicity of the pattern. We extract that multiplicity, so that
  105            -- 'matchOneconLike' knows the context multiplicity, in case it needs
  106            -- to come up with new variables.
  107        alts <- mapM (fmap toRealAlt . matchOneConLike vars ty mult) groups
  108        return (mkCoAlgCaseMatchResult var ty alts)
  109   where
  110     toRealAlt alt = case alt_pat alt of
  111         RealDataCon dcon -> alt{ alt_pat = dcon }
  112         _ -> panic "matchConFamily: not RealDataCon"
  113 
  114 matchPatSyn :: NonEmpty Id
  115             -> Type
  116             -> NonEmpty EquationInfo
  117             -> DsM (MatchResult CoreExpr)
  118 matchPatSyn (var :| vars) ty eqns
  119   = do let mult = idMult var
  120        alt <- fmap toSynAlt $ matchOneConLike vars ty mult eqns
  121        return (mkCoSynCaseMatchResult var ty alt)
  122   where
  123     toSynAlt alt = case alt_pat alt of
  124         PatSynCon psyn -> alt{ alt_pat = psyn }
  125         _ -> panic "matchPatSyn: not PatSynCon"
  126 
  127 type ConArgPats = HsConPatDetails GhcTc
  128 
  129 matchOneConLike :: [Id]
  130                 -> Type
  131                 -> Mult
  132                 -> NonEmpty EquationInfo
  133                 -> DsM (CaseAlt ConLike)
  134 matchOneConLike vars ty mult (eqn1 :| eqns)   -- All eqns for a single constructor
  135   = do  { let inst_tys = assert (all tcIsTcTyVar ex_tvs) $
  136                            -- ex_tvs can only be tyvars as data types in source
  137                            -- Haskell cannot mention covar yet (Aug 2018).
  138                          assert (tvs1 `equalLength` ex_tvs) $
  139                          arg_tys ++ mkTyVarTys tvs1
  140 
  141               val_arg_tys = conLikeInstOrigArgTys con1 inst_tys
  142         -- dataConInstOrigArgTys takes the univ and existential tyvars
  143         -- and returns the types of the *value* args, which is what we want
  144 
  145               match_group :: [Id]
  146                           -> [(ConArgPats, EquationInfo)] -> DsM (MatchResult CoreExpr)
  147               -- All members of the group have compatible ConArgPats
  148               match_group arg_vars arg_eqn_prs
  149                 = assert (notNull arg_eqn_prs) $
  150                   do { (wraps, eqns') <- liftM unzip (mapM shift arg_eqn_prs)
  151                      ; let group_arg_vars = select_arg_vars arg_vars arg_eqn_prs
  152                      ; match_result <- match (group_arg_vars ++ vars) ty eqns'
  153                      ; return $ foldr1 (.) wraps <$> match_result
  154                      }
  155 
  156               shift (_, eqn@(EqnInfo
  157                              { eqn_pats = ConPat
  158                                { pat_args = args
  159                                , pat_con_ext = ConPatTc
  160                                  { cpt_tvs = tvs
  161                                  , cpt_dicts = ds
  162                                  , cpt_binds = bind
  163                                  }
  164                                } : pats
  165                              }))
  166                 = do ds_bind <- dsTcEvBinds bind
  167                      return ( wrapBinds (tvs `zip` tvs1)
  168                             . wrapBinds (ds  `zip` dicts1)
  169                             . mkCoreLets ds_bind
  170                             , eqn { eqn_orig = Generated
  171                                   , eqn_pats = conArgPats val_arg_tys args ++ pats }
  172                             )
  173               shift (_, (EqnInfo { eqn_pats = ps })) = pprPanic "matchOneCon/shift" (ppr ps)
  174         ; let scaled_arg_tys = map (scaleScaled mult) val_arg_tys
  175             -- The 'val_arg_tys' are taken from the data type definition, they
  176             -- do not take into account the context multiplicity, therefore we
  177             -- need to scale them back to get the correct context multiplicity
  178             -- to desugar the sub-pattern in each field. We need to know these
  179             -- multiplicity because of the invariant that, in Core, binders in a
  180             -- constructor pattern must be scaled by the multiplicity of the
  181             -- case. See Note [Case expression invariants].
  182         ; arg_vars <- selectConMatchVars scaled_arg_tys args1
  183                 -- Use the first equation as a source of
  184                 -- suggestions for the new variables
  185 
  186         -- Divide into sub-groups; see Note [Record patterns]
  187         ; let groups :: [[(ConArgPats, EquationInfo)]]
  188               groups = groupBy compatible_pats [ (pat_args (firstPat eqn), eqn)
  189                                                | eqn <- eqn1:eqns ]
  190 
  191         ; match_results <- mapM (match_group arg_vars) groups
  192 
  193         ; return $ MkCaseAlt{ alt_pat = con1,
  194                               alt_bndrs = tvs1 ++ dicts1 ++ arg_vars,
  195                               alt_wrapper = wrapper1,
  196                               alt_result = foldr1 combineMatchResults match_results } }
  197   where
  198     ConPat { pat_con = L _ con1
  199            , pat_args = args1
  200            , pat_con_ext = ConPatTc
  201              { cpt_arg_tys = arg_tys
  202              , cpt_wrap = wrapper1
  203              , cpt_tvs = tvs1
  204              , cpt_dicts = dicts1
  205              }
  206            } = firstPat eqn1
  207     fields1 = map flSelector (conLikeFieldLabels con1)
  208 
  209     ex_tvs = conLikeExTyCoVars con1
  210 
  211     -- Choose the right arg_vars in the right order for this group
  212     -- Note [Record patterns]
  213     select_arg_vars :: [Id] -> [(ConArgPats, EquationInfo)] -> [Id]
  214     select_arg_vars arg_vars ((arg_pats, _) : _)
  215       | RecCon flds <- arg_pats
  216       , let rpats = rec_flds flds
  217       , not (null rpats)     -- Treated specially; cf conArgPats
  218       = assertPpr (fields1 `equalLength` arg_vars)
  219                   (ppr con1 $$ ppr fields1 $$ ppr arg_vars) $
  220         map lookup_fld rpats
  221       | otherwise
  222       = arg_vars
  223       where
  224         fld_var_env = mkNameEnv $ zipEqual "get_arg_vars" fields1 arg_vars
  225         lookup_fld (L _ rpat) = lookupNameEnv_NF fld_var_env
  226                                             (idName (hsRecFieldId rpat))
  227     select_arg_vars _ [] = panic "matchOneCon/select_arg_vars []"
  228 
  229 -----------------
  230 compatible_pats :: (ConArgPats,a) -> (ConArgPats,a) -> Bool
  231 -- Two constructors have compatible argument patterns if the number
  232 -- and order of sub-matches is the same in both cases
  233 compatible_pats (RecCon flds1, _) (RecCon flds2, _) = same_fields flds1 flds2
  234 compatible_pats (RecCon flds1, _) _                 = null (rec_flds flds1)
  235 compatible_pats _                 (RecCon flds2, _) = null (rec_flds flds2)
  236 compatible_pats _                 _                 = True -- Prefix or infix con
  237 
  238 same_fields :: HsRecFields GhcTc (LPat GhcTc) -> HsRecFields GhcTc (LPat GhcTc)
  239             -> Bool
  240 same_fields flds1 flds2
  241   = all2 (\(L _ f1) (L _ f2)
  242                           -> hsRecFieldId f1 == hsRecFieldId f2)
  243          (rec_flds flds1) (rec_flds flds2)
  244 
  245 
  246 -----------------
  247 selectConMatchVars :: [Scaled Type] -> ConArgPats -> DsM [Id]
  248 selectConMatchVars arg_tys con
  249   = case con of
  250       RecCon {}      -> newSysLocalsDs arg_tys
  251       PrefixCon _ ps -> selectMatchVars (zipMults arg_tys ps)
  252       InfixCon p1 p2 -> selectMatchVars (zipMults arg_tys [p1, p2])
  253   where
  254     zipMults = zipWithEqual "selectConMatchVar" (\a b -> (scaledMult a, unLoc b))
  255 
  256 conArgPats :: [Scaled Type]-- Instantiated argument types
  257                           -- Used only to fill in the types of WildPats, which
  258                           -- are probably never looked at anyway
  259            -> ConArgPats
  260            -> [Pat GhcTc]
  261 conArgPats _arg_tys (PrefixCon _ ps) = map unLoc ps
  262 conArgPats _arg_tys (InfixCon p1 p2) = [unLoc p1, unLoc p2]
  263 conArgPats  arg_tys (RecCon (HsRecFields { rec_flds = rpats }))
  264   | null rpats = map WildPat (map scaledThing arg_tys)
  265         -- Important special case for C {}, which can be used for a
  266         -- datacon that isn't declared to have fields at all
  267   | otherwise  = map (unLoc . hfbRHS . unLoc) rpats
  268 
  269 {-
  270 Note [Record patterns]
  271 ~~~~~~~~~~~~~~~~~~~~~~
  272 Consider
  273          data T = T { x,y,z :: Bool }
  274 
  275          f (T { y=True, x=False }) = ...
  276 
  277 We must match the patterns IN THE ORDER GIVEN, thus for the first
  278 one we match y=True before x=False.  See #246; or imagine
  279 matching against (T { y=False, x=undefined }): should fail without
  280 touching the undefined.
  281 
  282 Now consider:
  283 
  284          f (T { y=True, x=False }) = ...
  285          f (T { x=True, y= False}) = ...
  286 
  287 In the first we must test y first; in the second we must test x
  288 first.  So we must divide even the equations for a single constructor
  289 T into sub-groups, based on whether they match the same field in the
  290 same order.  That's what the (groupBy compatible_pats) grouping.
  291 
  292 All non-record patterns are "compatible" in this sense, because the
  293 positional patterns (T a b) and (a `T` b) all match the arguments
  294 in order.  Also T {} is special because it's equivalent to (T _ _).
  295 Hence the (null rpats) checks here and there.
  296 
  297 -}