ghc-7.10.3: The GHC API

Safe Haskell | None
Language | Haskell2010

RdrName

Contents

- The main type
  - Construction
  - Destruction
- Local mapping of `RdrName` to `Name`
- Global mapping of `RdrName` to `GlobalRdrElt`s
- GlobalRdrElts
  - Global `RdrName` mapping elements: `GlobalRdrElt`, `Provenance`, `ImportSpec`

Description

GHC uses several kinds of name internally:

- `OccName`: see OccName
- `RdrName` is the type of names that come directly from the parser. They have not yet had their scoping and binding resolved by the renamer and can be thought of to a first approximation as an `OccName` with an optional module qualifier
- `Name`: see Name
- `Id`: see Id
- `Var`: see Var

Synopsis

- data RdrName
  - = Unqual OccName
  - | Qual ModuleName OccName
  - | Orig Module OccName
  - | Exact Name
- mkRdrUnqual :: OccName -> RdrName
- mkRdrQual :: ModuleName -> OccName -> RdrName
- mkUnqual :: NameSpace -> FastString -> RdrName
- mkVarUnqual :: FastString -> RdrName
- mkQual :: NameSpace -> (FastString, FastString) -> RdrName
- mkOrig :: Module -> OccName -> RdrName
- nameRdrName :: Name -> RdrName
- getRdrName :: NamedThing thing => thing -> RdrName
- rdrNameOcc :: RdrName -> OccName
- rdrNameSpace :: RdrName -> NameSpace
- setRdrNameSpace :: RdrName -> NameSpace -> RdrName
- demoteRdrName :: RdrName -> Maybe RdrName
- isRdrDataCon :: RdrName -> Bool
- isRdrTyVar :: RdrName -> Bool
- isRdrTc :: RdrName -> Bool
- isQual :: RdrName -> Bool
- isQual_maybe :: RdrName -> Maybe (ModuleName, OccName)
- isUnqual :: RdrName -> Bool
- isOrig :: RdrName -> Bool
- isOrig_maybe :: RdrName -> Maybe (Module, OccName)
- isExact :: RdrName -> Bool
- isExact_maybe :: RdrName -> Maybe Name
- isSrcRdrName :: RdrName -> Bool
- data LocalRdrEnv
- emptyLocalRdrEnv :: LocalRdrEnv
- extendLocalRdrEnv :: LocalRdrEnv -> Name -> LocalRdrEnv
- extendLocalRdrEnvList :: LocalRdrEnv -> [Name] -> LocalRdrEnv
- lookupLocalRdrEnv :: LocalRdrEnv -> RdrName -> Maybe Name
- lookupLocalRdrOcc :: LocalRdrEnv -> OccName -> Maybe Name
- elemLocalRdrEnv :: RdrName -> LocalRdrEnv -> Bool
- inLocalRdrEnvScope :: Name -> LocalRdrEnv -> Bool
- localRdrEnvElts :: LocalRdrEnv -> [Name]
- delLocalRdrEnvList :: LocalRdrEnv -> [OccName] -> LocalRdrEnv
- type GlobalRdrEnv = OccEnv [GlobalRdrElt]
- emptyGlobalRdrEnv :: GlobalRdrEnv
- mkGlobalRdrEnv :: [GlobalRdrElt] -> GlobalRdrEnv
- plusGlobalRdrEnv :: GlobalRdrEnv -> GlobalRdrEnv -> GlobalRdrEnv
- lookupGlobalRdrEnv :: GlobalRdrEnv -> OccName -> [GlobalRdrElt]
- extendGlobalRdrEnv :: Bool -> GlobalRdrEnv -> [AvailInfo] -> GlobalRdrEnv
- pprGlobalRdrEnv :: Bool -> GlobalRdrEnv -> SDoc
- globalRdrEnvElts :: GlobalRdrEnv -> [GlobalRdrElt]
- lookupGRE_RdrName :: RdrName -> GlobalRdrEnv -> [GlobalRdrElt]
- lookupGRE_Name :: GlobalRdrEnv -> Name -> [GlobalRdrElt]
- getGRE_NameQualifier_maybes :: GlobalRdrEnv -> Name -> [Maybe [ModuleName]]
- transformGREs :: (GlobalRdrElt -> GlobalRdrElt) -> [OccName] -> GlobalRdrEnv -> GlobalRdrEnv
- findLocalDupsRdrEnv :: GlobalRdrEnv -> [Name] -> [[GlobalRdrElt]]
- pickGREs :: RdrName -> [GlobalRdrElt] -> [GlobalRdrElt]
- gresFromAvails :: Provenance -> [AvailInfo] -> [GlobalRdrElt]
- gresFromAvail :: (Name -> Provenance) -> AvailInfo -> [GlobalRdrElt]
- data GlobalRdrElt = GRE {
  - gre_name :: Name
  - gre_par :: Parent
  - gre_prov :: Provenance
  }
