diff options
author | Georgi Lyubenov <georgi.lyubenov@tweag.io> | 2022-09-09 15:24:03 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-02-21 18:35:56 -0500 |
commit | 172ff88fcac864a029d1cf77fbbe04c7a969d70d (patch) | |
tree | b13fbd18eea3ed72ba41b9ff825dc46836fc7f73 /compiler/GHC/Rename/Env.hs | |
parent | 8e765affde37197a6ebc174653171195fcc53003 (diff) | |
download | haskell-172ff88fcac864a029d1cf77fbbe04c7a969d70d.tar.gz |
GHC proposal 496 - Nullary record wildcards
This patch implements GHC proposal 496, which allows record wildcards
to be used for nullary constructors, e.g.
data A = MkA1 | MkA2 { fld1 :: Int }
f :: A -> Int
f (MkA1 {..}) = 0
f (MkA2 {..}) = fld1
To achieve this, we add arity information to the record field
environment, so that we can accept a constructor which has no fields
while continuing to reject non-record constructors with more than 1
field. See Note [Nullary constructors and empty record wildcards],
as well as the more general overview in Note [Local constructor info in the renamer],
both in the newly introduced GHC.Types.ConInfo module.
Fixes #22161
Diffstat (limited to 'compiler/GHC/Rename/Env.hs')
-rw-r--r-- | compiler/GHC/Rename/Env.hs | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/compiler/GHC/Rename/Env.hs b/compiler/GHC/Rename/Env.hs index ec423d0087..830e1a0dcc 100644 --- a/compiler/GHC/Rename/Env.hs +++ b/compiler/GHC/Rename/Env.hs @@ -36,7 +36,7 @@ module GHC.Rename.Env ( lookupSigCtxtOccRn, lookupSigCtxtOccRnN, lookupInstDeclBndr, lookupFamInstName, - lookupConstructorFields, + lookupConstructorInfo, lookupConstructorFields, lookupGreAvailRn, @@ -105,6 +105,7 @@ import GHC.Types.FieldLabel import GHC.Data.Bag import GHC.Types.PkgQual import Language.Haskell.Syntax.Basic (FieldLabelString(..)) +import GHC.Types.ConInfo (ConInfo, conInfoFields, mkConInfo) {- ********************************************************* @@ -399,27 +400,34 @@ lookupFamInstName (Just cls) tc_rdr -- Associated type; c.f GHC.Rename.Bind.rnM lookupFamInstName Nothing tc_rdr -- Family instance; tc_rdr is an *occurrence* = lookupLocatedOccRnConstr tc_rdr ------------------------------------------------ -lookupConstructorFields :: Name -> RnM [FieldLabel] --- Look up the fields of a given constructor +lookupConstructorInfo :: Name -> RnM ConInfo +-- Look up the info for a given constructor -- * For constructors from this module, use the record field env, -- which is itself gathered from the (as yet un-typechecked) -- data type decls +-- For more details, see Note [Local constructor info in the renamer] -- -- * For constructors from imported modules, use the *type* environment -- since imported modules are already compiled, the info is conveniently -- right there -lookupConstructorFields con_name +lookupConstructorInfo con_name = do { this_mod <- getModule ; if nameIsLocalOrFrom this_mod con_name then - do { field_env <- getRecFieldEnv - ; traceTc "lookupCF" (ppr con_name $$ ppr (lookupNameEnv field_env con_name) $$ ppr field_env) - ; return (lookupNameEnv field_env con_name `orElse` []) } + do { con_env <- getConEnv + ; let conInfo = lookupNameEnv con_env con_name + ; traceTc "lookupCF" (ppr con_name $$ ppr conInfo $$ ppr con_env) + -- we always info for all the constructors in the current module in GHC.Rename.mk_con_env + -- hence we should be able to look up the constructor in tcg_con_env if it's from the current module + ; return (conInfo `orElse` panic "GHC.Rename.Env.lookupConstructorInfo") } else do { con <- tcLookupConLike con_name ; traceTc "lookupCF 2" (ppr con) - ; return (conLikeFieldLabels con) } } + ; pure $ mkConInfo (conLikeArity con) (conLikeFieldLabels con) } } + +----------------------------------------------- +lookupConstructorFields :: Name -> RnM [FieldLabel] +lookupConstructorFields = fmap conInfoFields . lookupConstructorInfo -- In CPS style as `RnM r` is monadic |