Answering my own question: it looks like cleaning this up in GHC.Tc.Errors is 
rather impractical—there are just too many types buried inside other datatypes 
that would have to be updated—so it has to be wired into pprType. Fortunately, 
I can branch on userStyle to decide whether or not to do the expansion. This 
still seems like a bit of a hack, but I can’t think of a better way. Do tell me 
if there’s a better approach!

> On May 1, 2020, at 16:36, Alexis King <lexi.lam...@gmail.com> wrote:
> 
> Hi all,
> 
> As part of my ongoing rework of arrow notation 
> <https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3191>, I have introduced 
> two wired-in type families, which assist in the typechecking process. The 
> details are not terribly important (you can read the proposal if you’d like 
> for those), but the relevant detail is that equalities of the shape
> 
>     ArrowStackTup a ~ b
> 
> are produced by the typechecker in key places. ArrowStackTup is one of my 
> wired-in type families, and it’s really an implementation detail. 
> Unfortunately, I often end up with type errors that leak this detail, with 
> expected/actual types like these ones:
> 
>     Expected type: ArrowStackTup '[Int] -> Bool
>       Actual type: Int -> String
> 
> This is quite annoying, as it’s exceedingly rare that these type families 
> actually get stuck, so they can almost always be expanded in type errors. As 
> it happens, `ArrowStackTup '[a]` expands to simply `a`, so the type error I 
> would like to report is this one:
> 
>     Expected type: Int -> Bool
>       Actual type: Int -> String
> 
> Not technically challenging, but I find myself faced with the question of 
> where this special expansion logic ought to go. It seems like it could go in 
> any of several places:
> 
> It could be hard-wired into pprType, and perhaps selectively disabled with an 
> -fprint-* flag. This is nice in that it’s universal, but it’s almost 
> certainly a step too far: the casts for ArrowStackTup still end up in Core, 
> and expanding the type synonyms there would be quite confusing.
> 
> The expansion could happen in tidyType, since it’s called before reporting an 
> error. But this seems probably even worse than putting it in pprType, since 
> it’s still used in too many places, and it isn’t supposed to actually change 
> the type.
> 
> It could be handled as an extra, ad-hoc preprocessing step in reportWanteds. 
> This is much closer to reasonable, though it feels like quite a hack.
> 
> A separate error Reporter could catch these errors before the other reporters 
> do and perform the expansion there. But I don’t think this actually makes 
> sense, as the above example demonstrates that ArrowStackTup might be buried 
> inside another type and in fact might not actually be the source of the type 
> error at all!
> 
> It could be done last-minute in mkEqErr. But I don’t know if this is too 
> late, and ArrowStackTup could leak into an error through some other code path.
> 
> Of those options, the best one I’ve come up with seems to be option 3, an 
> ad-hoc preprocessing step in reportWanteds. Does that seem reasonable? Or is 
> it too much of a kludge?
> 
> Thanks,
> Alexis

_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Reply via email to