- isLocalGRE :: GlobalRdrElt -> Bool
- unQualOK :: GlobalRdrElt -> Bool
- qualSpecOK :: ModuleName -> ImportSpec -> Bool
- unQualSpecOK :: ImportSpec -> Bool
- data Provenance
  - = LocalDef
  - | Imported [ImportSpec]
- pprNameProvenance :: GlobalRdrElt -> SDoc
- data Parent
  - = NoParent
  - | ParentIs Name
- data ImportSpec = ImpSpec {
  - is_decl :: ImpDeclSpec
  - is_item :: ImpItemSpec
  }
- data ImpDeclSpec = ImpDeclSpec {
  - is_mod :: ModuleName
  - is_as :: ModuleName
  - is_qual :: Bool
  - is_dloc :: SrcSpan
  }
- data ImpItemSpec
  - = ImpAll
  - | ImpSome {
    - is_explicit :: Bool
    - is_iloc :: SrcSpan
    }
- importSpecLoc :: ImportSpec -> SrcSpan
- importSpecModule :: ImportSpec -> ModuleName
- isExplicitItem :: ImpItemSpec -> Bool

# The main type

data RdrName

Do not use the data constructors of RdrName directly: prefer the family of functions that creates them, such as `mkRdrUnqual`

- Note: A Located RdrName will only have API Annotations if it is a compound one, e.g.

    `bar`
    ( ~ )

- `AnnKeywordId` : `AnnType`, `AnnOpen` `'('` or `'['` or `'[:'`, `AnnClose` `')'` or `']'` or `':]'`,, `AnnBackquote` `'`'`, `AnnVal`,`AnnTildehsh`, `AnnTilde`,

Constructors

Unqual OccName | Used for ordinary, unqualified occurrences, e.g. `x`, `y` or `Foo`. Create such a `RdrName` with `mkRdrUnqual`
Qual ModuleName OccName | A qualified name written by the user in source code. The module isn't necessarily the module where the thing is defined; just the one from which it is imported. Examples are `Bar.x`, `Bar.y` or `Bar.Foo`. Create such a `RdrName` with `mkRdrQual`
Orig Module OccName | An original name; the module is the defining module. This is used when GHC generates code that will be fed into the renamer (e.g. from deriving clauses), but where we want to say "Use Prelude.map dammit". One of these can be created with `mkOrig`

Exact Name

We know exactly the `Name`. This is used:

1. When the parser parses built-in syntax like `[]` and `(,)`, but wants a `RdrName` from it
2. By Template Haskell, when TH has generated a unique name

Such a `RdrName` can be created by using `getRdrName` on a `Name`

Instances

Eq RdrName |
Data RdrName |
Ord RdrName |
OutputableBndr RdrName |
Outputable RdrName |
HasOccName RdrName |
type PostRn RdrName ty = PlaceHolder |
type PostTc RdrName ty = PlaceHolder |

## Construction

mkRdrUnqual :: OccName -> RdrName

mkRdrQual :: ModuleName -> OccName -> RdrName

mkUnqual :: NameSpace -> FastString -> RdrName

mkVarUnqual :: FastString -> RdrName

mkQual :: NameSpace -> (FastString, FastString) -> RdrName

Make a qualified `RdrName` in the given namespace and where the `ModuleName` and the `OccName` are taken from the first and second elements of the tuple respectively

mkOrig :: Module -> OccName -> RdrName

nameRdrName :: Name -> RdrName

getRdrName :: NamedThing thing => thing -> RdrName

