Skip to content

Safe Haskell package trusting doesn't care about module reexports

Summary

Safe Haskell doesn't trust modules that are reexported by trusted packages; it is only trusts them if the original package is trusted.

Steps to reproduce

Write these files

I also pushed them to a wip/safe-reexport branch in the main repo.

.
├── a
│   ├── a.cabal
│   └── Foo.hs
├── b
│   └── b.cabal
├── c
│   ├── Bar.hs
│   └── c.cabal
└─ cabal.project
{-# LANGUAGE Trustworthy #-}
module Foo where

import Unsafe.Coerce (unsafeCoerce)

x = unsafeCoerce
{-# LANGUAGE Safe #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -fpackage-trust #-}
module Bar where

import Foo
name: a
version: 0
build-type: Simple

library
  exposed-modules:
    Foo
  build-depends: base
name: b
version: 0
build-type: Simple

library
  reexported-modules:
    Foo
  build-depends: base
               , a
name: c
version: 0
build-type: Simple

library
  exposed-modules:
    Bar
  build-depends: base
               , b
  --ghc-options: -trust a
  ghc-options: -trust b
packages: a b c

Try doing build

With ghc-options: -trust a commented, the build fails with a safety violation, with it uncommented the build succeeds.

The presence or absence of ghc-options: -trust b has no effect.

Expected behavior

  • The presence or absence of ghc-options: -trust a has no effect, as the package is getting the module from b
  • The presence of ghc-options: -trust b makes the build succeed.

Environment

  • GHC version used: 9.2
Edited by John Ericson
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information