Using a debug enabled build to compile nofib revealed some warnings.
Summary
I built nofib with a debug enabled GHC and got large amount of warnings of the sort below.
WARNING: file compiler\\coreSyn\\CoreSubst.hs, line 254
CoreSubst.lookupIdSubst CSE.lookupSubst f_f_main_combine_classifications
InScope {wild_X1E a_f_Csg__l_a27P a_f_Csg__op_a27Q a_f_Csg__r_a27R
f_f_StandardXfer_skipwhitespace_a4Qd f_f_main_prune_hs
f_f_main_merge_subtrees f_foldl f_f_Gd_map_GDTtraverse_s8c2
f_f_Gd_map_Gdt2Create_s8c8 f_f_Csg_CSGtraverse_2_s8ct
$sreadEither_s90w lvl_s90B $wf_splitwhile_s9TP
$wf_f_Misc_getstring_s9TZ $wf_f_main_prune_hs_s9Uw lvl_safk
lvl_safl sc_sapM sc_sapN sc_sapO sc_sapP sc_sapQ
$sf_f_Csg_CSGtraverse_2_saq8 $sf_f_Gd_map_Gdt2Create_saqB
$sf_f_Gd_map_GDTtraverse_saqQ $s$wf_splitwhile_sar7
$s$wf_splitwhile_sar8 $sf_foldl_saru}
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler\utils\Outputable.hs:1248:29 in ghc:Outputable
warnPprTrace, called at compiler\\coreSyn\\CoreSubst.hs:253:18 in ghc:CoreSubst
This originates from this code:
-- | Find the substitution for an 'Id' in the 'Subst'
lookupIdSubst :: SDoc -> Subst -> Id -> CoreExpr
lookupIdSubst doc (Subst in_scope ids _ _) v
| not (isLocalId v) = Var v
| Just e <- lookupVarEnv ids v = e
| Just v' <- lookupInScope in_scope v = Var v'
-- Vital! See Note [Extending the Subst]
| otherwise = WARN( True, text "CoreSubst.lookupIdSubst" <+> doc <+> ppr v
$$ ppr in_scope)
Var v
Here is the related Note:
Note [Extending the Subst]
~~~~~~~~~~~~~~~~~~~~~~~~~~
For a core Subst, which binds Ids as well, we make a different choice for Ids
than we do for TyVars.
For TyVars, see Note [Extending the TCvSubst] in TyCoSubst.
For Ids, we have a different invariant
The IdSubstEnv is extended *only* when the Unique on an Id changes
Otherwise, we just extend the InScopeSet
In consequence:
* If all subst envs are empty, substExpr would be a
no-op, so substExprSC ("short cut") does nothing.
However, substExpr still goes ahead and substitutes. Reason: we may
want to replace existing Ids with new ones from the in-scope set, to
avoid space leaks.
* In substIdBndr, we extend the IdSubstEnv only when the unique changes
* If the CvSubstEnv, TvSubstEnv and IdSubstEnv are all empty,
substExpr does nothing (Note that the above rule for substIdBndr
maintains this property. If the incoming envts are both empty, then
substituting the type and IdInfo can't change anything.)
* In lookupIdSubst, we *must* look up the Id in the in-scope set, because
it may contain non-trivial changes. Example:
(/\a. \x:a. ...x...) Int
We extend the TvSubstEnv with [a |-> Int]; but x's unique does not change
so we only extend the in-scope set. Then we must look up in the in-scope
set when we find the occurrence of x.
* The requirement to look up the Id in the in-scope set means that we
must NOT take no-op short cut when the IdSubst is empty.
We must still look up every Id in the in-scope set.
* (However, we don't need to do so for expressions found in the IdSubst
itself, whose range is assumed to be correct wrt the in-scope set.)
Why do we make a different choice for the IdSubstEnv than the
TvSubstEnv and CvSubstEnv?
* For Ids, we change the IdInfo all the time (e.g. deleting the
unfolding), and adding it back later, so using the TyVar convention
would entail extending the substitution almost all the time
* The simplifier wants to look up in the in-scope set anyway, in case it
can see a better unfolding from an enclosing case expression
* For TyVars, only coercion variables can possibly change, and they are
easy to spot
Steps to reproduce
Build nofib with a compiler enabling warnPprTrace
.
Expected behavior
With such a large amount of warnings I suspect the warning is either obsolete or indicates some misuse of the substitutions.
Environment
- GHC version used: HEAD