
#14293: View patterns with locally defined functions in restructuring don't compile -------------------------------------+------------------------------------- Reporter: heisenbug | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): Here's an even more tricky case: {{{ (foo -> (a,b), foo) = ([True,False], \(a:b:_) -> (a,b)) }}} The lazy pattern binding matches a pair, binding `foo`, which is used as the viewing function in another part of the same pattern. I think the Right Thing here is to rename the ''binders'' of the pattern first, and then later rename the ''occurrences'' of bound variables. The latter occur in view patterns. At the moment a `HsBindLR` has two pass parameters, and goes through these stages: * `HsBindLR Parsed Parsed`: after the parser * `HsBindLR` Renamed Parsed`: binders renamed, but RHSs not renamed yet * `HsBindLR` Renamed Renamed`: fully renamed But patterns have only one pass parameter! So perhaps we can give them two, like `HsBindLR`. Then `rnPat` would be split into two, * `rnPatLHS` that deals with the binders, and * `rnPatRHS` that deals with the expressions in view patterns. The latter would be much simpler than the current `rnPat`: just find the view patterns and renamed the view function. The former is pretty much what we have now in `rnPat`. In the case of lambda/case patterns we don't want to split in this way. We positively want a left-to-right bias. For example {{{ f (foo -> (a,b), foo) = ... }}} is ill-scoped. So maybe `rnPatLHS` has type (roughly) {{{ rnPatLHS :: Pat GhcPs GhcPs -> (LHsExpr GhcPs -> RnM (LHsExpr p)) -> (LPat GhcRn p -> RnM (a, FreeVars)) -> RnM (a, FreeVars) }}} Here the second argument is used to rename the view functions; either it's a no-op (used in bindings) or it's `rnLHsExpr` (use in case/lambda). I have not worked through the details but it seems plausible. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14293#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler