Skip to content

Type synonyms to UniqFM causing accepting buggy programs

I recently wrote this buggy code:

    go_binds :: NameEnv TyThing -> CoreBind -> (NameEnv TyThing, CoreBind)
    go_binds env (NonRec b e)
      = (env `delVarEnv` b, NonRec b (go env e))

Here b :: Id and NameEnv is a map Name -> TyThing, so this code is buggy becuase I'm deleting an Id from a Name map using a wrong function. The operation is defined like this:

delVarEnv :: VarEnv a -> Var -> VarEnv a

So it doesn't sound unreasonable to expect this to fail becuase I'm passing a NameEnv to a function that expects a VarEnv, but because both VarEnv and NameEnv are defined as type synonyms to UniqFM

-- NameEnv.hs
type NameEnv a = UniqFM a       -- Domain is Name

-- VarEnv.hs
type VarEnv elt     = UniqFM elt

this code compiles and does the wrong thing in runtime.

I think it'd be better to define these type synonyms as newtypes.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information