warning police
[ghc-hetmet.git] / compiler / typecheck / TcSimplify.lhs
index 7deb852..373a174 100644 (file)
@@ -209,8 +209,8 @@ Notice that
 
 -----------------------------------------
 
-Choosing Q
-~~~~~~~~~~
+Note [Choosing which variables to quantify]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Here's a good way to choose Q:
 
        Q = grow( fv(T), C ) \ oclose( fv(G), C )
@@ -670,18 +670,35 @@ tcSimplifyInfer doc tau_tvs wanted
        ; gbl_tvs  <- tcGetGlobalTyVars
        ; let preds = fdPredsOfInsts wanted'
              qtvs  = grow preds tau_tvs' `minusVarSet` oclose preds gbl_tvs
-             (free, bound) = partition (isFreeWhenInferring qtvs) wanted'
-       ; traceTc (text "infer" <+> (ppr preds $$ ppr (grow preds tau_tvs') $$ ppr gbl_tvs $$ ppr (oclose preds gbl_tvs) $$ ppr free $$ ppr bound))
-       ; extendLIEs free
+                       -- See Note [Choosing which variables to quantify]
+
+               -- To maximise sharing, remove from consideration any 
+               -- constraints that don't mention qtvs at all
+       ; let (free1, bound) = partition (isFreeWhenInferring qtvs) wanted'
+       ; extendLIEs free1
 
                -- To make types simple, reduce as much as possible
+       ; traceTc (text "infer" <+> (ppr preds $$ ppr (grow preds tau_tvs') $$ ppr gbl_tvs $$ 
+                  ppr (oclose preds gbl_tvs) $$ ppr free1 $$ ppr bound))
        ; let try_me inst = ReduceMe AddSCs
        ; (irreds, binds) <- checkLoop (mkRedEnv doc try_me []) bound
-
        ; qtvs' <- zonkQuantifiedTyVars (varSetElems qtvs)
 
-       -- We can't abstract over implications
-       ; let (dicts, implics) = partition isDict irreds
+               -- Do not quantify over constraints that *now* do not
+               -- mention quantified type variables, because they are
+               -- simply ambiguous.  Example:
+               --      f :: Eq b => a -> (a, b)
+               --      g x = fst (f x)
+               -- From the RHS of g we get the MethodInst f77 :: alpha -> (alpha, beta)
+               -- We decide to quantify over 'alpha' alone, bur free1 does not include f77
+               -- because f77 mentions 'alpha'.  Then reducing leaves only the (ambiguous)
+               -- constraint (Eq beta), which we dump back into the free set
+               -- See test tcfail181
+       ; let (free2, irreds2) = partition (isFreeWhenInferring (mkVarSet qtvs')) irreds
+       ; extendLIEs free2
+       
+               -- We can't abstract over implications
+       ; let (dicts, implics) = partition isDict irreds2
        ; loc <- getInstLoc (ImplicOrigin doc)
        ; implic_bind <- bindIrreds loc qtvs' dicts implics
 
@@ -889,7 +906,7 @@ makeImplicationBind loc all_tvs reft
  | otherwise                   -- Otherwise we must generate a binding
  = do  { uniq <- newUnique 
        ; span <- getSrcSpanM
-       ; let name = mkInternalName uniq (mkVarOcc "ic") (srcSpanStart span)
+       ; let name = mkInternalName uniq (mkVarOcc "ic") span
              implic_inst = ImplicInst { tci_name = name, tci_reft = reft,
                                         tci_tyvars = all_tvs, 
                                         tci_given = givens,
@@ -2489,15 +2506,17 @@ addTopIPErrs :: [Name] -> [Inst] -> TcM ()
 addTopIPErrs bndrs [] 
   = return ()
 addTopIPErrs bndrs ips
-  = addErrTcM (tidy_env, mk_msg tidy_ips)
+  = do { dflags <- getDOpts
+       ; addErrTcM (tidy_env, mk_msg dflags tidy_ips) }
   where
     (tidy_env, tidy_ips) = tidyInsts ips
-    mk_msg ips = vcat [sep [ptext SLIT("Implicit parameters escape from"),
-                           nest 2 (ptext SLIT("the monomorphic top-level binding") 
+    mk_msg dflags ips 
+       = vcat [sep [ptext SLIT("Implicit parameters escape from"),
+               nest 2 (ptext SLIT("the monomorphic top-level binding") 
                                            <> plural bndrs <+> ptext SLIT("of")
                                            <+> pprBinders bndrs <> colon)],
-                      nest 2 (vcat (map ppr_ip ips)),
-                      monomorphism_fix]
+               nest 2 (vcat (map ppr_ip ips)),
+               monomorphism_fix dflags]
     ppr_ip ip = pprPred (dictPred ip) <+> pprInstArising ip
 
 topIPErrs :: [Inst] -> TcM ()
@@ -2647,30 +2666,35 @@ mkMonomorphismMsg :: TidyEnv -> [TcTyVar] -> TcM (TidyEnv, Message)
 -- Try to identify the offending variable
 -- ASSUMPTION: the Insts are fully zonked
 mkMonomorphismMsg tidy_env inst_tvs
-  = findGlobals (mkVarSet inst_tvs) tidy_env   `thenM` \ (tidy_env, docs) ->
-    returnM (tidy_env, mk_msg docs)
+  = do { dflags <- getDOpts
+       ; (tidy_env, docs) <- findGlobals (mkVarSet inst_tvs) tidy_env
+       ; return (tidy_env, mk_msg dflags docs) }
   where
-    mk_msg _ | any isRuntimeUnk inst_tvs
+    mk_msg _ _ | any isRuntimeUnk inst_tvs
         =  vcat [ptext SLIT("Cannot resolve unknown runtime types:") <+>
                    (pprWithCommas ppr inst_tvs),
                 ptext SLIT("Use :print or :force to determine these types")]
-    mk_msg []   = ptext SLIT("Probable fix: add a type signature that fixes these type variable(s)")
+    mk_msg _ []   = ptext SLIT("Probable fix: add a type signature that fixes these type variable(s)")
                        -- This happens in things like
                        --      f x = show (read "foo")
                        -- where monomorphism doesn't play any role
-    mk_msg docs = vcat [ptext SLIT("Possible cause: the monomorphism restriction applied to the following:"),
-                       nest 2 (vcat docs),
-                       monomorphism_fix
-                      ]
+    mk_msg dflags docs 
+       = vcat [ptext SLIT("Possible cause: the monomorphism restriction applied to the following:"),
+               nest 2 (vcat docs),
+               monomorphism_fix dflags]
 
 isRuntimeUnk :: TcTyVar -> Bool
 isRuntimeUnk x | SkolemTv RuntimeUnkSkol <- tcTyVarDetails x = True
                | otherwise = False
 
-monomorphism_fix :: SDoc
-monomorphism_fix = ptext SLIT("Probable fix:") <+> 
-                  (ptext SLIT("give these definition(s) an explicit type signature")
-                   $$ ptext SLIT("or use -fno-monomorphism-restriction"))
+monomorphism_fix :: DynFlags -> SDoc
+monomorphism_fix dflags
+  = ptext SLIT("Probable fix:") <+> vcat
+       [ptext SLIT("give these definition(s) an explicit type signature"),
+        if dopt Opt_MonomorphismRestriction dflags
+           then ptext SLIT("or use -fno-monomorphism-restriction")
+           else empty] -- Only suggest adding "-fno-monomorphism-restriction"
+                       -- if it is not already set!
     
 warnDefault ups default_ty
   = doptM Opt_WarnTypeDefaults  `thenM` \ warn_flag ->