[GHC] #13959: substTyVar's definition is highly dubious
GHC
ghc-devs at haskell.org
Thu Jul 20 08:35:29 UTC 2017
#13959: substTyVar's definition is highly dubious
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: (none)
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Compiler | Version: 8.0.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D3732
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
> Who arranges for the members of the in-scope set to have substituted
kinds?
Well, if the in-scope set comes from the context (as in the simplifier or
other places) all the `Var`s in the in-scope set are `OutIds`; that is,
fully substituted. It would be wrong to substitute again, because it's
entirely OK to have a substitution that goes `a :-> [a]`, because the LHS
is `InVars` and the RHS is `OutVaers`. (This is not true during
unification of course, but that's entirely separate.)
E.g. a substitution [a :-> Proxy k (b::k), k :-> *] really means
"replace `a` by `Proxy k (b::k)`" and NOT "then apply the subsituton to
the result to get `Proxy * (b::*)`. No no no. Substitutions apply
exactly once.
(In this example the `k` in `Proxy k (b::k)` is an `OutTyVar` whereas the
`k` in `k :-> *` is an `InTyVar`.)
What if we build the in-scope set by taking the free vars of the range of
the substitution? Eg.
{{{
Substitute [a :-> Proxy k (b::k)]
in the type (a, b)
}}}
The in-scope set, from the range of the substitution, is {b,k}. Do we
need to apply the substitution to {b}? No! The range of the substitution
is `OutVars` so we must not apply the substitution to it.
A more delicate point is this: what if we build (part of) the in-scope set
by taking the free vars of the type being substituted (see
`substTyAddInScope` and `Note [The substitution invariant]` in`TyCoRep`?
That's an `InType`! eg
{{{
Substitute [a :-> Int]
in the type (a, b::k)
}}}
Now we get an in-scope set of `{b::k}`. But although `b` appears in an
`InType`, it must be an `OutTyVar` precisely because it is not
substituted. It must be bound somewhere outside, and it'd be wrong to
substitute its kind at one of its occurrences and not at its binding site!
So I think everything is fine. But I really wish I had a clearer way to
explain WHY it is fine.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13959#comment:9>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list