Note [Long-distance information in matchWrapper]

GHC/HsToCore/Match.hs:862 compiler 1 ticket

The pattern match checking in matchWrapper is done conditionally, depending
on isMatchContextPmChecked. This means that we don't perform pattern match
checking on e.g. generated pattern matches.

However, when we skip pattern match checking, we still need to keep track
of long-distance information in case we need it in a nested context.

This came up in #23445. For example:

  data GADT a where
    IsUnit :: GADT ()

  data Foo b where
    FooUnit :: Foo ()
    FooInt  :: Foo Int

  data SomeRec = SomeRec { fld :: () }

  bug :: GADT a -> Foo a -> SomeRec -> SomeRec
  bug IsUnit foo r =
    let gen_fld :: ()
        gen_fld = case foo of { FooUnit -> () }
    in case r of { SomeRec _ -> SomeRec gen_fld }

Here the body of 'bug' was generated by 'desugarRecordUpd' from the user-written
record update

  cd { fld = case foo of { FooUnit -> () } }

As a result, we have a generated FunBind gen_fld whose RHS

  case foo of { FooUnit -> () }

is user-written. This all happens after the GADT pattern match on IsUnit,
which brings into scope the Given equality [G] a ~ (). We need to make sure
that this long distance information is visible when pattern match checking the
user-written case statement.

To propagate this long-distance information in 'matchWrapper', when we skip
pattern match checks, we make sure to manually pass the long-distance
information to 'mk_eqn_info', which is responsible for recurring further into
the expression (in this case, it will end up recursively calling 'matchWrapper'
on the user-written case statement).

References 0

This Note does not link to any other.

Referenced by 3