## Destruction

rdrNameOcc :: RdrName -> OccName

rdrNameSpace :: RdrName -> NameSpace

setRdrNameSpace :: RdrName -> NameSpace -> RdrName

This rather gruesome function is used mainly by the parser. When parsing:

    data T a = T | T1 Int

we parse the data constructors as types because of parser ambiguities, so then we need to change the type constr to a data constr

The exact-name case can occur when parsing:

    data [] a = [] | a : [a]

For the exact-name case we return an original name.

demoteRdrName :: RdrName -> Maybe RdrName

isRdrDataCon :: RdrName -> Bool

isRdrTyVar :: RdrName -> Bool

isRdrTc :: RdrName -> Bool

isQual :: RdrName -> Bool

isQual_maybe :: RdrName -> Maybe (ModuleName, OccName)

isUnqual :: RdrName -> Bool

isOrig :: RdrName -> Bool

isOrig_maybe :: RdrName -> Maybe (Module, OccName)

isExact :: RdrName -> Bool

isExact_maybe :: RdrName -> Maybe Name

isSrcRdrName :: RdrName -> Bool

# Local mapping of `RdrName` to `Name`

data LocalRdrEnv

This environment is used to store local bindings (`let`, `where`, lambda, `case`). It is keyed by OccName, because we never use it for qualified names We keep the current mapping, *and* the set of all Names in scope Reason: see Note [Splicing Exact Names] in RnEnv

Instances

Outputable LocalRdrEnv |

emptyLocalRdrEnv :: LocalRdrEnv

extendLocalRdrEnv :: LocalRdrEnv -> Name -> LocalRdrEnv

extendLocalRdrEnvList :: LocalRdrEnv -> [Name] -> LocalRdrEnv

lookupLocalRdrEnv :: LocalRdrEnv -> RdrName -> Maybe Name

lookupLocalRdrOcc :: LocalRdrEnv -> OccName -> Maybe Name

elemLocalRdrEnv :: RdrName -> LocalRdrEnv -> Bool

inLocalRdrEnvScope :: Name -> LocalRdrEnv -> Bool

localRdrEnvElts :: LocalRdrEnv -> [Name]

delLocalRdrEnvList :: LocalRdrEnv -> [OccName] -> LocalRdrEnv

# Global mapping of `RdrName` to `GlobalRdrElt`s

type GlobalRdrEnv = OccEnv [GlobalRdrElt]

Keyed by `OccName`; when looking up a qualified name we look up the `OccName` part, and then check the `Provenance` to see if the appropriate qualification is valid. This saves routinely doubling the size of the env by adding both qualified and unqualified names to the domain.

The list in the codomain is required because there may be name clashes These only get reported on lookup, not on construction

INVARIANT: All the members of the list have distinct `gre_name` fields; that is, no duplicate Names

INVARIANT: Imported provenance => Name is an ExternalName However LocalDefs can have an InternalName. This happens only when type-checking a [d| ... |] Template Haskell quotation; see this note in RnNames Note [Top-level Names in Template Haskell decl quotes]

emptyGlobalRdrEnv :: GlobalRdrEnv

mkGlobalRdrEnv :: [GlobalRdrElt] -> GlobalRdrEnv

plusGlobalRdrEnv :: GlobalRdrEnv -> GlobalRdrEnv -> GlobalRdrEnv

lookupGlobalRdrEnv :: GlobalRdrEnv -> OccName -> [GlobalRdrElt]

extendGlobalRdrEnv :: Bool -> GlobalRdrEnv -> [AvailInfo] -> GlobalRdrEnv

pprGlobalRdrEnv :: Bool -> GlobalRdrEnv -> SDoc

globalRdrEnvElts :: GlobalRdrEnv -> [GlobalRdrElt]

lookupGRE_RdrName :: RdrName -> GlobalRdrEnv -> [GlobalRdrElt]

lookupGRE_Name :: GlobalRdrEnv -> Name -> [GlobalRdrElt]

getGRE_NameQualifier_maybes :: GlobalRdrEnv -> Name -> [Maybe [ModuleName]]

transformGREs :: (GlobalRdrElt -> GlobalRdrElt) -> [OccName] -> GlobalRdrEnv -> GlobalRdrEnv

