Skip to content

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

  1. create a temporary file and don't use targetContents
  2. 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)

Edited by Sam Halliday
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information