Simon Peyton Jones pushed to branch wip/T26115 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Tc/Deriv.hs
    ... ... @@ -1432,13 +1432,13 @@ See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom
    1432 1432
     -- EarlyDerivSpec from it.
    
    1433 1433
     mk_eqn_from_mechanism :: DerivSpecMechanism -> DerivM EarlyDerivSpec
    
    1434 1434
     mk_eqn_from_mechanism mechanism
    
    1435
    -  = do DerivEnv { denv_overlap_mode = overlap_mode
    
    1436
    -                , denv_tvs          = tvs
    
    1437
    -                , denv_cls          = cls
    
    1438
    -                , denv_inst_tys     = inst_tys
    
    1439
    -                , denv_ctxt         = deriv_ctxt
    
    1440
    -                , denv_skol_info    = skol_info
    
    1441
    -                , denv_warn         = warn } <- ask
    
    1435
    +  = do env@(DerivEnv { denv_overlap_mode = overlap_mode
    
    1436
    +                     , denv_tvs          = tvs
    
    1437
    +                     , denv_cls          = cls
    
    1438
    +                     , denv_inst_tys     = inst_tys
    
    1439
    +                     , denv_ctxt         = deriv_ctxt
    
    1440
    +                     , denv_skol_info    = skol_info
    
    1441
    +                     , denv_warn         = warn }) <- ask
    
    1442 1442
            user_ctxt <- askDerivUserTypeCtxt
    
    1443 1443
            doDerivInstErrorChecks1 mechanism
    
    1444 1444
            loc       <- lift getSrcSpanM
    
    ... ... @@ -1446,7 +1446,7 @@ mk_eqn_from_mechanism mechanism
    1446 1446
            case deriv_ctxt of
    
    1447 1447
             InferContext wildcard ->
    
    1448 1448
               do { (inferred_constraints, tvs', inst_tys', mechanism')
    
    1449
    -                 <- inferConstraints mechanism
    
    1449
    +                 <- inferConstraints mechanism env
    
    1450 1450
                  ; return $ InferTheta $ DS
    
    1451 1451
                        { ds_loc = loc
    
    1452 1452
                        , ds_name = dfun_name, ds_tvs = tvs'
    

  • compiler/GHC/Tc/Deriv/Infer.hs
    ... ... @@ -66,7 +66,7 @@ import Data.Maybe
    66 66
     
    
    67 67
     ----------------------
    
    68 68
     
    
    69
    -inferConstraints :: DerivSpecMechanism
    
    69
    +inferConstraints :: DerivSpecMechanism -> DerivEnv
    
    70 70
                      -> DerivM (ThetaSpec, [TyVar], [TcType], DerivSpecMechanism)
    
    71 71
     -- inferConstraints figures out the constraints needed for the
    
    72 72
     -- instance declaration generated by a 'deriving' clause on a
    
    ... ... @@ -83,12 +83,12 @@ inferConstraints :: DerivSpecMechanism
    83 83
     -- Generate a sufficiently large set of constraints that typechecking the
    
    84 84
     -- generated method definitions should succeed.   This set will be simplified
    
    85 85
     -- before being used in the instance declaration
    
    86
    -inferConstraints mechanism
    
    87
    -  = do { DerivEnv { denv_tvs      = tvs
    
    88
    -                  , denv_cls      = main_cls
    
    89
    -                  , denv_inst_tys = inst_tys } <- ask
    
    90
    -       ; wildcard <- isStandaloneWildcardDeriv
    
    91
    -       ; let infer_constraints :: DerivM (ThetaSpec, [TyVar], [TcType], DerivSpecMechanism)
    
    86
    +inferConstraints mechanism (DerivEnv { denv_ctxt     = ctxt
    
    87
    +                                     , denv_tvs      = tvs
    
    88
    +                                     , denv_cls      = main_cls
    
    89
    +                                     , denv_inst_tys = inst_tys })
    
    90
    +  = do { let wildcard = isStandaloneWildcardDeriv ctxt
    
    91
    +             infer_constraints :: DerivM (ThetaSpec, [TyVar], [TcType], DerivSpecMechanism)
    
    92 92
                  infer_constraints =
    
    93 93
                    case mechanism of
    
    94 94
                      DerivSpecStock{dsm_stock_dit = dit}
    
    ... ... @@ -169,12 +169,12 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys
    169 169
                                             , dit_tc_args     = tc_args
    
    170 170
                                             , dit_rep_tc      = rep_tc
    
    171 171
                                             , dit_rep_tc_args = rep_tc_args })
    
    172
    -  = do DerivEnv { denv_tvs      = tvs
    
    172
    +  = do DerivEnv { denv_ctxt     = ctxt
    
    173
    +                , denv_tvs      = tvs
    
    173 174
                     , denv_cls      = main_cls
    
    174 175
                     , denv_inst_tys = inst_tys } <- ask
    
    175
    -       wildcard <- isStandaloneWildcardDeriv
    
    176
    -
    
    177
    -       let inst_ty    = mkTyConApp tc tc_args
    
    176
    +       let wildcard   = isStandaloneWildcardDeriv ctxt
    
    177
    +           inst_ty    = mkTyConApp tc tc_args
    
    178 178
                tc_binders = tyConBinders rep_tc
    
    179 179
                choose_level bndr
    
    180 180
                  | isNamedTyConBinder bndr = KindLevel
    
    ... ... @@ -370,13 +370,14 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys
    370 370
     -- derived instance context.
    
    371 371
     inferConstraintsAnyclass :: DerivM ThetaSpec
    
    372 372
     inferConstraintsAnyclass
    
    373
    -  = do { DerivEnv { denv_cls       = cls
    
    373
    +  = do { DerivEnv { denv_ctxt      = ctxt
    
    374
    +                  , denv_cls       = cls
    
    374 375
                       , denv_inst_tys  = inst_tys } <- ask
    
    375 376
            ; let gen_dms = [ (sel_id, dm_ty)
    
    376 377
                            | (sel_id, Just (_, GenericDM dm_ty)) <- classOpItems cls ]
    
    377
    -       ; wildcard <- isStandaloneWildcardDeriv
    
    378 378
     
    
    379
    -       ; let meth_pred :: (Id, Type) -> PredSpec
    
    379
    +       ; let wildcard = isStandaloneWildcardDeriv ctxt
    
    380
    +             meth_pred :: (Id, Type) -> PredSpec
    
    380 381
                    -- (Id,Type) are the selector Id and the generic default method type
    
    381 382
                    -- NB: the latter is /not/ quantified over the class variables
    
    382 383
                    -- See Note [Gathering and simplifying constraints for DeriveAnyClass]
    
    ... ... @@ -408,10 +409,10 @@ inferConstraintsAnyclass
    408 409
     inferConstraintsCoerceBased :: [Type] -> Type
    
    409 410
                                 -> DerivM ThetaSpec
    
    410 411
     inferConstraintsCoerceBased cls_tys rep_ty = do
    
    411
    -  DerivEnv { denv_tvs      = tvs
    
    412
    +  DerivEnv { denv_ctxt     = ctxt
    
    413
    +           , denv_tvs      = tvs
    
    412 414
                , denv_cls      = cls
    
    413 415
                , denv_inst_tys = inst_tys } <- ask
    
    414
    -  sa_wildcard <- isStandaloneWildcardDeriv
    
    415 416
       let -- rep_ty might come from:
    
    416 417
           --   GeneralizedNewtypeDeriving / DerivSpecNewtype:
    
    417 418
           --       the underlying type of the newtype ()
    
    ... ... @@ -426,6 +427,7 @@ inferConstraintsCoerceBased cls_tys rep_ty = do
    426 427
                   -- we are going to get all the methods for the final
    
    427 428
                   -- dictionary
    
    428 429
           deriv_origin = mkDerivOrigin sa_wildcard
    
    430
    +      sa_wildcard  = isStandaloneWildcardDeriv ctxt
    
    429 431
     
    
    430 432
           -- Next we collect constraints for the class methods
    
    431 433
           -- If there are no methods, we don't need any constraints
    
    ... ... @@ -574,7 +576,7 @@ Consider the `deriving Alt` part of this example (from the passing part of
    574 576
     T20815a):
    
    575 577
     
    
    576 578
       class Alt f where
    
    577
    -    some :: Applicative f => f a -> f [a]
    
    579
    +    some :: forall a. Applicative f => f a -> f [a]
    
    578 580
     
    
    579 581
       newtype T f a = T (f a) deriving Alt
    
    580 582
     
    

  • compiler/GHC/Tc/Deriv/Utils.hs
    ... ... @@ -35,11 +35,11 @@ import GHC.Tc.Deriv.Generate
    35 35
     import GHC.Tc.Deriv.Functor
    
    36 36
     import GHC.Tc.Deriv.Generics
    
    37 37
     import GHC.Tc.Errors.Types
    
    38
    -import GHC.Tc.Types.Constraint (WantedConstraints, mkNonCanonical)
    
    38
    +import GHC.Tc.Types.Constraint (WantedConstraints, mkNonCanonical, mkSimpleWC)
    
    39 39
     import GHC.Tc.Types.Origin
    
    40 40
     import GHC.Tc.Utils.Monad
    
    41 41
     import GHC.Tc.Utils.TcType
    
    42
    -import GHC.Tc.Utils.Unify (tcSubTypeSigma)
    
    42
    +import GHC.Tc.Utils.Unify (tcSubTypeSigma, buildImplicationFor)
    
    43 43
     import GHC.Tc.Zonk.Type
    
    44 44
     
    
    45 45
     import GHC.Core.Class
    
    ... ... @@ -71,7 +71,6 @@ import GHC.Utils.Error
    71 71
     import GHC.Utils.Unique (sameUnique)
    
    72 72
     
    
    73 73
     import Control.Monad.Trans.Reader
    
    74
    -import Data.Foldable (traverse_)
    
    75 74
     import Data.Maybe
    
    76 75
     import qualified GHC.LanguageExtensions as LangExt
    
    77 76
     import GHC.Data.List.SetOps (assocMaybe)
    
    ... ... @@ -92,12 +91,9 @@ isStandaloneDeriv = asks (go . denv_ctxt)
    92 91
     -- | Is GHC processing a standalone deriving declaration with an
    
    93 92
     -- extra-constraints wildcard as the context?
    
    94 93
     -- (e.g., @deriving instance _ => Eq (Foo a)@)
    
    95
    -isStandaloneWildcardDeriv :: DerivM Bool
    
    96
    -isStandaloneWildcardDeriv = asks (go . denv_ctxt)
    
    97
    -  where
    
    98
    -    go :: DerivContext -> Bool
    
    99
    -    go (InferContext wildcard) = isJust wildcard
    
    100
    -    go (SupplyContext {})      = False
    
    94
    +isStandaloneWildcardDeriv :: DerivContext -> Bool
    
    95
    +isStandaloneWildcardDeriv (InferContext wildcard) = isJust wildcard
    
    96
    +isStandaloneWildcardDeriv (SupplyContext {})      = False
    
    101 97
     
    
    102 98
     -- | Return 'InstDeclCtxt' if processing with a standalone @deriving@
    
    103 99
     -- declaration or 'DerivClauseCtxt' if processing a @deriving@ clause.
    
    ... ... @@ -563,11 +559,17 @@ data PredSpec
    563 559
         SimplePredSpec
    
    564 560
           { sps_pred :: TcPredType
    
    565 561
             -- ^ The constraint to emit as a wanted
    
    562
    +        -- Usually just a simple predicate like (Eq a) or (ki ~# Type),
    
    563
    +        -- but (hack) in the case of GHC.Tc.Deriv.Infer.inferConstraintsCoerceBased,
    
    564
    +        -- it can be a forall-constraint
    
    565
    +
    
    566 566
           , sps_origin :: CtOrigin
    
    567 567
             -- ^ The origin of the constraint
    
    568
    +
    
    568 569
           , sps_type_or_kind :: TypeOrKind
    
    569 570
             -- ^ Whether the constraint is a type or kind
    
    570 571
           }
    
    572
    +
    
    571 573
       | -- | A special 'PredSpec' that is only used by @DeriveAnyClass@. This
    
    572 574
         -- will check if @stps_ty_actual@ is a subtype of (i.e., more polymorphic
    
    573 575
         -- than) @stps_ty_expected@ in the constraint solving machinery, emitting an
    
    ... ... @@ -677,8 +679,8 @@ captureThetaSpecConstraints ::
    677 679
                       -- @deriving@ declaration
    
    678 680
       -> ThetaSpec    -- ^ The specs from which constraints will be created
    
    679 681
       -> TcM (TcLevel, WantedConstraints)
    
    680
    -captureThetaSpecConstraints user_ctxt theta =
    
    681
    -  pushTcLevelM $ mk_wanteds theta
    
    682
    +captureThetaSpecConstraints user_ctxt theta
    
    683
    +  = pushTcLevelM $ mk_wanteds theta
    
    682 684
       where
    
    683 685
         -- Create the constraints we need to solve. For stock and newtype
    
    684 686
         -- deriving, these constraints will be simple wanted constraints
    
    ... ... @@ -689,34 +691,48 @@ captureThetaSpecConstraints user_ctxt theta =
    689 691
         mk_wanteds :: ThetaSpec -> TcM WantedConstraints
    
    690 692
         mk_wanteds preds
    
    691 693
           = do { (_, wanteds) <- captureConstraints $
    
    692
    -                             traverse_ emit_constraints preds
    
    694
    +                             mapM_ (emitPredSpecConstraints user_ctxt) preds
    
    693 695
                ; pure wanteds }
    
    694 696
     
    
    695
    -    -- Emit the appropriate constraints depending on what sort of
    
    696
    -    -- PredSpec we are dealing with.
    
    697
    -    emit_constraints :: PredSpec -> TcM ()
    
    698
    -    emit_constraints ps =
    
    699
    -      case ps of
    
    700
    -        -- For constraints like (C a, Ord b), emit the
    
    701
    -        -- constraints directly as simple wanted constraints.
    
    702
    -        SimplePredSpec { sps_pred = wanted
    
    703
    -                       , sps_origin = orig
    
    704
    -                       , sps_type_or_kind = t_or_k
    
    705
    -                       } -> do
    
    706
    -          ev <- newWanted orig (Just t_or_k) wanted
    
    707
    -          emitSimple (mkNonCanonical ev)
    
    708
    -
    
    709
    -        -- For DeriveAnyClass, check if ty_actual is a subtype of
    
    710
    -        -- ty_expected, which emits an implication constraint as a
    
    711
    -        -- side effect. See
    
    712
    -        -- Note [Gathering and simplifying constraints for DeriveAnyClass].
    
    713
    -        -- in GHC.Tc.Deriv.Infer.
    
    714
    -        SubTypePredSpec { stps_ty_actual   = ty_actual
    
    715
    -                        , stps_ty_expected = ty_expected
    
    716
    -                        , stps_origin      = orig
    
    717
    -                        } -> do
    
    718
    -          _ <- tcSubTypeSigma orig user_ctxt ty_actual ty_expected
    
    719
    -          return ()
    
    697
    +emitPredSpecConstraints :: UserTypeCtxt -> PredSpec -> TcM ()
    
    698
    +--- Emit the appropriate constraints depending on what sort of
    
    699
    +-- PredSpec we are dealing with.
    
    700
    +emitPredSpecConstraints _ (SimplePredSpec { sps_pred = wanted_pred
    
    701
    +                                          , sps_origin = orig
    
    702
    +                                          , sps_type_or_kind = t_or_k })
    
    703
    +  -- For constraints like (C a) or (Ord b), emit the
    
    704
    +  -- constraints directly as simple wanted constraints.
    
    705
    +  | isRhoTy wanted_pred
    
    706
    +  = do { ev <- newWanted orig (Just t_or_k) wanted_pred
    
    707
    +        ; emitSimple (mkNonCanonical ev) }
    
    708
    +
    
    709
    +  | otherwise
    
    710
    +    -- Forall-constraints, which come exclusively from
    
    711
    +    -- GHC.Tc.Deriv.Infer.inferConstraintsCoerceBased.
    
    712
    +    -- For these we want to emit an implication constraint, and NOT a forall-constraint
    
    713
    +    -- Why?  Because forall-constraints are solved all-or-nothing, but here when we
    
    714
    +    -- are trying to infer the context for an instance decl, we need that half-solved
    
    715
    +    -- implicatation (see deriving/should_compile/T20815).
    
    716
    +  = do { let skol_info_anon = DerivSkol wanted_pred
    
    717
    +       ; skol_info <- mkSkolemInfo skol_info_anon
    
    718
    +       ; (_wrapper, tv_prs, givens, wanted_rho) <- topSkolemise skol_info wanted_pred
    
    719
    +         -- _wrapper: we ignore the evidence from all these constraints
    
    720
    +       ; (tc_lvl, ev) <- pushTcLevelM $ newWanted orig (Just t_or_k) wanted_rho
    
    721
    +       ; let skol_tvs = map (binderVar . snd) tv_prs
    
    722
    +       ; (implic, _) <- buildImplicationFor tc_lvl skol_info_anon skol_tvs
    
    723
    +                               givens (mkSimpleWC [ev])
    
    724
    +       ; emitImplications implic }
    
    725
    +
    
    726
    +emitPredSpecConstraints user_ctxt
    
    727
    +  (SubTypePredSpec { stps_ty_actual   = ty_actual
    
    728
    +                   , stps_ty_expected = ty_expected
    
    729
    +                   , stps_origin      = orig })
    
    730
    +-- For DeriveAnyClass, check if ty_actual is a subtype of ty_expected,
    
    731
    +-- which emits an implication constraint as a side effect. See
    
    732
    +-- Note [Gathering and simplifying constraints for DeriveAnyClass]
    
    733
    +-- in GHC.Tc.Deriv.Infer.
    
    734
    +  = do { _ <- tcSubTypeSigma orig user_ctxt ty_actual ty_expected
    
    735
    +       ; return () }
    
    720 736
     
    
    721 737
     {-
    
    722 738
     ************************************************************************
    

  • testsuite/tests/deriving/should_compile/T20815.hs
    ... ... @@ -12,3 +12,5 @@ instance Alt [] where
    12 12
       (<!>) = (++)
    
    13 13
     
    
    14 14
     newtype L a = L [a] deriving (Functor, Alt)
    
    15
    +
    
    16
    +newtype T f a = T (f a) deriving (Functor, Alt)