Skip to content
Snippets Groups Projects
Forked from Glasgow Haskell Compiler / GHC
Source project has a limited visibility.
  • sheaf's avatar
    8eadea67
    Fix isLiftedType_maybe and handle fallout · 8eadea67
    sheaf authored and Marge Bot's avatar Marge Bot committed
    As #20837 pointed out, `isLiftedType_maybe` returned `Just False` in
    many situations where it should return `Nothing`, because it didn't
    take into account type families or type variables.
    
    In this patch, we fix this issue. We rename `isLiftedType_maybe` to
    `typeLevity_maybe`, which now returns a `Levity` instead of a boolean.
    We now return `Nothing` for types with kinds of the form
    `TYPE (F a1 ... an)` for a type family `F`, as well as
    `TYPE (BoxedRep l)` where `l` is a type variable.
    
    This fix caused several other problems, as other parts of the compiler
    were relying on `isLiftedType_maybe` returning a `Just` value, and were
    now panicking after the above fix. There were two main situations in
    which panics occurred:
    
      1. Issues involving the let/app invariant. To uphold that invariant,
         we need to know whether something is lifted or not. If we get an
         answer of `Nothing` from `isLiftedType_maybe`, then we don't know
         what to do. As this invariant isn't particularly invariant, we
         can change the affected functions to not panic, e.g. by behaving
         the same in the `Just False` case and in the `Nothing` case
         (meaning: no observable change in behaviour compared to before).
    
      2. Typechecking of data (/newtype) constructor patterns. Some programs
         involving patterns with unknown representations were accepted, such
         as T20363. Now that we are stricter, this caused further issues,
         culminating in Core Lint errors. However, the behaviour was
         incorrect the whole time; the incorrectness only being revealed by
         this change, not triggered by it.
    
         This patch fixes this by overhauling where the representation
         polymorphism involving pattern matching are done. Instead of doing
         it in `tcMatches`, we instead ensure that the `matchExpected`
         functions such as `matchExpectedFunTys`, `matchActualFunTySigma`,
         `matchActualFunTysRho` allow return argument pattern types which
         have a fixed RuntimeRep (as defined in Note [Fixed RuntimeRep]).
         This ensures that the pattern matching code only ever handles types
         with a known runtime representation. One exception was that
         patterns with an unknown representation type could sneak in via
         `tcConPat`, which points to a missing representation-polymorphism
         check, which this patch now adds.
    
         This means that we now reject the program in #20363, at least until
         we implement PHASE 2 of FixedRuntimeRep (allowing type families in
         RuntimeRep positions). The aforementioned refactoring, in which
         checks have been moved to `matchExpected` functions, is a first
         step in implementing PHASE 2 for patterns.
    
    Fixes #20837
    8eadea67
    History
    Fix isLiftedType_maybe and handle fallout
    sheaf authored and Marge Bot's avatar Marge Bot committed
    As #20837 pointed out, `isLiftedType_maybe` returned `Just False` in
    many situations where it should return `Nothing`, because it didn't
    take into account type families or type variables.
    
    In this patch, we fix this issue. We rename `isLiftedType_maybe` to
    `typeLevity_maybe`, which now returns a `Levity` instead of a boolean.
    We now return `Nothing` for types with kinds of the form
    `TYPE (F a1 ... an)` for a type family `F`, as well as
    `TYPE (BoxedRep l)` where `l` is a type variable.
    
    This fix caused several other problems, as other parts of the compiler
    were relying on `isLiftedType_maybe` returning a `Just` value, and were
    now panicking after the above fix. There were two main situations in
    which panics occurred:
    
      1. Issues involving the let/app invariant. To uphold that invariant,
         we need to know whether something is lifted or not. If we get an
         answer of `Nothing` from `isLiftedType_maybe`, then we don't know
         what to do. As this invariant isn't particularly invariant, we
         can change the affected functions to not panic, e.g. by behaving
         the same in the `Just False` case and in the `Nothing` case
         (meaning: no observable change in behaviour compared to before).
    
      2. Typechecking of data (/newtype) constructor patterns. Some programs
         involving patterns with unknown representations were accepted, such
         as T20363. Now that we are stricter, this caused further issues,
         culminating in Core Lint errors. However, the behaviour was
         incorrect the whole time; the incorrectness only being revealed by
         this change, not triggered by it.
    
         This patch fixes this by overhauling where the representation
         polymorphism involving pattern matching are done. Instead of doing
         it in `tcMatches`, we instead ensure that the `matchExpected`
         functions such as `matchExpectedFunTys`, `matchActualFunTySigma`,
         `matchActualFunTysRho` allow return argument pattern types which
         have a fixed RuntimeRep (as defined in Note [Fixed RuntimeRep]).
         This ensures that the pattern matching code only ever handles types
         with a known runtime representation. One exception was that
         patterns with an unknown representation type could sneak in via
         `tcConPat`, which points to a missing representation-polymorphism
         check, which this patch now adds.
    
         This means that we now reject the program in #20363, at least until
         we implement PHASE 2 of FixedRuntimeRep (allowing type families in
         RuntimeRep positions). The aforementioned refactoring, in which
         checks have been moved to `matchExpected` functions, is a first
         step in implementing PHASE 2 for patterns.
    
    Fixes #20837
Code owners
Assign users and groups as approvers for specific file changes. Learn more.