Note [Desugaring non-canonical evidence]
When constructing an application
f @ty1 ty2 .. dict1 dict2 .. arg1 arg2 ..
if the evidence `dict_i` is canonical, we simply build that application.
But if any of the `dict_i` are /non-canonical/, we wrap the application
in `nospec`, thus
nospec @fty f @ty1 @ty2 .. dict1 dict2 .. arg1 arg2 ..
where nospec :: forall a. a -> a ensures that the typeclass specialiser
doesn't attempt to common up this evidence term with other evidence terms
of the same type (see Note [nospecId magic] in GHC.Types.Id.Make).
See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv for
what a "non-canonical" dictionary is, and whe shouldn't specialise on it.
How do we decide if the arguments are non-canonical dictionaries?
* In `ds_app_finish` we look for dictionary arguments (invisible value args)
* In the DsM monad we track the "unspecables" (i.e. non-canonical dictionaries)
in the `dsl_unspecable` field of `DsLclEnv`
* We extend that unspecable set via `addUnspecables`, in `dsEvBinds`.
A dictionary is non-canonical if its own resolution was incoherent (see
Note [Incoherent instances]), or if its definition refers to other non-canonical
evidence. `dsEvBinds` is the convenient place to compute this, since it already
needs to do inter-evidence dependency analysis to generate well-scoped
bindings.
Wrinkle:
(NC1) We don't do this in the LHS of a RULE. In particular, if we have
f :: (Num a, HasCallStack) => a -> a
{-# SPECIALISE f :: Int -> Int # References 3
- Coherence and specialisation: overview GHC.Core.InstEnv
- Incoherent instances GHC.Core.InstEnv
- nospecId magic GHC.Types.Id.Make
Referenced by 6
- GHC.Core.InstEnv call site
- GHC.HsToCore call site
- GHC.HsToCore.Binds call site
- GHC.HsToCore.Expr call site
- GHC.HsToCore.Types call site
- GHC.Tc.Types.Evidence call site