[Git][ghc/ghc][wip/sjakobi/T2057] 5 commits: testsuite: simplify T2057 Makefile recipe
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC Commits: 500dde14 by Simon Jakobi at 2026-03-09T01:18:11+01:00 testsuite: simplify T2057 Makefile recipe - - - - - 2dea8545 by Simon Jakobi at 2026-03-09T01:22:05+01:00 testsuite: document T2057 Makefile steps Assisted-by: Codex - - - - - f6f4894e by Simon Jakobi at 2026-03-09T01:32:25+01:00 testsuite: rename T2057 pkgA unit id - - - - - 4f3ec643 by Simon Jakobi at 2026-03-09T01:33:36+01:00 testsuite: simplify T2057 binding names - - - - - 89ed54d6 by Simon Jakobi at 2026-03-09T01:41:47+01:00 testsuite: document T2057 test setup - - - - - 11 changed files: - 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/Makefile ===================================== @@ -9,6 +9,7 @@ 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 @@ -16,31 +17,31 @@ clean: rm -rf $(WORK) # Dependency graph: -# pkgB is built against pkgA1. -# We then rebuild the same installed unit id (pkgA1-1) from the pkgA2 sources, -# leaving pkgB with a stale unfolding that still references pkgA1's old API. -# Compiling Main against pkgB should therefore stop at the interface error. +# pkgB is built against pkgA1, where A exports f1. +# We then rebuild the same installed unit id (pkgA-1) 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 - @set -eu; \ - BASE_ID=`'$(GHC_PKG)' field base id --simple-output`; \ - mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'; \ - '$(GHC_PKG)' init '$(PKGDB)'; \ - '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA1-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)'; \ - ar q '$(PKGA1)/libHSpkgA1-1.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; \ - '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -package pkgA1 -this-unit-id pkgB-1 -O -c pkgB/B.hs -outputdir '$(PKGB)'; \ - ar q '$(PKGB)/libHSpkgB-1.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; \ - '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA1-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)'; \ - ar q '$(PKGA2)/libHSpkgA1-1.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; \ - status=0; \ - '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB >'$(OUT)' 2>&1 || status=$$?; \ - if [ $$status -eq 0 ]; then \ - echo "expected compilation failure" >&2; \ - exit 1; \ - fi; \ - sed "s#`pwd`/##g" '$(OUT)' >&2 + # 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-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)' + ar q '$(PKGA1)/libHSpkgA-1.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-1 -O -c pkgB/B.hs -outputdir '$(PKGB)' + ar q '$(PKGB)/libHSpkgB-1.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-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)' + ar q '$(PKGA2)/libHSpkgA-1.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,13 @@ +`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. + +The golden [`T2057.stderr`](T2057.stderr) captures the expected behaviour on a +fixed compiler: report the missing declaration from the stale interface and +then abort with `Cannot continue after interface file error`. Any linker output +would be a regression. ===================================== testsuite/tests/driver/T2057/T2057.stderr ===================================== @@ -1,8 +1,8 @@ work/pkgB/B.hi -Declaration for saved -Unfolding of saved: - staleDependencyBinding ErrorWithoutFlag - Can't find interface-file declaration for variable staleDependencyBinding +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>: ===================================== testsuite/tests/driver/T2057/all.T ===================================== @@ -1,6 +1,6 @@ test( 'T2057', - [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in']) + [ 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 ===================================== testsuite/tests/driver/T2057/app/Main.hs ===================================== @@ -3,4 +3,4 @@ module Main where import B main :: IO () -main = print (saved 41) +main = print (g 41) ===================================== testsuite/tests/driver/T2057/pkgA1.conf.in ===================================== @@ -1,11 +1,11 @@ name: pkgA1 version: 1.0 -id: pkgA1-1 -key: pkgA1-1 +id: pkgA-1 +key: pkgA-1 exposed: True exposed-modules: A import-dirs: ${pkgroot}/pkgA1 library-dirs: ${pkgroot}/pkgA1 dynamic-library-dirs: ${pkgroot}/pkgA1 -hs-libraries: HSpkgA1-1 +hs-libraries: HSpkgA-1 depends: @BASE_ID@ ===================================== testsuite/tests/driver/T2057/pkgA1/A.hs ===================================== @@ -1,5 +1,5 @@ -module A (staleDependencyBinding) where +module A (f1) where -{-# INLINE staleDependencyBinding #-} -staleDependencyBinding :: Int -> Int -staleDependencyBinding x = x + 1 +{-# INLINE f1 #-} +f1 :: Int -> Int +f1 x = x + 1 ===================================== testsuite/tests/driver/T2057/pkgA2.conf.in ===================================== @@ -1,11 +1,11 @@ name: pkgA1 version: 1.0 -id: pkgA1-1 -key: pkgA1-1 +id: pkgA-1 +key: pkgA-1 exposed: True exposed-modules: A import-dirs: ${pkgroot}/pkgA2 library-dirs: ${pkgroot}/pkgA2 dynamic-library-dirs: ${pkgroot}/pkgA2 -hs-libraries: HSpkgA1-1 +hs-libraries: HSpkgA-1 depends: @BASE_ID@ ===================================== testsuite/tests/driver/T2057/pkgA2/A.hs ===================================== @@ -1,4 +1,4 @@ -module A (replacementBinding) where +module A (f2) where -replacementBinding :: Int -> Int -replacementBinding x = x + 100 +f2 :: Int -> Int +f2 x = x + 100 ===================================== testsuite/tests/driver/T2057/pkgB.conf.in ===================================== @@ -8,4 +8,4 @@ import-dirs: ${pkgroot}/pkgB library-dirs: ${pkgroot}/pkgB dynamic-library-dirs: ${pkgroot}/pkgB hs-libraries: HSpkgB-1 -depends: pkgA1-1 @BASE_ID@ +depends: pkgA-1 @BASE_ID@ ===================================== testsuite/tests/driver/T2057/pkgB/B.hs ===================================== @@ -1,7 +1,7 @@ -module B (saved) where +module B (g) where import A -{-# INLINE saved #-} -saved :: Int -> Int -saved x = staleDependencyBinding x +{-# INLINE g #-} +g :: Int -> Int +g x = f1 x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13ab42f498dbac37cb568b0ad63b767... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13ab42f498dbac37cb568b0ad63b767... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Simon Jakobi (@sjakobi2)