haskell / stylish-haskell

Haskell code prettifier
Other
990 stars 151 forks source link

Formatting a file with stylish-haskell results in future parsing errors by stylish-haskell #354

Open chshersh opened 3 years ago

chshersh commented 3 years ago

Using the latest version of stylish-haskell to format a particular file inplace changes the content of the file, and when running stylish-haskell again on this file, it doesn't parse anymore. In other words, stylish-haskell breaks the idempotence property.

Here is the file:

{-# LANGUAGE CPP #-}
{-# LINE 2 "System/DiskSpace.hsc" #-}

{- |
Module      : System.DiskSpace

Stability   : provisional
Portability : portable
-}

module System.DiskSpace
    ( DiskUsage(..)
    , getDiskUsage
    ) where

import Data.Aeson
import Foreign
import Foreign.C
import GHC.Generics
import Foreign.C

{-# LINE 22 "System/DiskSpace.hsc" #-}

#ifndef mingw32_HOST_OS
foreign import ccall safe statvfs :: CString -> Ptr a -> IO CInt
#else
statvfs :: CString -> Ptr a -> IO CInt
statvfs = error "Don't use me on windows...."
#endif

type FsBlkCnt = Word64
{-# LINE 26 "System/DiskSpace.hsc" #-}

getDiskUsage path =
    withCString path $ \cPath ->
        allocaBytes ((112)) $ \stat -> do
{-# LINE 30 "System/DiskSpace.hsc" #-}
            throwErrnoPathIfMinus1_ "getDiskUsage" path $ statvfs cPath stat
            bsize  <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) stat :: IO CULong
{-# LINE 32 "System/DiskSpace.hsc" #-}
            frsize <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) stat :: IO CULong
{-# LINE 33 "System/DiskSpace.hsc" #-}
            blocks <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) stat :: IO FsBlkCnt
{-# LINE 34 "System/DiskSpace.hsc" #-}
            bfree  <- ((\hsc_ptr -> peekByteOff hsc_ptr 24)) stat :: IO FsBlkCnt
{-# LINE 35 "System/DiskSpace.hsc" #-}
            bavail <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) stat :: IO FsBlkCnt
{-# LINE 36 "System/DiskSpace.hsc" #-}
            let frsize' = fromIntegral frsize
            return DiskUsage
                { diskTotal = frsize' * fromIntegral blocks
                , diskFree  = frsize' * fromIntegral bfree
                , diskAvail = frsize' * fromIntegral bavail
                , blockSize = fromIntegral bsize
                }

{-# LINE 61 "System/DiskSpace.hsc" #-}

-- | Disk usage information. All fields are in bytes.
data DiskUsage = DiskUsage
    { diskTotal :: Integer -- ^ The total size of the file system.
    , diskFree  :: Integer -- ^ The amount of free space. You probably want to
                           --   use 'diskAvail' instead.
    , diskAvail :: Integer -- ^ The amount of space available to the user.
                           --   Might be less than 'diskFree'. On Windows,
                --   this is always equal to 'diskFree'.
                           --   This is what most tools report as free
                           --   space (e.g. the unix @df@ tool).
    , blockSize :: Int     -- ^ The optimal block size for I/O in this volume.
                           --   Some operating systems report incorrect values
                           --   for this field.
    }
  deriving (Show, Eq, Generic)

instance ToJSON DiskUsage
instance FromJSON DiskUsage

-- | Retrieve disk usage information about a volume. The volume is
-- specified with the @FilePath@ argument. The path can refer to the root
-- directory or any other directory inside the volume.
-- Unix systems also accept arbitrary files, but this
-- does not work under Windows and therefore should be avoided if
-- portability is desired.
getDiskUsage :: FilePath -> IO DiskUsage

After running stylish-haskell, the diff is the following:

--- src/System/DiskSpace.hs     2021-02-22 13:38:57.563807974 +0000
+++ DiskSpaceNew.hs     2021-02-22 13:48:42.165595139 +0000
@@ -12,7 +12,6 @@
     ( DiskUsage(..)
     , getDiskUsage
     ) where
-
 import Data.Aeson
 import Foreign
 import Foreign.C
@@ -62,14 +61,14 @@
 data DiskUsage = DiskUsage
     { diskTotal :: Integer -- ^ The total size of the file system.
     , diskFree  :: Integer -- ^ The amount of free space. You probably want to
-                           --   use 'diskAvail' instead.
+                --   use 'diskAvail' instead.
     , diskAvail :: Integer -- ^ The amount of space available to the user.
-                           --   Might be less than 'diskFree'. On Windows,
+                --   Might be less than 'diskFree'. On Windows,
                 --   this is always equal to 'diskFree'.
                            --   This is what most tools report as free
                            --   space (e.g. the unix @df@ tool).
     , blockSize :: Int     -- ^ The optimal block size for I/O in this volume.
-                           --   Some operating systems report incorrect values
+                --   Some operating systems report incorrect values
                            --   for this field.
     }
   deriving (Show, Eq, Generic)

However, when I run stylish-haskell again, I see the following parse error:

$ ./stylish-haskell src/System/DiskSpace.hs
src/System/DiskSpace.hs: RealSrcSpan SrcSpanOneLine "System/DiskSpace.hsc" 13 1 7: parse error on input `import'

Stylish Haskell Version:

$ ./stylish-haskell --version
stylish-haskell 0.12.2.0
EncodePanda commented 3 years ago

Can you please share your configuration file that you use with stylish?

chshersh commented 3 years ago

I'm using the following configuration: