alanz / ghc-exactprint

GHC version of haskell-src-exts exactPrint
BSD 3-Clause "New" or "Revised" License
70 stars 32 forks source link

parseModuleFromString seems to use unhelpful dflags #87

Open jrp2014 opened 4 years ago

jrp2014 commented 4 years ago

I am using ghx-exactprint to write ghc type-checked plugin, with ghc-8.10.1. I am testing it over the agda codebase (https://github.com/agda/agda) as it uses a range of GHC features. ghc-exactprint generally does a great job, but there are a couple of cases where it seems not to respect the language extensions, when parsing a file using parseModuleFromString. If instead, I use parseModuleFromStringInternal with the dflags that ghc provides to a plug-in, everything seems to work well.

So I have a work-around, but thought that I'd report the issue, in case there is an underlying problem, rather than a misuse of ghc-exactprint

For example, parseModulefromString doesn't seem to like this

src/full/Agda/Syntax/Translation/AbstractToConcrete.hs:75:42: error:
    parse error on input ‘:|’
   |
75 | import Agda.Utils.List1 (List1, pattern (:|))
   |                                          ^^

The language extentions in use are:

 On TypeSynonymInstances, On TupleSections, On StandaloneDeriving,
 On ExplicitForAll, On ScopedTypeVariables,
 On DisambiguateRecordFields, On RecordWildCards, On ExplicitForAll,
 On RankNTypes, On PatternSynonyms, On OverloadedStrings,
 On RecordPuns, On MultiWayIf, On ConstrainedClassMethods,
 On MultiParamTypeClasses, On LambdaCase,
 On ConstrainedClassMethods, On MultiParamTypeClasses,
 On FunctionalDependencies, On TypeSynonymInstances,
 On FlexibleInstances, On FlexibleContexts, On ExplicitForAll,
 On ExistentialQuantification, On DeriveFunctor, On DeriveFoldable,
 On DeriveTraversable, On DeriveFunctor, On DeriveFoldable,
 On DefaultSignatures, On ConstraintKinds, On BangPatterns]

A further case is:

src/full/Agda/TypeChecking/Monad/Signature.hs:98:76: error:
    Illegal lambda-case (use LambdaCase)
   |
98 | setTerminates q b = modifySignature $ updateDefinition q $ updateTheDef $ \case
   |                                                                            ^^^^
:
src/full/Agda/TypeChecking/Monad/Signature.hs:845:7: error:
    Illegal bang-pattern (use BangPatterns):
    ! cs'
    |
845 |   let !cs' = cs ++ dataCons def in
    |       ^^^^

with language extensions (extensions dflags)

[On MonoLocalBinds, On KindSignatures, On ExplicitNamespaces,
 On TypeFamilies, On NondecreasingIndentation,
 On TypeSynonymInstances, On TupleSections, On StandaloneDeriving,
 On ExplicitForAll, On ScopedTypeVariables,
 On DisambiguateRecordFields, On RecordWildCards, On ExplicitForAll,
 On RankNTypes, On PatternSynonyms, On OverloadedStrings,
 On RecordPuns, On MultiWayIf, On ConstrainedClassMethods,
 On MultiParamTypeClasses, On LambdaCase,
 On ConstrainedClassMethods, On MultiParamTypeClasses,
 On FunctionalDependencies, On TypeSynonymInstances,
 On FlexibleInstances, On FlexibleContexts, On ExplicitForAll,
 On ExistentialQuantification, On DeriveFunctor, On DeriveFoldable,
 On DeriveTraversable, On DeriveFunctor, On DeriveFoldable,
 On DefaultSignatures, On ConstraintKinds, On BangPatterns]

As I am writing a type-checked phase plugin, ghc has parsed the code without complaint. In fact, I am feeding parseModuleFromString with a string generated by lexemeToString applied to ms_hspp_buf modSummary (ie, the pre-processed source).

As I say, the issue appears to be with the DynFlags that parseModuleFromString conjures up. When I use those provided to the plugin (via getDynFlags and parseModuleFromStringInternal) all seems well. Maybe this can be fixed, or the documentation of the contexts in which parseModuleFromString could be supplemented.

[Later] Maybe spoke too soon. Source comments appear to be discarded when I use parseModulefromStringIntenal

Anyway thanks for the package.

PS: I assume that the a key reason for having ghc-exactprint is that GHC does not retain enough source code annotations, hence the need to reparse the source.

jrp2014 commented 4 years ago

To answer my own issue, the problem seem to be with the dflags that are set in initDynFlagsPure (perhaps when some language extensions are set in the cabal file, supplemented by language extensions in the source file). If I use the ModSummary dflags but also set Opt_KeepRawTokenStream with parseModuleFromStringInternal it all works OK.

I suspect that the fix to https://gitlab.haskell.org/ghc/ghc/issues/10942 is what is causing the comments to disappear without setting Opt_KeepRawTokenStream.

I have not tried the other adjustments that initDynFlagsPure makes, such as -hide-all-packages, without apparent ill effect.

So there does seem to be an underlying bug here, but it's not clear to me what the fix is.