Skip to content

Wildcard reporting unhelpfully suppressed

NB: fixing #23223 (closed) makes the bug reported here more apparent, by breaking:

  • partial-sigs/should_compile/T11192
  • partial-sigs/should_fail/Defaulting1MROff
  • partial-sigs/should_fail/T11122

Consider this module

{-# LANGUAGE PartialTypeSignatures #-}
module Wom where

class C a where op :: a -> a

f :: _ -> _
f x = op x

We get

Wom.hs:8:7: error: [GHC-39999]
    • No instance for ‘C w0’ arising from a use of ‘op’
    • In the expression: op x
      In an equation for ‘f’: f x = op x
  |
8 | f x = op x
  |       ^^

If we add fdefer-type-errors we get more helpful output

Wom.hs:7:6: warning: [GHC-88464] [-Wpartial-type-signatures]
    • Found type wildcard ‘_’ standing for ‘w0’
      Where: ‘w0’ is an ambiguous type variable
    • In the type signature: f :: _ -> _
  |
7 | f :: _ -> _
  |      ^

Wom.hs:7:11: warning: [GHC-88464] [-Wpartial-type-signatures]
    • Found type wildcard ‘_’ standing for ‘w0’
      Where: ‘w0’ is an ambiguous type variable
    • In the type signature: f :: _ -> _
  |
7 | f :: _ -> _
  |           ^

Wom.hs:8:7: warning: [GHC-39999] [-Wdeferred-type-errors]
    • No instance for ‘C w0’ arising from a use of ‘op’
    • In the expression: op x
      In an equation for ‘f’: f x = op x
  |
8 | f x = op x
  |       ^^

The wildcard info is very helpful in figuring out what the No instance for (C w0) stuff is about.

So what I want is this:

  • to have a warning (i.e. does not kill the rest of the compilation pipeline) from the wildcards
  • that is displayed even if there is also an error (in this case No instance for (C w0).

Some more detail

The type checker obediently creates messages for both (try -ddump-tc-trace to see).

But I think the error message infrastructure suppresses all warnings if there are any errors. And that is why -fdefer-type-errors (which turns type errors into warnings) allows the wildcard warnings to re-appear.

I tried and failed to find out how this suppression happens -- it's a bit of a maze. I think it may be in the mysterious and not-very-helpfully-named function GHC.Driver.Main.ioMsgMaybe, but I'm not sure.

I can't even find where GHC.Tc.Errors.reportHoles decides the severity of the message. I thought it was in the call to diagReasonSeverity in that function; but no: that severity is used briefly to filter out some holes. Instead, it must be somewhere inside mkHoleError, or perhaps mkErrorReport, but (discouragingly) I could not find where.

I rather suspect that the infrastructure simply can't deal with

  • a warning (i.e. does not kill the rest of the compilation pipeline)...
  • that is displayed even if there is also an error.

Maybe we need an extra constructor in Severity for "warnings that should displayed with errors, but which don't kill compilation"?

This bump in the road is what is causing a couple of regressions in !10123 (merged), which I am eager to land. But it's not restricted to !10123 (merged). The above problem is in HEAD today.

Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information