Need help with debugging "Impossible case alternative"

Simon Peyton-Jones simonpj at microsoft.com
Fri May 10 15:06:23 CEST 2013


It's hard to help without being able to reproduce it.

| If I understand correctly this means that the case tries to scrutinize
| integer 1 against True and
| False, which obviously fails (surprisingly, compiling with -dcore-lint
| and -dcmm-lint doesn't
| detect any problems). 

That sounds right.  So what is happening right now is that

	case 1 of { True -> e1; False -> e2 }

is getting converted to

	error "Missing alternative"

which isn't much help.  Better perhaps to leave it as
		case 1 of { True -> e1; False -> e2 }

and then the next run of CoreLint will complain, and you can see where. You can do that by replacing the call to missingALt with a call to
	reallyRebuildCase env scrut case_bndr alts cont
as in the last equation for rebuildCase

Then you should get Core Lint errors in the offending library. (Make sure -dcore-lint is on all the time)

S

| -----Original Message-----
| From: ghc-devs-bounces at haskell.org [mailto:ghc-devs-bounces at haskell.org]
| On Behalf Of Jan Stolarek
| Sent: 10 May 2013 11:52
| To: ghc-devs at haskell.org
| Subject: Need help with debugging "Impossible case alternative"
| 
| I'm working on modifying comparison primops so that they return Int#
| instead of Bool. I've been
| stuck with one bug for about two weeks now and I just reached a point
| where I don't have any more
| ideas what to do. I would appreciate any hints or ideas.
| 
| So far I changed the primops to return Int# and created a module
| GHC.PrimWrappers that contains
| wrappers around the new primops:
| 
| (>#) :: Int# -> Int# -> Bool
| (>#) a b = tagToEnum# (a >$# b)  -- (>$#) :: Int# -> Int# -> Int#
| 
| I also made changes to base, integer-gmp, primitive and ghc-prim
| libraries
| 
| The problem is that many compiled programs produce "Impossible case
| alternative" message when they
| are run. This is generated by missingAlt function, which is called by
| rebuildCase function on
| line 1785 in simplCore/Simplify.lhs. I modified the message displayed by
| missingAlt to get
| information about the scrutinee, binder and case alternatives:
| 
| missingAlt env scrut@(LitAlt _) case_bndr alts cont
|   = WARN( True, ptext (sLit "missing LitAlt: ") <+> ppr case_bndr )
|     return (env, mkImpossibleExpr_REMOVE_ME (contResultType cont)
| (showSDoc unsafeGlobalDynFlags $
| ptext (sLit "missing LitAlt : ") <+> ppr scrut <+> ppr case_bndr <+> ppr
| alts))
| 
| Here's an example error message:
| 
| Impossible case alternative: missing LitAlt :  1 wild [(GHC.Types.False,
| [], GHC.Types.False),
|                           (GHC.Types.True, [], x)]
| 
| If I understand correctly this means that the case tries to scrutinize
| integer 1 against True and
| False, which obviously fails (surprisingly, compiling with -dcore-lint
| and -dcmm-lint doesn't
| detect any problems). My theory is that this integer is supposed to be a
| tag of a Bool data type
| (in the example message this would be True) and the call to tagToEnum#
| somehow got eliminated or
| floated out of the case scrutinee. Is that a reasonable theory? Is there
| a transform that could
| perform such floating of tagToEnum# and if so how to prevent it?
| 
| I am unable to create a minimal code example that would cause this
| problem. I noticed that the
| problem happens on every attempt to print a floating point number (this
| causes tens of tests in
| the testsuite to fail). I extracted all the code responsible for
| converting Double to String from
| the GHC.Float and GHC.Show modules so that I have a self-contained
| program (except the call to
| print). Surprisingly that extracted code does not produce the error
| message. I'm clueless and
| will really appreciate any ideas.
| 
| Janek
| 
| _______________________________________________
| ghc-devs mailing list
| ghc-devs at haskell.org
| http://www.haskell.org/mailman/listinfo/ghc-devs



More information about the ghc-devs mailing list