CPP is not allowed in combination with targetContents
Summary
GHC.load does not accept in-memory files that (on disk) appear to require preprocessing (CPP enabled locally), or if CPP is enabled for the session.
HscTypes defines
data Target
= Target {
targetId :: TargetId,
targetAllowObjCode :: Bool,
targetContents :: Maybe (StringBuffer,UTCTime)
}
where the targetContents is for files that have not yet been saved to disk by the user.
Steps to reproduce
For this source
{-# LANGUAGE CPP #-}
module Medley.Wibble where
#ifdef UNCOMPILABLE
blah blah not compilable
#endif
If the user edits out the entire #ifdef ... #endif section in memory, and a version that looks more like
{-# LANGUAGE CPP #-}
module Medley.Wibble where
is GHC.loaded, then we get
buffer needs preprocesing; interactive check disabled
Note that using (Just $ Hsc HsSrcFile) as the starting phase makes no difference. The documentation of TargetFile contradicts Target by indicating that the file will be preprocessed.
Looking in GhcMake it looks like the fact that CPP is enabled may be the problem.
Expected behavior
The the contents of the file on disk would not be read at all if a targetContents is provided. Or at least that it would not cause compilation to fail.
Environment
- GHC version used: 8.4.4 and 8.6.5.
Workaround
- create a temporary file and don't use
targetContents - disable CPP (and suffer the consequences)
The better solution appears to be never to use targetContents... would it not make sense for preprocessFile to create a temporary file if it feels that precprocessing is required? It returns IO (although admitedly it would not know how to clean up)