stylish-haskell icon indicating copy to clipboard operation
stylish-haskell copied to clipboard

BangPatterns causing identifiers being split into multiple identifiers

Open axman6 opened this issue 4 years ago • 1 comments

We have run into an issue with v0.10.0.0 where the code

    go (DoneH hdr rest) = case indexedToParser <$> toIndexed hdr (parseOrderedRecord @a) of
      Left errMsg -> FailH rest errMsg
      Right !cParser -> DoneH hdr (decodeWithP cParser opts rest)

is converted into

    go (DoneH hdr rest) = case indexedToParser <$> toIndexed hdr (parseOrderedRecord @a) of
      Left errMsg -> FailH rest errMsg
      Right !c    Parser -> DoneH hdr (decodeWithP cParser opts rest)

breaking the identifier !cParser into !c Parser.

The file is being run with the following settings

steps:
  - simple_align:
      cases: true
      top_level_patterns: true
      records: true

  - imports:
      align: global
      list_align: after_alias
      pad_module_names: false
      long_list_align: new_line
      empty_list_align: inherit
      list_padding: 18
      separate_lists: false
      space_surround: false

  - language_pragmas:
      style: vertical
      align: false
      remove_redundant: true

  - trailing_whitespace: {}

columns: 100
newline: native
language_extensions:
  - DerivingStrategies
  - DerivingVia
  - FlexibleContexts
  - GeneralizedNewtypeDeriving
  - LambdaCase
  - MultiParamTypeClasses
  - QuasiQuotes
  - RecordWildCards
  - ScopedTypeVariables
  - TemplateHaskell
  - TupleSections
  - BangPatterns

The same thing happens whether BangPatterns is in the list of language_extensions or not.

axman6 avatar Feb 04 '20 02:02 axman6

Sorry to hijack this thread if it's not the same bug, but not only strict fields / bangpatterns, it seems:

instance Replaceable NumTerm where
  replace :: (Monad m) => NumTerm -> ReaderT (RenamerAPI m) m NumTerm
  replace (MkMul   ts)    = MkMul <$> mapM replace ts
  replace (MkMinus t1 t2) = MkMinus <$> replace t1 <*> replace t2
  replace (MkDiv   t1 t2) = MkDiv <$> replace t1 <*> replace t2

is rewritten to

instance Replaceable NumTerm where
  replace :: (Monad m) => NumTerm -> ReaderT (RenamerAPI m) m NumTerm
  replace (MkMul   ts)    = MkMul <$> mapM replace ts
  replace (MkMinus t1 t   2) = MkMinus <$> replace t1 <*> replace t2
  replace (MkDiv   t1 t2) = MkDiv <$> replace t1 <*> replace t2

Note the spurious space in the MkMinus case.

Reordering cases 'moves' the bug: If you switch MkMul and MkMinus in the order, then the bug occurs with MkDiv. If you put MkMul all the way to the bottom, it works fine and the bug disappears.

Matthiasvanderhallen avatar Mar 09 '20 14:03 Matthiasvanderhallen