[project @ 1999-06-17 09:51:16 by simonmar]
[ghc-hetmet.git] / ghc / compiler / deSugar / Match.lhs
index 9ac0d39..6c242a9 100644 (file)
@@ -26,7 +26,7 @@ import Id             ( idType, recordSelectorFieldLabel, Id )
 import DataCon         ( dataConFieldLabels, dataConArgTys )
 import MatchCon                ( matchConFamily )
 import MatchLit                ( matchLiterals )
-import PrelVals                ( pAT_ERROR_ID )
+import PrelInfo                ( pAT_ERROR_ID )
 import Type            ( isUnLiftedType, splitAlgTyConApp,
                          Type
                        )
@@ -78,8 +78,8 @@ matchExport vars qs@((EqnInfo _ ctx _ (MatchResult _ _)) : _)
        eqns_shadow   = map (\n -> qs!!(n - 1)) unused_eqns
 \end{code}
 
-This variable shows the maximun number of lines of output generated for warnings.
-It will limit the number of patterns/equations displayed to maximum_output.
+This variable shows the maximum number of lines of output generated for warnings.
+It will limit the number of patterns/equations displayed to@ maximum_output@.
 
 (ToDo: add command-line option?)
 
@@ -87,7 +87,7 @@ It will limit the number of patterns/equations displayed to maximum_output.
 maximum_output = 4
 \end{code}
 
-The next two functions creates the warning message.
+The next two functions create the warning message.
 
 \begin{code}
 dsShadowWarn :: DsMatchContext -> [EquationInfo] -> DsM ()
@@ -95,59 +95,76 @@ dsShadowWarn ctx@(DsMatchContext kind _ _) qs = dsWarn warn
        where
          warn | length qs > maximum_output
                = pp_context ctx (ptext SLIT("are overlapped"))
-                     8    (vcat (map (ppr_eqn kind) (take maximum_output qs)) $$
+                           (\ f -> vcat (map (ppr_eqn f kind) (take maximum_output qs)) $$
                            ptext SLIT("..."))
               | otherwise
                = pp_context ctx (ptext SLIT("are overlapped"))
-                    8     (vcat $ map (ppr_eqn kind) qs)
+                           (\ f -> vcat $ map (ppr_eqn f kind) qs)
 
 
 dsIncompleteWarn :: DsMatchContext -> [ExhaustivePat] -> DsM ()
 dsIncompleteWarn ctx@(DsMatchContext kind _ _) pats = dsWarn warn 
        where
-         warn | length pats > maximum_output
-               = pp_context ctx (ptext SLIT("are non-exhaustive"))
-                    8 (hang (ptext SLIT("Patterns not recognized:"))
-                        4 ((vcat $ map (ppr_incomplete_pats kind) (take maximum_output pats))
-                          $$ ptext SLIT("...")))
-              | otherwise
-               = pp_context ctx (ptext SLIT("are non-exhaustive"))
-                    8 (hang (ptext SLIT("Patterns not recognized:"))
-                       4 (vcat $ map (ppr_incomplete_pats kind) pats))
-
-pp_context NoMatchContext msg ind rest_of_msg = dontAddErrLoc "" (ptext SLIT("Some match(es)") <+> hang msg ind rest_of_msg)
-
-pp_context (DsMatchContext kind pats loc) msg ind rest_of_msg
-  = addErrLocHdrLine loc message (hang (pp_match kind pats) ind rest_of_msg)
+         warn = pp_context ctx (ptext SLIT("are non-exhaustive"))
+                           (\f -> hang (ptext SLIT("Patterns not matched:"))
+                                  4 ((vcat $ map (ppr_incomplete_pats kind)
+                                                 (take maximum_output pats))
+                                     $$ dots))
+
+         dots | length pats > maximum_output = ptext SLIT("...")
+              | otherwise                    = empty
+
+pp_context NoMatchContext msg rest_of_msg_fun
+  = dontAddErrLoc "" (ptext SLIT("Some match(es)") <+> hang msg 8 (rest_of_msg_fun id))
+
+pp_context (DsMatchContext kind pats loc) msg rest_of_msg_fun
+  = case pp_match kind pats of
+      (ppr_match, pref) ->
+          addErrLocHdrLine loc message (nest 8 (rest_of_msg_fun pref))
+       where
+         message = ptext SLIT("Pattern match(es)") <+> msg <+> ppr_match <> char ':'
  where
-    message = ptext SLIT("Pattern match(es)") <+> msg     
-
     pp_match (FunMatch fun) pats
-      = hsep [ptext SLIT("in the definition of function"), quotes (ppr fun)]
+      = let ppr_fun = ppr fun in
+        ( hsep [ptext SLIT("in the definition of function"), quotes ppr_fun]
+       , (\ x -> ppr_fun <+> x)
+       )
 
     pp_match CaseMatch pats
-      = hang (ptext SLIT("in a group of case alternatives beginning:"))
-       4 (ppr_pats pats)
+      = (hang (ptext SLIT("in a group of case alternatives beginning"))
+          4 (ppr_pats pats)
+       , id
+       )
 
     pp_match PatBindMatch pats
-      = hang (ptext SLIT("in a pattern binding:"))
-       4 (ppr_pats pats)
+      = ( hang (ptext SLIT("in a pattern binding"))
+           4 (ppr_pats pats)
+       , id
+       )
 
     pp_match LambdaMatch pats
-      = hang (ptext SLIT("in a lambda abstraction:"))
-       4 (ppr_pats pats)
+      = ( hang (ptext SLIT("in a lambda abstraction"))
+           4 (ppr_pats pats)
+       , id
+       )
 
     pp_match DoBindMatch pats
-      = hang (ptext SLIT("in a `do' pattern binding:"))
-       4 (ppr_pats pats)
+      = ( hang (ptext SLIT("in a `do' pattern binding"))
+            4 (ppr_pats pats)
+       , id
+       )
 
     pp_match ListCompMatch pats
-      = hang (ptext SLIT("in a `list comprension' pattern binding:"))
-       4 (ppr_pats pats)
+      = ( hang (ptext SLIT("in a `list comprension' pattern binding"))
+            4 (ppr_pats pats)
+       , id
+       ) 
 
     pp_match LetMatch pats
-      = hang (ptext SLIT("in a `let' pattern binding:"))
-       4 (ppr_pats pats)
+      = ( hang (ptext SLIT("in a `let' pattern binding"))
+            4 (ppr_pats pats)
+       , id
+       )
 
 ppr_pats pats = sep (map ppr pats)
 
@@ -159,7 +176,8 @@ separator (DoBindMatch)   = SLIT("<-")
 separator (ListCompMatch) = SLIT("<-")  
 separator (LetMatch)      = SLIT("=")
                  
-ppr_shadow_pats kind pats = sep [ppr_pats pats, ptext (separator kind), ptext SLIT("...")]
+ppr_shadow_pats kind pats
+  = sep [ppr_pats pats, ptext (separator kind), ptext SLIT("...")]
     
 ppr_incomplete_pats kind (pats,[]) = ppr_pats pats
 ppr_incomplete_pats kind (pats,constraints) = 
@@ -169,7 +187,7 @@ ppr_incomplete_pats kind (pats,constraints) =
 
 ppr_constraint (var,pats) = sep [ppr var, ptext SLIT("`not_elem`"), ppr pats]
 
-ppr_eqn kind (EqnInfo _ _ pats _) = ppr_shadow_pats kind pats
+ppr_eqn prefixF kind (EqnInfo _ _ pats _) = prefixF (ppr_shadow_pats kind pats)
 \end{code}
 
 
@@ -440,6 +458,13 @@ tidy1 v (LazyPat pat) match_result
 -- re-express <con-something> as (ConPat ...) [directly]
 
 tidy1 v (RecPat data_con pat_ty tvs dicts rpats) match_result
+  | null rpats
+  =    -- Special case for C {}, which can be used for 
+       -- a constructor that isn't declared to have
+       -- fields at all
+    returnDs (ConPat data_con pat_ty tvs dicts (map WildPat con_arg_tys'), match_result)
+
+  | otherwise
   = returnDs (ConPat data_con pat_ty tvs dicts pats, match_result)
   where
     pats            = map mk_pat tagged_arg_tys
@@ -557,7 +582,8 @@ tidy1 v non_interesting_pat match_result
   = returnDs (non_interesting_pat, match_result)
 \end{code}
 
-PREVIOUS matchTwiddled STUFF:
+\noindent
+{\bf Previous @matchTwiddled@ stuff:}
 
 Now we get to the only interesting part; note: there are choices for
 translation [from Simon's notes]; translation~1:
@@ -716,23 +742,29 @@ matchWrapper :: DsMatchKind                       -- For shadowing warning messages
 
  There is one small problem with the Lambda Patterns, when somebody
  writes something similar to:
+\begin{verbatim}
     (\ (x:xs) -> ...)
+\end{verbatim}
  he/she don't want a warning about incomplete patterns, that is done with 
- the flag opt_WarnSimplePatterns.
- This problem also appears in the :
-   do patterns, but if the do can fail it creates another equation if the match can 
-                fail (see DsExpr.doDo function)
-   let patterns, are treated by matchSimply
-   List Comprension Patterns, are treated by matchSimply also
-
-We can't call matchSimply with Lambda patterns, due to lambda patterns can have more than
+ the flag @opt_WarnSimplePatterns@.
+ This problem also appears in the:
+\begin{itemize}
+\item @do@ patterns, but if the @do@ can fail
+      it creates another equation if the match can fail
+      (see @DsExpr.doDo@ function)
+\item @let@ patterns, are treated by @matchSimply@
+   List Comprension Patterns, are treated by @matchSimply@ also
+\end{itemize}
+
+We can't call @matchSimply@ with Lambda patterns,
+due to the fact that lambda patterns can have more than
 one pattern, and match simply only accepts one pattern.
 
 JJQC 30-Nov-1997
+
 \begin{code}
 matchWrapper kind matches error_string
-  = flattenMatches kind matches                                `thenDs` \ (result_ty, eqns_info) ->
+  = flattenMatches kind matches                        `thenDs` \ (result_ty, eqns_info) ->
     let
        EqnInfo _ _ arg_pats _ : _ = eqns_info
     in