Note [Handling overloaded and rebindable constructs]
Nomenclature
* Expansion (`HsExpr GhcRn -> HsExpr GhcRn`): expand between renaming and
typechecking, using the `XXExprGhcRn` constructor of `HsExpr`.
* Desugaring (`HsExpr GhcTc -> Core.Expr`): convert the typechecked `HsSyn` to Core. This is done in GHC.HsToCore
For overloaded constructs (overloaded literals, lists, strings), and
rebindable constructs (e.g. if-then-else), our general plan is this,
using overloaded labels #foo as an example:
* In the RENAMER: transform
HsOverLabel "foo"
==> XExpr (ExpandedThingRn (HsOverLabel #foo)
(fromLabel `HsAppType` "foo"))
We write this more compactly in concrete-syntax form like this
#foo ==> fromLabel @"foo"
Recall that in (ExpandedThingRn orig expanded), 'orig' is the original term
the user wrote, and 'expanded' is the expanded or desugared version
to be typechecked.
* In the TYPECHECKER: typecheck the expansion, in this case
fromLabel @"foo"
The typechecker (and desugarer) will never see HsOverLabel
In effect, the renamer does a bit of desugaring. Recall GHC.Hs.Expr
Note [Rebindable syntax and XXExprGhcRn], which describes the use of XXExprGhcRn.
RebindableSyntax:
If RebindableSyntax is off we use the built-in 'fromLabel', defined in
GHC.Builtin.Names.fromLabelClassOpName
If RebindableSyntax if ON, we look up "fromLabel" in the environment
to get whichever one is in scope.
This is accomplished by lookupSyntaxName, and it applies to all the
constructs below.
See also Note [Handling overloaded and rebindable patterns] in GHC.Rename.Pat
for the story with patterns.
Here are the expressions that we transform in this way. Some are uniform,
but several have a little bit of special treatment:
* HsIf (if-the-else)
if b then e1 else e2 ==> ifThenElse b e1 e2
We do this /only/ if rebindable syntax is on, because the coverage
checker looks for HsIf (see GHC.HsToCore.Ticks.addTickHsExpr)
That means the typechecker and desugarer need to understand HsIf
for the non-rebindable-syntax case.
* OverLabel (overloaded labels, #lbl)
#lbl ==> fromLabel @"lbl"
As ever, we use lookupSyntaxName to look up 'fromLabel'
See Note [Overloaded labels] below
* ExplicitList (explicit lists [a,b,c])
When (and only when) OverloadedLists is on
[e1,e2] ==> fromListN 2 [e1,e2]
NB: the type checker and desugarer still see ExplicitList,
but to them it always means the built-in lists.
* SectionL and SectionR (left and right sections)
(`op` e) ==> rightSection op e
(e `op`) ==> leftSection (op e)
where `leftSection` and `rightSection` are representation-polymorphic
wired-in Ids. See Note [Left and right sections]
* To understand why expansions for `OpApp` is done in `GHC.Tc.Gen.Head.splitHsApps`
see Note [Doing XXExprGhcRn in the Renamer vs Typechecker] below.
* RecordUpd: we desugar record updates into case expressions,
in GHC.Tc.Gen.Expr.tcExpr.
Example:
data T p q = T1 { x :: Int, y :: Bool, z :: Char }
| T2 { v :: Char }
| T3 { x :: Int }
| T4 { p :: Float, y :: Bool, x :: Int }
| T5
e { x=e1, y=e2 }
===>
let { x' = e1; y' = e2 } in
case e of
T1 _ _ z -> T1 x' y' z
T4 p _ _ -> T4 p y' x'
See Note [Record Updates] in GHC.Tc.Gen.Expr for more details.
To understand Why is this done in the typechecker, and not in the renamer
see Note [Doing XXExprGhcRn in the Renamer vs Typechecker]
* HsDo: We expand `HsDo` statements in `Ghc.Tc.Gen.Do`.
- For example, a user written code:
do { x <- e1 ; g x ; return (f x) }
is expanded to:
(>>=) e1
(\x -> ((>>) (g x)
(return (f x))))
See Note [Expanding HsDo with XXExprGhcRn] in `Ghc.Tc.Gen.Do` for more details.
To understand why is this done in the typechecker and not in the renamer.
See Note [Doing XXExprGhcRn in the Renamer vs Typechecker] References 7
- Rebindable syntax and XXExprGhcRn GHC.Hs.Expr
- Doing XXExprGhcRn in the Renamer vs Typechecker GHC.Rename.Expr
- Left and right sections GHC.Rename.Expr
- Overloaded labels GHC.Rename.Expr
- Handling overloaded and rebindable patterns GHC.Rename.Pat
- Expanding HsDo with XXExprGhcRn GHC.Tc.Gen.Do
- Record Updates GHC.Tc.Gen.Expr
Referenced by 25
- GHC.Hs.Expr call site ×6
- GHC.Rename.Expr call site ×6
- GHC.HsToCore.Expr call site
- Quotation and rebindable syntax GHC.HsToCore.Quote
- Doing XXExprGhcRn in the Renamer vs Typechecker GHC.Rename.Expr
- Handling overloaded and rebindable patterns GHC.Rename.Pat
- GHC.Rename.Pat call site
- GHC.Rename.Utils call site
- Quick Look for particular Ids GHC.Tc.Gen.App
- GHC.Tc.Gen.App call site
- Expanding HsDo with XXExprGhcRn GHC.Tc.Gen.Do
- GHC.Tc.Gen.Do call site
- GHC.Tc.Gen.Expr call site
- Desugar OpApp in the typechecker GHC.Tc.Gen.Head
- Wired-in Ids for rebindable syntax GHC.Types.Id.Make