[Git][ghc/ghc][wip/sjakobi/T2057] Add regression test for #2057
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC Commits: e894fe64 by Simon Jakobi at 2026-03-09T02:03:45+01:00 Add regression test for #2057 Test that GHC stops after an interface-file error instead of continuing into the linker. The test constructs a stale package dependency on purpose. `pkgB` is compiled against one version of package `A`, then the same unit id is replaced by an incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`, finds an unfolding that still mentions the old `A`, and should fail while loading interfaces. Closes #2057. Assisted-by: Codex - - - - - 12 changed files: - + testsuite/tests/driver/T2057/.gitignore - + testsuite/tests/driver/T2057/Makefile - + testsuite/tests/driver/T2057/README.md - + testsuite/tests/driver/T2057/T2057.stderr - + testsuite/tests/driver/T2057/all.T - + testsuite/tests/driver/T2057/app/Main.hs - + testsuite/tests/driver/T2057/pkgA1.conf.in - + testsuite/tests/driver/T2057/pkgA1/A.hs - + testsuite/tests/driver/T2057/pkgA2.conf.in - + testsuite/tests/driver/T2057/pkgA2/A.hs - + testsuite/tests/driver/T2057/pkgB.conf.in - + testsuite/tests/driver/T2057/pkgB/B.hs Changes: ===================================== testsuite/tests/driver/T2057/.gitignore ===================================== @@ -0,0 +1 @@ +work/ ===================================== testsuite/tests/driver/T2057/Makefile ===================================== @@ -0,0 +1,59 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +WORK = work +PKGDB = $(WORK)/pkgdb +PKGA1 = $(WORK)/pkgA1 +PKGA2 = $(WORK)/pkgA2 +PKGB = $(WORK)/pkgB +APP = $(WORK)/app +OUT = $(WORK)/T2057.out +BASE_ID := $(shell "$(GHC_PKG)" field base id --simple-output) + +.PHONY: T2057 clean + +clean: + rm -rf $(WORK) + +# Dependency graph: +# pkgB is built against pkgA1, where A exports f1. +# We then rebuild the same installed unit id (pkgA) from the pkgA2 sources, +# where A instead exports f2. Reading B.hi therefore finds an unfolding for g +# that still refers to f1, and compiling Main against pkgB should stop at the +# interface error. +T2057: clean + + # Create an isolated package DB and output directories for the repro. + mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)' + '$(GHC_PKG)' init '$(PKGDB)' + + # Build and register pkgA1, the original version of A. + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \ + -this-unit-id pkgA -O -c pkgA1/A.hs -outputdir '$(PKGA1)' + ar q '$(PKGA1)/libHSpkgA.a' '$(PKGA1)/A.o' >/dev/null 2>&1 + sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf' + '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null + + # Build and register pkgB against pkgA1 so B.hi records the unfolding of g = f1. + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \ + -package pkgA1 -this-unit-id pkgB -O -c pkgB/B.hs \ + -outputdir '$(PKGB)' + ar q '$(PKGB)/libHSpkgB.a' '$(PKGB)/B.o' >/dev/null 2>&1 + sed "s|@BASE_ID@|$(BASE_ID)|g" pkgB.conf.in >'$(WORK)/pkgB.conf' + '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null + + # Rebuild the same installed unit id from pkgA2, replacing f1 with f2. + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \ + -this-unit-id pkgA -O -c pkgA2/A.hs -outputdir '$(PKGA2)' + ar q '$(PKGA2)/libHSpkgA.a' '$(PKGA2)/A.o' >/dev/null 2>&1 + sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf' + '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null + + # Compiling Main against pkgB should now fail while loading the stale B.hi. + ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs \ + -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB \ + >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; } + + # Strip the absolute test directory prefix before comparing against T2057.stderr. + sed "s#$(CURDIR)/##g" '$(OUT)' >&2 ===================================== testsuite/tests/driver/T2057/README.md ===================================== @@ -0,0 +1,8 @@ +`T2057` checks that GHC stops after an interface-file error instead of +continuing into the linker. + +The test constructs a stale package dependency on purpose. `pkgB` is compiled +against one version of package `A`, then the same unit id is replaced by an +incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`, +finds an unfolding that still mentions the old `A`, and should fail while +loading interfaces. ===================================== testsuite/tests/driver/T2057/T2057.stderr ===================================== @@ -0,0 +1,9 @@ +work/pkgB/B.hi +Declaration for g +Unfolding of g: + f1 ErrorWithoutFlag + Can't find interface-file declaration for variable f1 + Probable cause: bug in .hi-boot file, or inconsistent .hi file + Use -ddump-if-trace to get an idea of which file caused the error +<no location info>: + Cannot continue after interface file error ===================================== testsuite/tests/driver/T2057/all.T ===================================== @@ -0,0 +1,11 @@ +test( + 'T2057', + [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'README.md', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in']) + , when(opsys('mingw32'), skip) + , js_skip + , wasm_skip + , ignore_stdout + ], + makefile_test, + [] +) ===================================== testsuite/tests/driver/T2057/app/Main.hs ===================================== @@ -0,0 +1,6 @@ +module Main where + +import B + +main :: IO () +main = print (g 41) ===================================== testsuite/tests/driver/T2057/pkgA1.conf.in ===================================== @@ -0,0 +1,11 @@ +name: pkgA1 +version: 1.0 +id: pkgA +key: pkgA +exposed: True +exposed-modules: A +import-dirs: ${pkgroot}/pkgA1 +library-dirs: ${pkgroot}/pkgA1 +dynamic-library-dirs: ${pkgroot}/pkgA1 +hs-libraries: HSpkgA +depends: @BASE_ID@ ===================================== testsuite/tests/driver/T2057/pkgA1/A.hs ===================================== @@ -0,0 +1,5 @@ +module A (f1) where + +{-# INLINE f1 #-} +f1 :: Int -> Int +f1 x = x + 1 ===================================== testsuite/tests/driver/T2057/pkgA2.conf.in ===================================== @@ -0,0 +1,11 @@ +name: pkgA1 +version: 1.0 +id: pkgA +key: pkgA +exposed: True +exposed-modules: A +import-dirs: ${pkgroot}/pkgA2 +library-dirs: ${pkgroot}/pkgA2 +dynamic-library-dirs: ${pkgroot}/pkgA2 +hs-libraries: HSpkgA +depends: @BASE_ID@ ===================================== testsuite/tests/driver/T2057/pkgA2/A.hs ===================================== @@ -0,0 +1,4 @@ +module A (f2) where + +f2 :: Int -> Int +f2 x = x + 100 ===================================== testsuite/tests/driver/T2057/pkgB.conf.in ===================================== @@ -0,0 +1,11 @@ +name: pkgB +version: 1.0 +id: pkgB +key: pkgB +exposed: True +exposed-modules: B +import-dirs: ${pkgroot}/pkgB +library-dirs: ${pkgroot}/pkgB +dynamic-library-dirs: ${pkgroot}/pkgB +hs-libraries: HSpkgB +depends: pkgA @BASE_ID@ ===================================== testsuite/tests/driver/T2057/pkgB/B.hs ===================================== @@ -0,0 +1,7 @@ +module B (g) where + +import A + +{-# INLINE g #-} +g :: Int -> Int +g x = f1 x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e894fe640926df1ae83c757dd4a821f5... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e894fe640926df1ae83c757dd4a821f5... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Simon Jakobi (@sjakobi2)