Lousy error message for `instance forall c. c`
This erroneous program is rejected with a rather strange error message:
{-# LANGUAGE ScopedTypeVariables #-}
module Bug where
instance forall c. c
$ /opt/ghc/8.6.3/bin/ghc Bug.hs
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
Bug.hs:4:20: error: Not in scope: type variable ‘c’
|
4 | instance forall c. c
| ^
This error message is hogwash, since c is absolutely in scope. The reason GHC believes that c is out of scope is because before GHC renamed the type signature in the instance, it performs a pass over all top-level binders in RnNames.getLocalNonValBinders to obtain their Names. In particular, this is the culprit:
new_assoc overload_ok (L _ (ClsInstD _ (ClsInstDecl { cid_poly_ty = inst_ty
, cid_datafam_insts = adts })))
| Just (L loc cls_rdr) <- getLHsInstDeclClass_maybe inst_ty
= do { cls_nm <- setSrcSpan loc $ lookupGlobalOccRn cls_rdr
; (avails, fldss)
<- mapAndUnzipM (new_loc_di overload_ok (Just cls_nm)) adts
; return (avails, concat fldss) }
| otherwise
= return ([], []) -- Do not crash on ill-formed instances
-- Eg instance !Show Int Trac #3811c
Notice the use of lookupGlobalOccRn there. Since this code just tunnels into the instance type signature (using getLHsInstDeclClass_maybe) without binding any type variables, this calls lookupGlobalOcc on an unbound type variable c. Eek.
I believe the fix would be to use lookupGlobalOccRn_maybe instead and simply default to return ([], []) in the event that lookupGlobalOccRn_maybe returns Nothing.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |