diff --git a/compiler/GHC/Tc/Utils/Env.hs b/compiler/GHC/Tc/Utils/Env.hs index 5a8a1698127655de7bbf6fabd9cb4f035b1e9a48..abb4289dfcade4477e9e1fdb68d337b741a4b7d6 100644 --- a/compiler/GHC/Tc/Utils/Env.hs +++ b/compiler/GHC/Tc/Utils/Env.hs @@ -106,10 +106,11 @@ import GHC.Unit.External import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Encoding -import GHC.Utils.Misc ( HasDebugCallStack ) +import GHC.Utils.Misc ( HasDebugCallStack, fuzzyLookup ) import GHC.Data.FastString import GHC.Data.Bag +import qualified Data.List.NonEmpty as NE import GHC.Data.List.SetOps import GHC.Data.Maybe( MaybeErr(..), orElse ) @@ -120,6 +121,7 @@ import GHC.Types.SourceFile import GHC.Types.Name import GHC.Types.Name.Set import GHC.Types.Name.Env +import GHC.Types.Hint ( GhcHint(SuggestSimilarNames), SimilarName(..) ) import GHC.Types.Id import GHC.Types.Id.Info ( RecSelParent(..) ) import GHC.Types.Name.Reader @@ -1076,14 +1078,22 @@ notFound name | isUnboundName name -> failM -- If the name really isn't in scope -- don't report it again (#11941) | otherwise -> failWithTc (TcRnStageRestriction (StageCheckSplice name)) - _ -> failWithTc $ - mkTcRnNotInScope (getRdrName name) (NotInScopeTc (getLclEnvTypeEnv lcl_env)) + _ -> failWithTc $ notInScope lcl_env -- Take care: printing the whole gbl env can -- cause an infinite loop, in the case where we -- are in the middle of a recursive TyCon/Class group; -- so let's just not print it! Getting a loop here is -- very unhelpful, because it hides one compiler bug with another } + where + rdrName = getRdrName name + similar_names + = map SimilarName $ fuzzyLookup (unpackFS $ occNameFS $ rdrNameOcc $ rdrName) + $ map (\x -> ((unpackFS $ occNameFS $ nameOccName x), x)) [] + hint = case similar_names of + (nm : nms) -> [SuggestSimilarNames rdrName (nm NE.:| nms)] + _ -> [] + notInScope lcl_env = TcRnNotInScope (NotInScopeTc (getLclEnvTypeEnv lcl_env)) rdrName [] hint wrongThingErr :: WrongThingSort -> TcTyThing -> Name -> TcM a wrongThingErr expected thing name =