
#16116: Explicit foralls in associated type family equations are oblivious to class-bound variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.7 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): The culprit is [http://git.haskell.org/ghc.git/blob/ae4f1033cfe131fca9416e2993bda081e1f8c152... these lines of code] in `rnFamInstEqn`: {{{#!hs ; let bad_tvs = maybe [] (filter is_bad . snd) mb_cls var_name_set = mkNameSet (map hsLTyVarName bndrs' ++ all_imp_var_names) is_bad cls_tkv = cls_tkv `elemNameSet` rhs_fvs && not (cls_tkv `elemNameSet` var_name_set) ; unless (null bad_tvs) (badAssocRhs bad_tvs) }}} `a` //is// in scope over that type family equation, but it's spuriously rejected by this validity check. This check assumes that if a type family equation has an explicit forall, then every type variable on the RHS must either be: 1. Explicitly bound by the `forall`, or 2. Implicitly bound (e.g., as a kind variable) But the sort of program above presents a third option: 3. It's explicitly bound by the class instance, but not by the family equation's `forall`. Unfortunately, this validity check doesn't take this option into account, as evidenced by the implementation of `var_name_set`. I was able to fix this program (and pass GHC's test suite) by changing `var_name_set` to this: {{{#!diff diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs index c76eb31abc..e42f79bd45 100644 --- a/compiler/rename/RnSource.hs +++ b/compiler/rename/RnSource.hs @@ -772,8 +772,9 @@ rnFamInstEqn doc mb_cls rhs_kvars -- See Note [Renaming associated types] ; let bad_tvs = maybe [] (filter is_bad . snd) mb_cls - var_name_set = mkNameSet (map hsLTyVarName bndrs' - ++ all_imp_var_names) + var_name_set = extendNameSetList pat_fvs $ + map hsLTyVarName bndrs' ++ + all_imp_var_names is_bad cls_tkv = cls_tkv `elemNameSet` rhs_fvs && not (cls_tkv `elemNameSet` var_name_set) ; unless (null bad_tvs) (badAssocRhs bad_tvs) }}} I'm not sure if this is the correct approach, however. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16116#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler