Replace ASSERT with WARN, and explain why
authorsimonpj@microsoft.com <unknown>
Thu, 18 Sep 2008 15:52:45 +0000 (15:52 +0000)
committersimonpj@microsoft.com <unknown>
Thu, 18 Sep 2008 15:52:45 +0000 (15:52 +0000)
The DPH library tripped an ASSERT.  The code is actually OK, but it's
badly-optimised so I changed it to WARN.  The issue here is explained
in ClosureInfo, Note [Unsafe coerce complications].

compiler/codeGen/ClosureInfo.lhs

index 25cde6f..07a833f 100644 (file)
@@ -623,11 +623,15 @@ getCallMethod name (LFThunk _ _ updatable std_form_info is_fun) n_args
     JumpToIt (thunkEntryLabel name std_form_info updatable)
 
 getCallMethod name (LFUnknown True) n_args
-  = SlowCall -- might be a function
+  = SlowCall -- Might be a function
 
 getCallMethod name (LFUnknown False) n_args
-  = ASSERT2 ( n_args == 0, ppr name <+> ppr n_args ) 
-    EnterIt -- Not a function
+  | n_args > 0 
+  = WARN( True, ppr name <+> ppr n_args ) 
+    SlowCall   -- Note [Unsafe coerce complications]
+
+  | otherwise
+  = EnterIt -- Not a function
 
 getCallMethod name (LFBlackHole _) n_args
   = SlowCall   -- Presumably the black hole has by now
@@ -677,6 +681,29 @@ isKnownFun (LFLetNoEscape _) = True
 isKnownFun _ = False
 \end{code}
 
+Note [Unsafe coerce complications]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In some (badly-optimised) DPH code we see this
+   Module X:    rr :: Int = error Int "Urk"
+   Module Y:    ...((X.rr |> g) True) ...
+     where g is an (unsafe) coercion of kind (Int ~ Bool->Bool), say
+
+It's badly optimised, because knowing that 'X.rr' is bottom, we should
+have dumped the application to True.  But it should still work. These
+strange unsafe coercions arise from the case-of-error transformation:
+       (case (error Int "foo") of { ... }) True
+--->   (error Int "foo" |> g) True
+
+Anyway, the net effect is that in STG-land, when casts are discarded,
+we *can* see a value of type Int applied to an argument.  This only happens
+if (a) the programmer made a mistake, or (b) the value of type Int is
+actually bottom.
+
+So it's wrong to trigger an ASSERT failure in this circumstance.  Instead
+we now emit a WARN -- mainly to draw attention to a probably-badly-optimised
+program fragment -- and do the conservative thing which is SlowCall.
+
+
 -----------------------------------------------------------------------------
 SRT-related stuff