From f158a8d08fd21fb0778593de3dd1426650e844d3 Mon Sep 17 00:00:00 2001
From: Rodrigo Mesquita <rodrigo.m.mesquita@gmail.com>
Date: Thu, 16 Nov 2023 15:38:55 +0000
Subject: [PATCH] Improve error message when reading invalid `.target` files

A `.target` file generated by ghc-toolchain or by configure can become
invalid if the target representation (`Toolchain.Target`) is changed
while the files are not re-generated by calling `./configure` or
`ghc-toolchain` again. There is also the issue of hadrian caching the
dependencies on `.target` files, which makes parsing fail when reading
reading the cached value if the representation has been updated.

This patch provides a better error message in both situations, moving
away from a terrible `Prelude.read: no parse` error that you would get
otherwise.

Fixes #24199
---
 hadrian/src/Hadrian/Oracles/TextFile.hs | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/hadrian/src/Hadrian/Oracles/TextFile.hs b/hadrian/src/Hadrian/Oracles/TextFile.hs
index ebdfe31a168b..a85669780d34 100644
--- a/hadrian/src/Hadrian/Oracles/TextFile.hs
+++ b/hadrian/src/Hadrian/Oracles/TextFile.hs
@@ -163,14 +163,23 @@ textFileOracle = do
         putVerbose $ "| TargetFile oracle: reading " ++ quote file ++ "..."
         mtarget <- readMaybe <$> readFile' file
         case mtarget of
-          Nothing -> error $ "Failed to read a Toolchain.Target from " ++ quote file
+          Nothing -> error $ unlines ["Error parsing a Toolchain.Target from " ++ quote file,
+                                      "Perhaps the `.target` file is out of date.",
+                                      "Try re-running `./configure`."
+                                     ]
+
           Just target -> return (target :: Toolchain.Target)
     void $ addOracleCache $ \(TargetFile file) -> tf file
 
 -- Orphan instances for (ShakeValue Toolchain.Target)
 instance Binary Toolchain.Target where
-  put = put  . show
-  get = read <$> get
+  put = put . show
+  get = fromMaybe (error $ unlines ["Error parsing a toolchain `.target` file from its binary representation in hadrian.",
+                                    "This is likely caused by a stale hadrian/shake cache",
+                                    "which has saved an old `.target` file that can't be parsed",
+                                    "into a more recent `Toolchain.Target`. It is recommended to reset",
+                                    "by running `./hadrian/build clean`."
+                                   ]) . readMaybe <$> get
 
 instance Hashable Toolchain.Target where
   hashWithSalt s = hashWithSalt s . show
-- 
GitLab