• Ryan Scott's avatar
    Run checkNewDataCon before constraint-solving newtype constructors · a0d8e92e
    Ryan Scott authored
    Within `checkValidDataCon`, we used to run `checkValidType` on the
    argument types of a newtype constructor before running
    `checkNewDataCon`, which ensures that the user does not attempt
    non-sensical things such as newtypes with multiple arguments or
    constraints. This works out in most situations, but this falls over
    on a corner case revealed in #17955:
    
    ```hs
    newtype T = Coercible () T => T ()
    ```
    
    `checkValidType`, among other things, peforms an ambiguity check on
    the context of a data constructor, and that it turn invokes the
    constraint solver. It turns out that there is a special case in the
    constraint solver for representational equalities (read: `Coercible`
    constraints) that causes newtypes to be unwrapped (see
    `Note [Unwrap newtypes first]` in `TcCanonical`). This special case
    does not know how to cope with an ill formed newtype like `T`, so
    it ends up panicking.
    
    The solution is surprisingly simple: just invoke `checkNewDataCon`
    before `checkValidType` to ensure that the illicit newtype
    constructor context is detected before the constraint solver can
    run amok with it.
    
    Fixes #17955.
    a0d8e92e
TcTyClsDecls.hs 207 KB