haskell / filepath

Haskell FilePath core library
BSD 3-Clause "New" or "Revised" License
66 stars 33 forks source link

Move deprecated modules to undeprecated hidden modules #213

Closed tbidne closed 7 months ago

tbidne commented 7 months ago

Resolves #209, obviates https://github.com/haskell/filepath/pull/211.

Problem

Given the modules:

module X {-# DEPRECATED "message" #-} (foo) where

foo :: ()
module Y (foo) where

import X (foo)

We want the following to succeed without warnings:

module Z where

import Y (foo)

Unfortunately we receive a deprecation warning for the usage in Z even though we imported a(n ostensibly non-deprecated) symbol from a non-deprecated symbol. The problem is that any symbol (foo) defined in a deprecated module (X) inherits the deprecation.

Solution

The strategy here is outlined in this comment: https://github.com/haskell/filepath/issues/209#issuecomment-1832809252

We move X's implementation into the non-deprecated but hidden X.Hidden.

module X.Hidden (foo)

-- foo no longer inherits the deprecation
foo :: ()

X retains its deprecation, merely re-exporting X.Hidden.

-- importing this still warns
module X {-# DEPRECATED "message" #-} (module X.Hidden) where

import X.Hidden
module Y (foo) where

import X (foo)

Now, this succeeds as we would like:

module Z where

import Y (foo)

And this fails:

module W where

import X (foo)

This PR also changes internal usage of deprecated modules to use the new hidden ones. This removes the need to litter the codebase with {-# OPTIONS_GHC -Wno-deprecations #-}, to avoid internal warnings.

It is recommended to review the commits individually, as the overall diff is large. The first commit merely renames modules X -> X.Hidden. The second adds back X with deprecation message, and removes the deprecation from X.Hidden.

hasufell commented 7 months ago

I tested this locally with the https://github.com/tbidne/osstr-deprecated package and GHC 8.6 to 9.8. It seems to work as expected.

tbidne commented 7 months ago

Thanks everyone!