[GHC] #11371: Bogus in-scope set in substitutions
GHC
ghc-devs at haskell.org
Thu Jan 7 14:17:12 UTC 2016
#11371: Bogus in-scope set in substitutions
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner:
Type: bug | Status: new
Priority: high | Milestone: 8.2.1
Component: Compiler | Version: 7.10.3
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
Bartosz [https://mail.haskell.org/pipermail/ghc-
devs/2016-January/010892.html reports] that substitution isn't working
properly for him. He cites this Note in `TyCoRep`:
{{{
-- Note [Generating the in-scope set for a substitution]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- If we want to substitute [a -> ty1, b -> ty2] I used to
-- think it was enough to generate an in-scope set that includes
-- fv(ty1,ty2). But that's not enough; we really should also take the
-- free vars of the type we are substituting into! Example:
-- (forall b. (a,b,x)) [a -> List b]
-- Then if we use the in-scope set {b}, there is a danger we will rename
-- the forall'd variable to 'x' by mistake, getting this:
-- (forall x. (List b, x, x))
-- Urk! This means looking at all the calls to mkOpenTCvSubst....
}}}
I think this is an outright bug that has been lurking for ages, and which
Bartosz has just managed to tickle.
Things to do:
* We should add an ASSERT to substTy (and similar functions): **when
calling `substTy subst ty` it should be the case that the in-scope set in
the substitution is a superset of**
* **The free vars of the range of the substitution**
* **The free vars of ty minus the domain of the substitution**
That ASSERT could be added to the immediate callers of `subst_ty` in
`TyCoRep`.
(Bartosz: if you add that you should find that it trips before the bug
you are actually getting.)
* How to fix it properly? The places to look are: everywhere that uses
(transitively) one of the `mkOpenTCvSubst` or `zipOpenTCvSubst` functions.
* Many calls to `mkOpenTCvSubst` produce a substitution that is only
applied to closed types; or at least to types whose only free variables
are the ones in the domain of the substitution. Example: the call to
`zipOpenTCvSubst` in `DataCon.dataConInstSig`. These ones will all
satisfy the ASSERT[[BR]][[BR]]
* In other cases, we already have the in-scope set in hand. Example: in
`CoreLint.lintTyApp` we find a call to `substTyWith`. But Lint carries an
in-scope set, so it would be easy to pass it to `substTyWith`.[[BR]][[BR]]
* Finally there may be cases where we really have to take the free vars
of the type we are substituting into, and add them to the in-scope set.
Doubtless all this applies to substituting in coercions too, and indeed
into expressions.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11371>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list