From 2eb46b62fcdf9c4c1297a44bb0de0d630f53f545 Mon Sep 17 00:00:00 2001 From: jappeace-sloth Date: Tue, 10 Mar 2026 15:57:08 +0000 Subject: [PATCH] Include provenance in Backpack unfilled requirements error When a non-library component has unfilled Backpack signature requirements, the error message now shows where each requirement came from (e.g. "brought into scope by build-depends: Fail1") using the ModuleSource information already available in the ModuleScope. Updated the Fail3 test golden files and strengthened the test assertion to verify provenance information is present. Addresses https://github.com/haskell/cabal/issues/7192 run fourmalou more formatting --- .../Distribution/Backpack/LinkedComponent.hs | 12 +++++++++- .../Backpack/Fail3/setup.cabal.out | 3 ++- .../PackageTests/Backpack/Fail3/setup.out | 3 ++- .../PackageTests/Backpack/Fail3/setup.test.hs | 1 + .../PackageTests/Backpack/Fail4/Fail4.cabal | 24 +++++++++++++++++++ .../PackageTests/Backpack/Fail4/Main.hs | 1 + .../Backpack/Fail4/lib-a/UnfilledSig.hsig | 1 + .../Backpack/Fail4/lib-b/UnfilledSig.hsig | 1 + .../Backpack/Fail4/setup.cabal.out | 8 +++++++ .../PackageTests/Backpack/Fail4/setup.out | 8 +++++++ .../PackageTests/Backpack/Fail4/setup.test.hs | 9 +++++++ 11 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/Fail4.cabal create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/Main.hs create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/lib-a/UnfilledSig.hsig create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/lib-b/UnfilledSig.hsig create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/setup.cabal.out create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/setup.out create mode 100644 cabal-testsuite/PackageTests/Backpack/Fail4/setup.test.hs diff --git a/Cabal/src/Distribution/Backpack/LinkedComponent.hs b/Cabal/src/Distribution/Backpack/LinkedComponent.hs index a66240d82e3..7b98c04682d 100644 --- a/Cabal/src/Distribution/Backpack/LinkedComponent.hs +++ b/Cabal/src/Distribution/Backpack/LinkedComponent.hs @@ -258,7 +258,17 @@ toLinkedComponent hang (text "Non-library component has unfilled requirements:") 4 - (vcat [pretty req | req <- Set.toList reqs]) + ( vcat + [ case Map.lookup req (modScopeRequires linked_shape0) of + Just srcs@(_ : _) -> + hang + (pretty req) + 4 + (vcat [text "brought into scope by" <+> dispModuleSource (getSource src) | src <- srcs]) + _ -> pretty req + | req <- Set.toList reqs + ] + ) -- NB: do NOT include hidden modules here: GHC 7.10's ghc-pkg -- won't allow it (since someone could directly synthesize diff --git a/cabal-testsuite/PackageTests/Backpack/Fail3/setup.cabal.out b/cabal-testsuite/PackageTests/Backpack/Fail3/setup.cabal.out index d1e33f130cf..cdf8656f78f 100644 --- a/cabal-testsuite/PackageTests/Backpack/Fail3/setup.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Fail3/setup.cabal.out @@ -1,5 +1,6 @@ # Setup configure Configuring Fail1-0.1.0.0... Error: - Non-library component has unfilled requirements: UnfilledSig + Non-library component has unfilled requirements: + UnfilledSig brought into scope by build-depends: Fail1 In the stanza executable foo diff --git a/cabal-testsuite/PackageTests/Backpack/Fail3/setup.out b/cabal-testsuite/PackageTests/Backpack/Fail3/setup.out index d1e33f130cf..cdf8656f78f 100644 --- a/cabal-testsuite/PackageTests/Backpack/Fail3/setup.out +++ b/cabal-testsuite/PackageTests/Backpack/Fail3/setup.out @@ -1,5 +1,6 @@ # Setup configure Configuring Fail1-0.1.0.0... Error: - Non-library component has unfilled requirements: UnfilledSig + Non-library component has unfilled requirements: + UnfilledSig brought into scope by build-depends: Fail1 In the stanza executable foo diff --git a/cabal-testsuite/PackageTests/Backpack/Fail3/setup.test.hs b/cabal-testsuite/PackageTests/Backpack/Fail3/setup.test.hs index 64f462ef12f..0d36a8852b8 100644 --- a/cabal-testsuite/PackageTests/Backpack/Fail3/setup.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Fail3/setup.test.hs @@ -3,4 +3,5 @@ main = setupAndCabalTest $ do skipUnlessGhcVersion ">= 8.1" r <- fails $ setup' "configure" [] assertOutputContains "UnfilledSig" r + assertOutputContains "brought into scope by" r return () diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/Fail4.cabal b/cabal-testsuite/PackageTests/Backpack/Fail4/Fail4.cabal new file mode 100644 index 00000000000..eb53549bab9 --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/Fail4.cabal @@ -0,0 +1,24 @@ +cabal-version: 3.0 +name: Fail4 +version: 0.1.0.0 +license: BSD-3-Clause +author: Edward Z. Yang +maintainer: ezyang@cs.stanford.edu +build-type: Simple + +library sig-lib-a + signatures: UnfilledSig + build-depends: base + hs-source-dirs: lib-a + default-language: Haskell2010 + +library sig-lib-b + signatures: UnfilledSig + build-depends: base + hs-source-dirs: lib-b + default-language: Haskell2010 + +executable foo + build-depends: Fail4:sig-lib-a, Fail4:sig-lib-b + main-is: Main.hs + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/Main.hs b/cabal-testsuite/PackageTests/Backpack/Fail4/Main.hs new file mode 100644 index 00000000000..b3549c2fe3d --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/Main.hs @@ -0,0 +1 @@ +main = return () diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/lib-a/UnfilledSig.hsig b/cabal-testsuite/PackageTests/Backpack/Fail4/lib-a/UnfilledSig.hsig new file mode 100644 index 00000000000..567af716f6c --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/lib-a/UnfilledSig.hsig @@ -0,0 +1 @@ +signature UnfilledSig where diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/lib-b/UnfilledSig.hsig b/cabal-testsuite/PackageTests/Backpack/Fail4/lib-b/UnfilledSig.hsig new file mode 100644 index 00000000000..567af716f6c --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/lib-b/UnfilledSig.hsig @@ -0,0 +1 @@ +signature UnfilledSig where diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/setup.cabal.out b/cabal-testsuite/PackageTests/Backpack/Fail4/setup.cabal.out new file mode 100644 index 00000000000..97c0f360bfb --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/setup.cabal.out @@ -0,0 +1,8 @@ +# Setup configure +Configuring Fail4-0.1.0.0... +Error: + Non-library component has unfilled requirements: + UnfilledSig + brought into scope by build-depends: Fail4:sig-lib-a + brought into scope by build-depends: Fail4:sig-lib-b + In the stanza executable foo diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/setup.out b/cabal-testsuite/PackageTests/Backpack/Fail4/setup.out new file mode 100644 index 00000000000..97c0f360bfb --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/setup.out @@ -0,0 +1,8 @@ +# Setup configure +Configuring Fail4-0.1.0.0... +Error: + Non-library component has unfilled requirements: + UnfilledSig + brought into scope by build-depends: Fail4:sig-lib-a + brought into scope by build-depends: Fail4:sig-lib-b + In the stanza executable foo diff --git a/cabal-testsuite/PackageTests/Backpack/Fail4/setup.test.hs b/cabal-testsuite/PackageTests/Backpack/Fail4/setup.test.hs new file mode 100644 index 00000000000..dd901b1aa58 --- /dev/null +++ b/cabal-testsuite/PackageTests/Backpack/Fail4/setup.test.hs @@ -0,0 +1,9 @@ +import Test.Cabal.Prelude + +main = setupAndCabalTest $ do + skipUnlessGhcVersion ">= 8.1" + r <- fails $ setup' "configure" [] + assertOutputContains "UnfilledSig" r + assertOutputContains "brought into scope by build-depends: Fail4:sig-lib-a" r + assertOutputContains "brought into scope by build-depends: Fail4:sig-lib-b" r + return ()