Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information