diff --git a/ghc/compiler/reader/RdrHsSyn.lhs b/ghc/compiler/reader/RdrHsSyn.lhs index 922fe48ffae541a263ed58ac8769dad19f22b2be..cb8e8c9f292173c85780c88761d5450466a564da 100644 --- a/ghc/compiler/reader/RdrHsSyn.lhs +++ b/ghc/compiler/reader/RdrHsSyn.lhs @@ -46,7 +46,7 @@ module RdrHsSyn ( qual, varQual, tcQual, varUnqual, lexVarQual, lexTcQual, dummyRdrVarName, dummyRdrTcName, isUnqual, isQual, - showRdr, rdrNameOcc, ieOcc, + showRdr, rdrNameOcc, rdrNameModule, ieOcc, cmpRdr, prefixRdrName, mkOpApp, mkClassDecl @@ -195,6 +195,7 @@ lexVarQual (m,n,hif) = Qual m (VarOcc n) hif dummyRdrVarName = Unqual (VarOcc SLIT("V-DUMMY")) dummyRdrTcName = Unqual (VarOcc SLIT("TC-DUMMY")) + varUnqual n = Unqual (VarOcc n) isUnqual (Unqual _) = True @@ -218,6 +219,9 @@ rdrNameOcc :: RdrName -> OccName rdrNameOcc (Unqual occ) = occ rdrNameOcc (Qual _ occ _) = occ +rdrNameModule :: RdrName -> Module +rdrNameModule (Qual m _ _) = m + ieOcc :: RdrNameIE -> OccName ieOcc ie = rdrNameOcc (ieName ie) diff --git a/ghc/compiler/rename/RnEnv.lhs b/ghc/compiler/rename/RnEnv.lhs index c41b0bd7a7083809b3ea20c34b465d4310ceac24..e74404632a0e88d62281208ed90d363e5b7fb381 100644 --- a/ghc/compiler/rename/RnEnv.lhs +++ b/ghc/compiler/rename/RnEnv.lhs @@ -17,6 +17,7 @@ import RdrHsSyn ( RdrName(..), RdrNameIE, import HsTypes ( getTyVarName, replaceTyVarName ) import BasicTypes ( Fixity(..), FixityDirection(..), IfaceFlavour(..) ) import RnMonad +import ErrUtils ( ErrMsg ) import Name ( Name, OccName(..), Provenance(..), ExportFlag(..), NamedThing(..), occNameFlavour, getSrcLoc, NameSet, emptyNameSet, addListToNameSet, nameSetToList, @@ -254,19 +255,33 @@ Looking up a name in the RnEnv. lookupRn :: RdrName -> Maybe Name -- Result of environment lookup -> RnMS s Name - -lookupRn rdr_name (Just name) +lookupRn rdr_name (Just name) = -- Found the name in the envt returnRn name -- In interface mode the only things in -- the environment are things in local (nested) scopes +lookupRn rdr_name nm@Nothing + = tryLookupRn rdr_name nm `thenRn` \ name_or_error -> + case name_or_error of + Left (nm,err) -> failWithRn nm err + Right nm -> returnRn nm + +tryLookupRn :: RdrName + -> Maybe Name -- Result of environment lookup + -> RnMS s (Either (Name, ErrMsg) Name) +tryLookupRn rdr_name (Just name) + = -- Found the name in the envt + returnRn (Right name) -- In interface mode the only things in + -- the environment are things in local (nested) scopes -lookupRn rdr_name Nothing +-- lookup in environment, but don't flag an error if +-- name is not found. +tryLookupRn rdr_name Nothing = -- We didn't find the name in the environment getModeRn `thenRn` \ mode -> case mode of { - SourceMode -> failWithRn (mkUnboundName rdr_name) - (unknownNameErr rdr_name) ; - -- Souurce mode; lookup failure is an error + SourceMode -> returnRn (Left ( mkUnboundName rdr_name + , unknownNameErr rdr_name)); + -- Source mode; lookup failure is an error InterfaceMode _ _ -> @@ -279,9 +294,13 @@ lookupRn rdr_name Nothing -- So, qualify the unqualified name with the -- module of the interface file, and try again case rdr_name of - Unqual occ -> getModuleRn `thenRn` \ mod -> - newImportedGlobalName mod occ HiFile - Qual mod occ hif -> newImportedGlobalName mod occ hif + Unqual occ -> + getModuleRn `thenRn` \ mod -> + newImportedGlobalName mod occ HiFile `thenRn` \ nm -> + returnRn (Right nm) + Qual mod occ hif -> + newImportedGlobalName mod occ hif `thenRn` \ nm -> + returnRn (Right nm) } @@ -321,12 +340,28 @@ lookupBndrRn rdr_name -- deciding which instance declarations to import. lookupOccRn :: RdrName -> RnMS s Name lookupOccRn rdr_name + = tryLookupOccRn rdr_name `thenRn` \ name_or_error -> + case name_or_error of + Left (nm, err) -> failWithRn nm err + Right nm -> returnRn nm + +-- tryLookupOccRn is the fail-safe version of lookupOccRn, returning +-- back the error rather than immediately flagging it. It is only +-- directly used by RnExpr.rnExpr to catch and rewrite unbound +-- uses of `assert'. +tryLookupOccRn :: RdrName -> RnMS s (Either (Name,ErrMsg) Name) +tryLookupOccRn rdr_name = lookupNameRn rdr_name `thenRn` \ maybe_name -> - lookupRn rdr_name maybe_name `thenRn` \ name -> - let + tryLookupRn rdr_name maybe_name `thenRn` \ name_or_error -> + case name_or_error of + Left _ -> returnRn name_or_error + Right name -> + let name' = mungePrintUnqual rdr_name name - in - addOccurrenceName name' + in + addOccurrenceName name' `thenRn_` + returnRn name_or_error + -- lookupGlobalOccRn is like lookupOccRn, except that it looks in the global -- environment only. It's used for record field names only. diff --git a/ghc/compiler/rename/RnExpr.lhs b/ghc/compiler/rename/RnExpr.lhs index 4a7bd2283b1856977036d7679b96bf1c7f64b4e9..5d9092b330d5bda6a2c7afc972646dbb52b34960 100644 --- a/ghc/compiler/rename/RnExpr.lhs +++ b/ghc/compiler/rename/RnExpr.lhs @@ -26,11 +26,11 @@ import RnHsSyn import RnMonad import RnEnv import CmdLineOpts ( opt_GlasgowExts ) -import BasicTypes ( Fixity(..), FixityDirection(..) ) +import BasicTypes ( Fixity(..), FixityDirection(..), IfaceFlavour(..) ) import PrelInfo ( numClass_RDR, fractionalClass_RDR, eqClass_RDR, ccallableClass_RDR, creturnableClass_RDR, monadZeroClass_RDR, enumClass_RDR, ordClass_RDR, - ratioDataCon_RDR, negate_RDR, + ratioDataCon_RDR, negate_RDR, assert_RDR, ioDataCon_RDR, ioOkDataCon_RDR ) import TysPrim ( charPrimTyCon, addrPrimTyCon, intPrimTyCon, @@ -248,10 +248,24 @@ free-var set iff if it's a LocallyDefined Name. rnExpr :: RdrNameHsExpr -> RnMS s (RenamedHsExpr, FreeVars) rnExpr (HsVar v) - = lookupOccRn v `thenRn` \ vname -> - returnRn (HsVar vname, if isLocallyDefined vname - then unitNameSet vname - else emptyUniqSet) + = tryLookupOccRn v `thenRn` \ res -> + case res of + Left (nm,err) + | opt_GlasgowExts && v == assertRdrName -> + -- if `assert' is not in scope, + -- we expand it to (GHCerr.assert__ location) + mkAssertExpr `thenRn` \ (expr, assert_name) -> + returnRn (expr, unitNameSet assert_name) + + | otherwise -> -- a failure after all. + failWithRn nm err `thenRn_` + returnRn (HsVar nm, if isLocallyDefined nm + then unitNameSet nm + else emptyUniqSet) + Right vname -> + returnRn (HsVar vname, if isLocallyDefined vname + then unitNameSet vname + else emptyUniqSet) rnExpr (HsLit lit) = litOccurrence lit `thenRn_` @@ -711,6 +725,31 @@ litOccurrence (HsLitLit _) = lookupImplicitOccRn ccallableClass_RDR \end{code} +%************************************************************************ +%* * +\subsubsection{Assertion utils} +%* * +%************************************************************************ + +\begin{code} +mkAssertExpr :: RnMS s (RenamedHsExpr, Name) +mkAssertExpr = + newImportedGlobalName mod occ HiFile `thenRn` \ name -> + addOccurrenceName name `thenRn_` + getSrcLocRn `thenRn` \ sloc -> + let + expr = HsApp (HsVar name) + (HsLit (HsString (_PK_ (showSDoc (ppr sloc))))) + in + returnRn (expr, name) + + where + mod = rdrNameModule assert_RDR + occ = rdrNameOcc assert_RDR + +assertRdrName :: RdrName +assertRdrName = Unqual (VarOcc SLIT("assert")) +\end{code} %************************************************************************ %* *