NameShape

ghc-8.4.4: The GHC API

Safe Haskell | None
Language | Haskell2010

NameShape

Synopsis

- data NameShape = NameShape {
  - ns_mod_name :: ModuleName
  - ns_exports :: [AvailInfo]
  - ns_map :: OccEnv Name
  }
- emptyNameShape :: ModuleName -> NameShape
- mkNameShape :: ModuleName -> [AvailInfo] -> NameShape
- extendNameShape :: HscEnv -> NameShape -> [AvailInfo] -> IO (Either SDoc NameShape)
- nameShapeExports :: NameShape -> [AvailInfo]
- substNameShape :: NameShape -> Name -> Name
- maybeSubstNameShape :: NameShape -> Name -> Maybe Name

# Documentation

data NameShape #

A `NameShape` is a substitution on `Name`s that can be used to refine the identities of a hole while we are renaming interfaces (see `RnModIface`). Specifically, a `NameShape` for `ns_module_name` `A`, defines a mapping from `{A.T}` (for some `OccName` `T`) to some arbitrary other `Name`.

The most intruiging thing about a `NameShape`, however, is how it's constructed. A `NameShape` is *implied* by the exported `AvailInfo`s of the implementor of an interface: if an implementor of signature `H` exports `M.T`, you implicitly define a substitution from `{H.T}` to `M.T`. So a `NameShape` is computed from the list of `AvailInfo`s that are exported by the implementation of a module, or successively merged together by the export lists of signatures which are joining together.

It's not the most obvious way to go about doing this, but it does seem to work!

NB: Can't boot this and put it in NameShape because then we start pulling in too many DynFlags things.

Constructors

NameShape |
Fields ns_mod_name :: ModuleName ns_exports :: [AvailInfo] ns_map :: OccEnv Name

emptyNameShape :: ModuleName -> NameShape #

Create an empty `NameShape` (i.e., the renaming that would occur with an implementing module with no exports) for a specific hole `mod_name`.

mkNameShape :: ModuleName -> [AvailInfo] -> NameShape #

Create a `NameShape` corresponding to an implementing module for the hole `mod_name` that exports a list of `AvailInfo`s.

extendNameShape :: HscEnv -> NameShape -> [AvailInfo] -> IO (Either SDoc NameShape) #

Given an existing `NameShape`, merge it with a list of `AvailInfo`s with Backpack style mix-in linking. This is used solely when merging signatures together: we successively merge the exports of each signature until we have the final, full exports of the merged signature.

What makes this operation nontrivial is what we are supposed to do when we want to merge in an export for M.T when we already have an existing export {H.T}. What should happen in this case is that {H.T} should be unified with `M.T`: we've determined a more *precise* identity for the export at `OccName` `T`.

Note that we don't do unrestricted unification: only name holes from `ns_mod_name ns` are flexible. This is because we have a much more restricted notion of shaping than in Backpack'14: we do shaping *as* we do type-checking. Thus, once we shape a signature, its exports are *final* and we're not allowed to refine them further,

nameShapeExports :: NameShape -> [AvailInfo] #

The export list associated with this `NameShape` (i.e., what the exports of an implementing module which induces this `NameShape` would be.)

substNameShape :: NameShape -> Name -> Name #

Given a `Name`, substitute it according to the `NameShape` implied substitution, i.e. map `{A.T}` to `M.T`, if the implementing module exports `M.T`.

maybeSubstNameShape :: NameShape -> Name -> Maybe Name #

Like `substNameShape`, but returns `Nothing` if no substitution works.