agda / agda

Agda is a dependently typed programming language / interactive theorem prover.

Home Page:https://wiki.portal.chalmers.se/agda/pmwiki.php

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OptionWarnings are emitted twice

andreasabel opened this issue · comments

OptionWarnings are emitted twice, e.g.:

LossyUnification.agda:1,1-49
warning: -W[no]OptionRenamed
Option --experimental-lossy-unification is deprecated, please use --lossy-unification instead
LossyUnification.agda:1,1-49
warning: -W[no]OptionRenamed
Option --experimental-lossy-unification is deprecated, please use --lossy-unification instead

Suspected reason: We are calling setOptionsFromPragma several times during processing a file.

setOptionsFromPragma :: OptionsPragma -> TCM ()
setOptionsFromPragma ps = setCurrentRange (pragmaRange ps) $ do
opts <- commandLineOptions
let (z, warns) = runOptM (parsePragmaOptions ps opts)
mapM_ (warning . OptionWarning) warns

Found while working on:

Not sure how it applies to this issue, but in #6640 I had to jump through some hoops to not get the conflicting options warning multiple times:

  • Only warn when the pragma options have changed (otherwise you get the same warning for each new OPTIONS pragma in a file)
    check (ImpliesPragmaOption nameA valA flagA nameB valB flagB)
    | flagA newOpts == flagA oldOpts
    , flagB newOpts == flagB oldOpts = pure () -- Nothing changed, don't check again.
  • Split setOptionsFromPragma into a checking and a non-checking version
    -- | Set pragma options without checking for consistency.
    setOptionsFromPragma :: OptionsPragma -> TCM ()
    setOptionsFromPragma = setOptionsFromPragma' False
    -- | Set pragma options and check them for consistency.
    checkAndSetOptionsFromPragma :: OptionsPragma -> TCM ()
    checkAndSetOptionsFromPragma = setOptionsFromPragma' True
  • and propagate it to setOptionsFromSourcePragma in Interaction.Imports
    -- | Set options from a 'Source' pragma, using the source
    -- ranges of the pragmas for error reporting. Flag to check consistency.
    setOptionsFromSourcePragmas :: Bool -> Source -> TCM ()
    setOptionsFromSourcePragmas checkOpts src = do
    mapM_ setOpts (srcDefaultPragmas src)
    mapM_ setOpts (srcFilePragmas src)
    where
    setOpts | checkOpts = checkAndSetOptionsFromPragma
    | otherwise = setOptionsFromPragma
  • and only run the check in typeCheckMain and in createInterface for non-main modules (otherwise you get the warning twice for the main module)
    typeCheckMain mode src = do
    -- liftIO $ putStrLn $ "This is typeCheckMain " ++ prettyShow f
    -- liftIO . putStrLn . show =<< getVerbosity
    -- For the main interface, we also remember the pragmas from the file
    setOptionsFromSourcePragmas True src
    -- Only check consistency if not main (we check consistency for the main module in
    -- `typeCheckMain`.
    let checkConsistency | MainInterface{} <- isMain = False
    | otherwise = True
    setOptionsFromSourcePragmas checkConsistency src

My question here is whether we should dig out the reason why the warning is raised twice, or whether we reorganise the warning store so that duplicate warnings are just stored once.
E.g. the warning store could be a map from positions to sets of warnings. (Currently it is a plain list.)