Arrows desguaring does not take account of bindings in patterns
The test arrows/should_compile/arrowcase1 is failing Lint. The bug is in the desugarer.
Here’s a smaller test case:
h :: ArrowChoice a => Int -> a (Int,Int) Int
h x = proc (y,z) -> case compare x y of
GT -> returnA -< z+x
The type checker turns the case into
case compare x y of
GT { p77 = plusInt } -> returnA -< p77 z x
Here p77 is a local binding for the (+) operation. In general, patterns can contain bindings (used to discharge constraints that are bound by the pattern). In this case the binding isn’t strictly necessary, but in general it is – consider existentials. It’s equivalent to adding a ‘let’ around the RHS, but since the patters are perhaps nested, and one pattern might use a constraint that is bound by another, the pattern is the right place to attach the binding.
This has come up because GHC is binding things a little earlier than before, but an existential would have exposed it before.
The trouble is that the suspicious-looking replaceLeaves code in DsArrows (line 528 or so) doesn’t know about these bindings.
I don’t understand DsArrows at all. Indeed the whole Arrows code feels smelly to me. Maybe we tried to share too much code?
I'm hoping Ross will look at this.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 6.6 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |