-
036c9e62
by Zubin Duggal at 2026-08-21T14:03:40+05:30
An abstract TyCon may hide a unary class
A class declared in an hs-boot file is an AbstractTyCon inside the
module loop, and compiling the real declaration may reveal it to be a
UnaryClassTyCon.
- isTerminatingType returned True for such AbstractTyCons
- IfaceToCore set the unary flag to False in the DFunId
So we could end up speculating bottom dictionaries because inside a module
loop we see an UnaryClassTyCon as an AbstractTyCon
Use mayBeUnaryClassTyCon instead of isUnaryClassTyCon, which returns True for an
abstract TyCon.
Fixes #27704
-
11e617d0
by Zubin Duggal at 2026-08-21T14:03:40+05:30
Specialise: don't drop a dead arg that the stable unfolding uses
specHeader decides an argument is dead by calling isDeadBinder on a binder of
the /optimised RHS/, then applies the filler to the /stable unfolding/
template instead. The two may differ, so the argument can be dead in
the RHS and not in the template.
The specialised function's unfolding then has an absent filler, and any call
site that inlines it evaluates the error thunk.
Thread the template's binders through specHeader alongside the RHS
binders and make a filler only when the argument is dead in both.
See Note [Dead args and stable unfoldings].
Fixes #27703
-
13fe1031
by Zubin Duggal at 2026-08-21T14:03:41+05:30
Never make an absent filler at a constraint type,
isDictTy doesn't catch constraints hidden behind unreduced type family applications
Example:
type family F a :: Constraint
type instance F W = TC W
a :: F W => Int -> Int -- (F W) argument is absent
Oops! Entered absent arg Arg: irred
Type: F W
also in the test T27627f
Use `ConstraintLike <- typeTypeOrConstraint arg_ty` instead???
-
14d04e9b
by Zubin Duggal at 2026-08-21T14:03:41+05:30
CorePrep: don't speculate a call across an hs-boot edge
We take care not to evaluate things that might be bottom, like a
looping dictionary group, but our analysis is defeated by boot files.
We only track recursion within a module, so two dictionaries that
depend on each other across a module loop each look non-recursive, and
we might speculate them.
Any recursion we cannot see must cross an hs-boot edge, so refuse to
speculate calls that cross one.
Fixes #27717