Skip to content
Snippets Groups Projects
Commit 4d2ee313 authored by Sebastian Graf's avatar Sebastian Graf
Browse files

Specialising through specialised method calls (#19644)

In #19644, we discovered that the ClassOp/DFun rules from
Note [ClassOp/DFun selection] inhibit transitive specialisation in a scenario
like
```
class C a where m :: Show b => a -> b -> ...; n :: ...
instance C Int where m = ... -- $cm :: Show b => Int -> b -> ...
f :: forall a b. (C a, Show b) => ...
f $dC $dShow = ... m @a $dC @b $dShow ...
main = ... f @Int @Bool ...
```
After we specialise `f` for `Int`, we'll see `m @a $dC @b $dShow` in the body of
`$sf`. But before this patch, Specialise doesn't apply the ClassOp/DFun rule to
rewrite to a call of the instance method for `C Int`, e.g., `$cm @Bool $dShow`.
As a result, Specialise couldn't further specialise `$cm` for `Bool`.

There's a better example in `Note [Specialisation modulo dictionary selectors]`.

This patch enables proper Specialisation, as follows:

1. In the App case of `specExpr`, try to apply the CalssOp/DictSel rule on the
   head of the application
2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and
   `$dShow` in `bindAuxiliaryDict`

NB: Without (2), (1) would be pointless, because `lookupRule` wouldn't be able
to look into the RHS of `$dC` to see the DFun.

(2) triggered #21332, because the Specialiser floats around dictionaries without
accounting for them in the `SpecEnv`'s `InScopeSet`, triggering a panic when
rewriting dictionary unfoldings.

Fixes #19644 and #21332.
parent 0090ad7b
No related branches found
No related tags found
Loading
Showing
with 1184 additions and 90 deletions
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment