(This parser doesn't make much sense of course, but I've removed everything not necessary for the error.)
I get this using ghc -O2 bad.hs:
[1 of 1] Compiling TickInRule ( bad.hs, bad.o )ghc: panic! (the 'impossible' happened) (GHC version 8.10.0.20191210: Tick in rule src<libraries/base/GHC/Base.hs:(1448,1)-(1453,15)> src<libraries/base/Data/List/NonEmpty.hs:(187,1)-(190,51)> src<libraries/base/GHC/Base.hs:(1403,1)-(1418,26)> lvl_s3lT Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/utils/Outputable.hs:1179:37 in ghc:Outputable pprPanic, called at compiler/specialise/Rules.hs:720:5 in ghc:RulesPlease report this as a GHC bug: https://www.haskell.org/ghc/reportabug
Oddly, factoring out the void part (let v = void (string s)) makes the error go away; indeed, so does factoring out just string s.
Using no optimization or even -O also results in no error.
This is as far as I've gotten.
Environment
GHC version used: ghc-8.10.0.20191210-x86_64-deb9-linux-dwarf
Edited
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Ahh, it looks like we have a source tick in the LHS of a rule. Given that we will look past source notes anyways, I think we should just strip source notes from the LHS when constructing the rule.
However, then CSE substitutes, introducing the tick:
substIdInfo Call stack: ┊ ┊ CallStack (from HasCallStack): ┊ ┊ ┊ callStackDoc, called at compiler/coreSyn/CoreSubst.hs:614:78 in ghc:CoreSubst ┊ ┊ ┊ substIdInfo, called at compiler/coreSyn/CoreSubst.hs:487:19 in ghc:CoreSubst ┊ ┊ ┊ substIdBndr, called at compiler/coreSyn/CoreSubst.hs:452:21 in ghc:CoreSubst ┊ ┊ ┊ substBndr, called at compiler/simplCore/CSE.hs:733:32 in ghc:CSE
The tick here arose because of CSE's treatment of floatable ticks: when CSE'ing it will strip off all floatable ticks, check for an equivalent subexpression in its environment (which ignores ticks), and, if one is found, replaces the old expression with the new one, wrapping it with the ticks it previously stripped.
Now the simplifier runs, looks at the lvl_s3l9 binding, and decides to unconditionally post-inline it. This introduces lvl_s3l9 ~> src<hi.hs:9:49> lvl_s3l6 into the simplifier's variable substitution.
Finally we eventually get around to simplifying $weerr_Xu, the variable to which our SpecConstr rule is attached. simplRules applies the variable substitution to the rule's template, giving us:
Which the simplifier later stumbles upon in a later pass, spots the tick in the template, and panics.
There are clearly many interactions here. However, it's not entirely clear to me which step is wrong. Substituting in the rule is clearly reasonable. However, if the call-site specialised by SpecConstr had contained a tick at the time the call was specialised then the tick would have simply been dropped (see argToPat and Note [Notes in call patterns]) when constructing the template.
I can think of two possible ways in which the problem could be avoided:
the rule matcher could just ignore ticks in templates, dropping the invariant that rule templates are devoid of ticks
substRule and simplRules could drop ticks from the template after it substitutes, preserving the invariant
match renv subst e1 (Tick t e2) | tickishFloatable t = match renv subst' e1 e2
I think we could add
match renv subst (Tick t e1) e2 | tickishFloatable t = match renv subst e1 e2
This has the same effect as your changes, but localised to the same place as ticks in the expression being matched, rather that scattered around CoreSubst.
My original thought was that the fact that a tick cannot occur in a RULE may be itself a useful invariant to enforce (e.g. if nothing else, there is no reason to write such ticks to interface file). That being said, I'll admit I'm not entirely happy with the patch that resulted from option (2).
I do not get this error anymore using the newly released GHC 8.10.1. Since it looks like the proposed patch to fix has not actually been merged, I'm guessing the underlying problem remains but for some other reason the above code snippet no longer exposes it.