Apply a transformation function to the GREs for these OccNames

findLocalDupsRdrEnv :: GlobalRdrEnv -> [Name] -> [[GlobalRdrElt]]

For each `OccName`, see if there are multiple local definitions for it; return a list of all such and return a list of the duplicate bindings

pickGREs :: RdrName -> [GlobalRdrElt] -> [GlobalRdrElt]

Take a list of GREs which have the right OccName Pick those GREs that are suitable for this RdrName And for those, keep only only the Provenances that are suitable Only used for Qual and Unqual, not Orig or Exact

Consider:

          module A ( f ) where
          import qualified Foo( f )
          import Baz( f )
          f = undefined

Let's suppose that `Foo.f` and `Baz.f` are the same entity really. The export of `f` is ambiguous because it's in scope from the local def and the import. The lookup of `Unqual f` should return a GRE for the locally-defined `f`, and a GRE for the imported `f`, with a single provenance, namely the one for `Baz(f)`.

# GlobalRdrElts

gresFromAvails :: Provenance -> [AvailInfo] -> [GlobalRdrElt]

make a `GlobalRdrEnv` where all the elements point to the same Provenance (useful for "hiding" imports, or imports with no details).

gresFromAvail :: (Name -> Provenance) -> AvailInfo -> [GlobalRdrElt]

## Global `RdrName` mapping elements: `GlobalRdrElt`, `Provenance`, `ImportSpec`

data GlobalRdrElt

An element of the `GlobalRdrEnv`

Constructors

GRE |

Fields

gre_name :: Name
gre_par :: Parent
gre_prov :: Provenance

  Why it's in scope

Instances

Outputable GlobalRdrElt |

isLocalGRE :: GlobalRdrElt -> Bool

unQualOK :: GlobalRdrElt -> Bool

Test if an unqualifed version of this thing would be in scope

qualSpecOK :: ModuleName -> ImportSpec -> Bool

Is in scope qualified with the given module?

unQualSpecOK :: ImportSpec -> Bool

Is in scope unqualified?

data Provenance

The `Provenance` of something says how it came to be in scope. It's quite elaborate so that we can give accurate unused-name warnings.

Constructors

LocalDef | The thing was defined locally
Imported [ImportSpec] | The thing was imported. INVARIANT: the list of `ImportSpec` is non-empty

Instances

Eq Provenance |
Ord Provenance |

pprNameProvenance :: GlobalRdrElt -> SDoc

Print out the place where the name was imported

data Parent

The children of a Name are the things that are abbreviated by the ".." notation in export lists. See Note [Parents]

Constructors

NoParent |
ParentIs Name |

Instances

Eq Parent |
Outputable Parent |

data ImportSpec

Constructors

ImpSpec |

Fields

is_decl :: ImpDeclSpec
is_item :: ImpItemSpec

Instances

Eq ImportSpec |
Ord ImportSpec |
Outputable ImportSpec |

data ImpDeclSpec

Describes a particular import declaration and is shared among all the `Provenance`s for that decl

Constructors

ImpDeclSpec |

Fields

is_mod :: ModuleName

  Module imported, e.g. `import Muggle` Note the `Muggle` may well not be the defining module for this thing!

is_as :: ModuleName

  Import alias, e.g. from `as M` (or `Muggle` if there is no `as` clause)

is_qual :: Bool

  Was this import qualified?

is_dloc :: SrcSpan

  The location of the entire import declaration

Instances

Eq ImpDeclSpec |
Ord ImpDeclSpec |

data ImpItemSpec

Describes import info a particular Name

Constructors

ImpAll | The import had no import list, or had a hiding list

ImpSome

The import had an import list. The `is_explicit` field is `True` iff the thing was named explicitly in the import specs rather than being imported as part of a "..." group. Consider:

    import C( T(..) )

Here the constructors of `T` are not named explicitly; only `T` is named explicitly.

Fields

is_explicit :: Bool
is_iloc :: SrcSpan

Instances

Eq ImpItemSpec |
Ord ImpItemSpec |

importSpecLoc :: ImportSpec -> SrcSpan

importSpecModule :: ImportSpec -> ModuleName

isExplicitItem :: ImpItemSpec -> Bool