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

Commits:

9 changed files:

Changes:

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -46,6 +46,7 @@ import GHC.Core.FVs
    46 46
     import GHC.Core.Utils
    
    47 47
     import GHC.Core.Stats ( coreBindsStats )
    
    48 48
     import GHC.Core.DataCon
    
    49
    +import GHC.Core.SubstTypeLets( substTypeLets )
    
    49 50
     import GHC.Core.Ppr
    
    50 51
     import GHC.Core.Coercion
    
    51 52
     import GHC.Core.Type as Type
    
    ... ... @@ -178,65 +179,7 @@ Note [Linting function types]
    178 179
     All saturated applications of funTyCon are represented with the FunTy constructor.
    
    179 180
     See Note [Function type constructors and FunTy] in GHC.Builtin.Types.Prim
    
    180 181
     
    
    181
    - We check this invariant in lintType.
    
    182
    -
    
    183
    -Note [Linting type lets]
    
    184
    -~~~~~~~~~~~~~~~~~~~~~~~~
    
    185
    -In the desugarer, it's very very convenient to be able to say (in effect)
    
    186
    -        let a = Type Bool in
    
    187
    -        let x::a = True in <body>
    
    188
    -That is, use a type let.  See Note [Core type and coercion invariant] in "GHC.Core".
    
    189
    -One place it is used is in mkWwBodies; see Note [Join points and beta-redexes]
    
    190
    -in GHC.Core.Opt.WorkWrap.Utils.  (Maybe there are other "clients" of this feature; I'm not sure).
    
    191
    -
    
    192
    -* Hence when linting <body> we need to remember that a=Int, else we
    
    193
    -  might reject a correct program.  So we carry a type substitution (in
    
    194
    -  this example [a -> Bool]) and apply this substitution before
    
    195
    -  comparing types. In effect, in Lint, type equality is always
    
    196
    -  equality-modulo-le-subst.  This is in the le_subst field of
    
    197
    -  LintEnv.  But nota bene:
    
    198
    -
    
    199
    -  (SI1) The le_subst substitution is applied to types and coercions only
    
    200
    -
    
    201
    -  (SI2) The result of that substitution is used only to check for type
    
    202
    -        equality, to check well-typed-ness, /but is then discarded/.
    
    203
    -        The result of substitution does not outlive the CoreLint pass.
    
    204
    -
    
    205
    -  (SI3) The InScopeSet of le_subst includes only TyVar and CoVar binders.
    
    206
    -
    
    207
    -* The function
    
    208
    -        lintInTy :: Type -> LintM (Type, Kind)
    
    209
    -  returns a substituted type.
    
    210
    -
    
    211
    -* When we encounter a binder (like x::a) we must apply the substitution
    
    212
    -  to the type of the binding variable.  lintBinders does this.
    
    213
    -
    
    214
    -* Clearly we need to clone tyvar binders as we go.
    
    215
    -
    
    216
    -* But take care (#17590)! We must also clone CoVar binders:
    
    217
    -    let a = TYPE (ty |> cv)
    
    218
    -    in \cv -> blah
    
    219
    -  blindly substituting for `a` might capture `cv`.
    
    220
    -
    
    221
    -* Alas, when cloning a coercion variable we might choose a unique
    
    222
    -  that happens to clash with an inner Id, thus
    
    223
    -      \cv_66 -> let wild_X7 = blah in blah
    
    224
    -  We decide to clone `cv_66` because it's already in scope.  Fine,
    
    225
    -  choose a new unique.  Aha, X7 looks good.  So we check the lambda
    
    226
    -  body with le_subst of [cv_66 :-> cv_X7]
    
    227
    -
    
    228
    -  This is all fine, even though we use the same unique as wild_X7.
    
    229
    -  As (SI2) says, we do /not/ return a new lambda
    
    230
    -     (\cv_X7 -> let wild_X7 = blah in ...)
    
    231
    -  We simply use the le_subst substitution in types/coercions only, when
    
    232
    -  checking for equality.
    
    233
    -
    
    234
    -* We still need to check that Id occurrences are bound by some
    
    235
    -  enclosing binding.  We do /not/ use the InScopeSet for the le_subst
    
    236
    -  for this purpose -- it contains only TyCoVars.  Instead we have a separate
    
    237
    -  le_ids for the in-scope Id binders.
    
    238
    -
    
    239
    -Sigh.  We might want to explore getting rid of type-let!
    
    182
    +We check this invariant in lintType.
    
    240 183
     
    
    241 184
     Note [Bad unsafe coercion]
    
    242 185
     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -311,6 +254,7 @@ path does not result in allocation in the hot path. This can be surprisingly
    311 254
     impactful. Changing `lint_app` reduced allocations for one test program I was
    
    312 255
     looking at by ~4%.
    
    313 256
     
    
    257
    +
    
    314 258
     ************************************************************************
    
    315 259
     *                                                                      *
    
    316 260
                      Beginning and ending passes
    
    ... ... @@ -407,26 +351,37 @@ data LintPassResultConfig = LintPassResultConfig
    407 351
       , lpr_platform         :: !Platform
    
    408 352
       , lpr_makeLintFlags    :: !LintFlags
    
    409 353
       , lpr_passPpr          :: !SDoc
    
    354
    +  , lpr_preSubst         :: !Bool  -- True <=> run substTypeLets before linting
    
    355
    +                                   -- See Note [Substituting type-lets]
    
    410 356
       , lpr_localsInScope    :: ![Var]
    
    411 357
       }
    
    412 358
     
    
    413 359
     lintPassResult :: Logger -> LintPassResultConfig
    
    414 360
                    -> CoreProgram -> IO ()
    
    415 361
     lintPassResult logger cfg binds
    
    416
    -  = do { let warns_and_errs = lintCoreBindings'
    
    417
    -               (LintConfig
    
    362
    +  = do { let lint_config = LintConfig
    
    418 363
                     { l_diagOpts = lpr_diagOpts cfg
    
    419 364
                     , l_platform = lpr_platform cfg
    
    420 365
                     , l_flags    = lpr_makeLintFlags cfg
    
    421 366
                     , l_vars     = lpr_localsInScope cfg
    
    422
    -                })
    
    423
    -               binds
    
    367
    +                }
    
    368
    +
    
    369
    +       -- Do the pre-substitution if necessary
    
    370
    +       -- See Note [Substituting type-lets] in GHC.Core.SubstTypeLets
    
    371
    +       -- especially wrinkle (STL2)
    
    372
    +       ; let binds1 | lpr_preSubst cfg = substTypeLets binds
    
    373
    +                    | otherwise        = binds
    
    374
    +
    
    375
    +       -- Do the main Lint pass itself
    
    376
    +       ; let warns_and_errs = lintCoreBindings' lint_config binds1
    
    377
    +
    
    378
    +       -- Report the results
    
    424 379
            ; Err.showPass logger $
    
    425 380
                "Core Linted result of " ++
    
    426 381
                renderWithContext defaultSDocContext (lpr_passPpr cfg)
    
    427 382
            ; displayLintResults logger
    
    428 383
                                 (lpr_passPpr cfg)
    
    429
    -                            (pprCoreBindings binds) warns_and_errs
    
    384
    +                            (pprCoreBindings binds1) warns_and_errs
    
    430 385
            }
    
    431 386
     
    
    432 387
     displayLintResults :: Logger
    
    ... ... @@ -472,8 +427,7 @@ lintCoreBindings' cfg binds
    472 427
            ; checkL (null ext_dups) (dupExtVars ext_dups)
    
    473 428
     
    
    474 429
              -- Typecheck the bindings
    
    475
    -       ; lintRecBindings TopLevel all_pairs $ \_ ->
    
    476
    -         return () }
    
    430
    +       ; lintRecBindings TopLevel all_pairs $ return () }
    
    477 431
       where
    
    478 432
         all_pairs = flattenBinds binds
    
    479 433
          -- Put all the top-level binders in scope at the start
    
    ... ... @@ -555,11 +509,11 @@ Check a core binding, returning the list of variables bound.
    555 509
     -- Let
    
    556 510
     
    
    557 511
     lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)]
    
    558
    -                -> ([OutId] -> LintM a) -> LintM (a, [UsageEnv])
    
    512
    +                -> LintM a -> LintM (a, [UsageEnv])
    
    559 513
     lintRecBindings top_lvl pairs thing_inside
    
    560
    -  = lintIdBndrs top_lvl bndrs $ \ bndrs' ->
    
    561
    -    do { ues <- zipWithM lint_pair bndrs' rhss
    
    562
    -       ; a <- thing_inside bndrs'
    
    514
    +  = lintIdBndrs top_lvl bndrs $
    
    515
    +    do { ues <- zipWithM lint_pair bndrs rhss
    
    516
    +       ; a <- thing_inside
    
    563 517
            ; return (a, ues) }
    
    564 518
       where
    
    565 519
         (bndrs, rhss) = unzip pairs
    
    ... ... @@ -569,14 +523,14 @@ lintRecBindings top_lvl pairs thing_inside
    569 523
                ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty
    
    570 524
                ; return ue }
    
    571 525
     
    
    572
    -lintLetBody :: LintLocInfo -> [OutId] -> CoreExpr -> LintM (OutType, UsageEnv)
    
    526
    +lintLetBody :: LintLocInfo -> [Id] -> CoreExpr -> LintM (Type, UsageEnv)
    
    573 527
     lintLetBody loc bndrs body
    
    574 528
       = do { (body_ty, body_ue) <- addLoc loc (lintCoreExpr body)
    
    575 529
            ; mapM_ (lintJoinBndrType body_ty) bndrs
    
    576 530
            ; return (body_ty, body_ue) }
    
    577 531
     
    
    578
    -lintLetBind :: TopLevelFlag -> RecFlag -> OutId
    
    579
    -              -> CoreExpr -> OutType -> LintM ()
    
    532
    +lintLetBind :: TopLevelFlag -> RecFlag -> Id
    
    533
    +            -> CoreExpr -> Type -> LintM ()
    
    580 534
     -- Binder's type, and the RHS, have already been linted
    
    581 535
     -- This function checks other invariants
    
    582 536
     lintLetBind top_lvl rec_flag binder rhs rhs_ty
    
    ... ... @@ -667,7 +621,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty
    667 621
     -- join point.
    
    668 622
     --
    
    669 623
     -- See Note [Checking StaticPtrs].
    
    670
    -lintRhs :: Id -> CoreExpr -> LintM (OutType, UsageEnv)
    
    624
    +lintRhs :: Id -> CoreExpr -> LintM (Type, UsageEnv)
    
    671 625
     -- NB: the Id can be Linted or not -- it's only used for
    
    672 626
     --     its OccInfo and join-pointer-hood
    
    673 627
     lintRhs bndr rhs
    
    ... ... @@ -682,7 +636,7 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go
    682 636
       where
    
    683 637
         -- Allow occurrences of 'makeStatic' at the top-level but produce errors
    
    684 638
         -- otherwise.
    
    685
    -    go :: StaticPtrCheck -> LintM (OutType, UsageEnv)
    
    639
    +    go :: StaticPtrCheck -> LintM (Type, UsageEnv)
    
    686 640
         go AllowAtTopLevel
    
    687 641
           | (binders0, rhs') <- collectTyBinders rhs
    
    688 642
           , Just (fun, t, info, e) <- collectMakeStaticArgs rhs'
    
    ... ... @@ -699,7 +653,7 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go
    699 653
     
    
    700 654
     -- | Lint the RHS of a join point with expected join arity of @n@ (see Note
    
    701 655
     -- [Join points] in "GHC.Core").
    
    702
    -lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (OutType, UsageEnv)
    
    656
    +lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (Type, UsageEnv)
    
    703 657
     lintJoinLams join_arity enforce rhs
    
    704 658
       = go join_arity rhs
    
    705 659
       where
    
    ... ... @@ -887,13 +841,8 @@ suspicious and worth investigating if you have a seg-fault or bizarre behaviour.
    887 841
     ************************************************************************
    
    888 842
     -}
    
    889 843
     
    
    890
    -lintCoreExpr :: InExpr -> LintM (OutType, UsageEnv)
    
    891
    --- The returned type has the substitution from the monad
    
    892
    --- already applied to it:
    
    893
    ---      lintCoreExpr e subst = exprType (subst e)
    
    894
    ---
    
    895
    --- The returned "type" can be a kind, if the expression is (Type ty)
    
    896
    -
    
    844
    +lintCoreExpr :: CoreExpr -> LintM (Type, UsageEnv)
    
    845
    +-- The returned type is the type of the expression
    
    897 846
     -- If you edit this function, you may need to update the GHC formalism
    
    898 847
     -- See Note [GHC Formalism]
    
    899 848
     
    
    ... ... @@ -920,7 +869,7 @@ lintCoreExpr (Cast expr co)
    920 869
     
    
    921 870
            ; lintCoercion co
    
    922 871
            ; lintRole co Representational (coercionRole co)
    
    923
    -       ; Pair from_ty to_ty <- substCoKindM co
    
    872
    +       ; let Pair from_ty to_ty = coercionKind co
    
    924 873
            ; checkValueType (typeKind to_ty) $
    
    925 874
              text "target of cast" <+> quotes (ppr co)
    
    926 875
            ; ensureEqTys from_ty expr_ty (mkCastErr expr co from_ty expr_ty)
    
    ... ... @@ -934,15 +883,10 @@ lintCoreExpr (Tick tickish expr)
    934 883
     
    
    935 884
     lintCoreExpr (Let (NonRec tv (Type ty)) body)
    
    936 885
       | isTyVar tv
    
    937
    -  =     -- See Note [Linting type lets]
    
    938
    -    do  { ty' <- lintTypeAndSubst ty
    
    939
    -        ; lintTyCoBndr tv              $ \ tv' ->
    
    940
    -    do  { addLoc (RhsOf tv) $ lintTyKind tv' ty'
    
    941
    -                -- Now extend the substitution so we
    
    942
    -                -- take advantage of it in the body
    
    943
    -        ; extendTvSubstL tv ty' $
    
    944
    -          addLoc (BodyOfLet tv) $
    
    945
    -          lintCoreExpr body } }
    
    886
    +  = do  { lintType ty
    
    887
    +        ; lintTyCoBndr tv              $
    
    888
    +    do  { addLoc (RhsOf tv)     $ lintTyKind tv ty
    
    889
    +        ; addLoc (BodyOfLet tv) $ lintCoreExpr body } }
    
    946 890
     
    
    947 891
     lintCoreExpr (Let (NonRec bndr rhs) body)
    
    948 892
       | isId bndr
    
    ... ... @@ -951,10 +895,10 @@ lintCoreExpr (Let (NonRec bndr rhs) body)
    951 895
     
    
    952 896
               -- See Note [Multiplicity of let binders] in Var
    
    953 897
              -- Now lint the binder
    
    954
    -       ; lintBinder LetBind bndr $ \bndr' ->
    
    955
    -    do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty
    
    956
    -       ; addAliasUE bndr' let_ue $
    
    957
    -         lintLetBody (BodyOfLet bndr') [bndr'] body } }
    
    898
    +       ; lintBinder LetBind bndr $
    
    899
    +    do { lintLetBind NotTopLevel NonRecursive bndr rhs rhs_ty
    
    900
    +       ; addAliasUE bndr let_ue $
    
    901
    +         lintLetBody (BodyOfLet bndr) [bndr] body } }
    
    958 902
     
    
    959 903
       | otherwise
    
    960 904
       = failWithL (mkLetErr bndr rhs)       -- Not quite accurate
    
    ... ... @@ -973,8 +917,8 @@ lintCoreExpr e@(Let (Rec pairs) body)
    973 917
     
    
    974 918
               -- See Note [Multiplicity of let binders] in Var
    
    975 919
             ; ((body_type, body_ue), ues) <-
    
    976
    -            lintRecBindings NotTopLevel pairs $ \ bndrs' ->
    
    977
    -            lintLetBody (BodyOfLetRec bndrs') bndrs' body
    
    920
    +            lintRecBindings NotTopLevel pairs $
    
    921
    +            lintLetBody (BodyOfLetRec bndrs) bndrs body
    
    978 922
             ; return (body_type, body_ue  `addUE` scaleUE ManyTy (foldr1WithDefault zeroUE addUE ues)) }
    
    979 923
       where
    
    980 924
         bndrs = map fst pairs
    
    ... ... @@ -986,7 +930,7 @@ lintCoreExpr e@(App _ _)
    986 930
         -- N.B. we may have an over-saturated application of the form:
    
    987 931
         --   runRW (\s -> \x -> ...) y
    
    988 932
       , ty_arg1 : ty_arg2 : cont_arg : rest <- args
    
    989
    -  = do { let lint_rw_cont :: CoreArg -> Mult -> UsageEnv -> LintM (OutType, UsageEnv)
    
    933
    +  = do { let lint_rw_cont :: CoreArg -> Mult -> UsageEnv -> LintM (Type, UsageEnv)
    
    990 934
                  lint_rw_cont expr@(Lam _ _) mult fun_ue
    
    991 935
                     = do { (arg_ty, arg_ue) <- lintJoinLams 1 (Just fun) expr
    
    992 936
                          ; let app_ue = addUE fun_ue (scaleUE mult arg_ue)
    
    ... ... @@ -1036,74 +980,73 @@ lintCoreExpr (Type ty)
    1036 980
     lintCoreExpr (Coercion co)
    
    1037 981
       -- See Note [Coercions in terms]
    
    1038 982
       = do { addLoc (InCo co) $ lintCoercion co
    
    1039
    -       ; ty <- substTyM (coercionType co)
    
    983
    +       ; let ty = coercionType co
    
    1040 984
            ; return (ty, zeroUE) }
    
    1041 985
     
    
    1042 986
     ----------------------
    
    1043
    -lintIdOcc :: InId -> Int -- Number of arguments (type or value) being passed
    
    1044
    -          -> LintM (OutType, UsageEnv) -- returns type of the *variable*
    
    1045
    -lintIdOcc in_id nargs
    
    1046
    -  = addLoc (OccOf in_id) $
    
    1047
    -    do  { checkL (isNonCoVarId in_id)
    
    1048
    -                 (text "Non term variable" <+> ppr in_id)
    
    987
    +lintIdOcc :: Id -> Int -- Number of arguments (type or value) being passed
    
    988
    +          -> LintM (Type, UsageEnv) -- returns type of the *variable*
    
    989
    +lintIdOcc id nargs
    
    990
    +  = addLoc (OccOf id) $
    
    991
    +    do  { checkL (isNonCoVarId id)
    
    992
    +                 (text "Non term variable" <+> ppr id)
    
    1049 993
                      -- See GHC.Core Note [Variable occurrences in Core]
    
    1050 994
     
    
    1051
    -        -- Check that the type of the occurrence is the same
    
    1052
    -        -- as the type of the binding site.  The inScopeIds are
    
    1053
    -        -- /un-substituted/, so this checks that the occurrence type
    
    1054
    -        -- is identical to the binder type.
    
    1055
    -        -- This makes things much easier for things like:
    
    1056
    -        --    /\a. \(x::Maybe a). /\a. ...(x::Maybe a)...
    
    1057
    -        -- The "::Maybe a" on the occurrence is referring to the /outer/ a.
    
    1058
    -        -- If we compared /substituted/ types we'd risk comparing
    
    1059
    -        -- (Maybe a) from the binding site with bogus (Maybe a1) from
    
    1060
    -        -- the occurrence site.  Comparing un-substituted types finesses
    
    1061
    -        -- this altogether
    
    1062
    -        ; out_ty <- lintVarOcc in_id
    
    995
    +        ; lintVarOcc id
    
    1063 996
     
    
    1064 997
               -- Check for a nested occurrence of the StaticPtr constructor.
    
    1065 998
               -- See Note [Checking StaticPtrs].
    
    1066 999
             ; when (nargs /= 0) $
    
    1067
    -          checkL (idName in_id /= makeStaticName) $
    
    1000
    +          checkL (idName id /= makeStaticName) $
    
    1068 1001
               text "Found makeStatic nested in an expression"
    
    1069 1002
     
    
    1070
    -        ; checkDeadIdOcc in_id
    
    1003
    +        ; checkDeadIdOcc id
    
    1071 1004
     
    
    1072
    -        ; case isDataConId_maybe in_id of
    
    1005
    +        ; case isDataConId_maybe id of
    
    1073 1006
                  Nothing -> return ()
    
    1074 1007
                  Just dc -> checkTypeDataConOcc "expression" dc
    
    1075 1008
     
    
    1076
    -        ; checkJoinOcc in_id nargs
    
    1077
    -        ; usage <- varCallSiteUsage in_id
    
    1078
    -
    
    1079
    -        ; return (out_ty, usage) }
    
    1009
    +        ; checkJoinOcc id nargs
    
    1010
    +        ; usage <- varCallSiteUsage id
    
    1080 1011
     
    
    1012
    +        ; return (idType id, usage) }
    
    1081 1013
     
    
    1082 1014
     
    
    1015
    +------------------
    
    1083 1016
     lintCoreFun :: CoreExpr
    
    1084
    -            -> Int                          -- Number of arguments (type or val) being passed
    
    1085
    -            -> LintM (OutType, UsageEnv) -- Returns type of the *function*
    
    1017
    +            -> Int                    -- Number of arguments (type or val) being passed
    
    1018
    +            -> LintM (Type, UsageEnv) -- Returns type of the *function*
    
    1086 1019
     lintCoreFun (Var var) nargs
    
    1087 1020
       = lintIdOcc var nargs
    
    1088 1021
     
    
    1089 1022
     lintCoreFun (Lam var body) nargs
    
    1090
    -  -- Act like lintCoreExpr of Lam, but *don't* call markAllJoinsBad;
    
    1091
    -  -- See Note [Beta redexes]
    
    1023
    +  -- Act like lintCoreExpr of Lam, but *don't* necessarily call markAllJoinsBad;
    
    1024
    +  -- See Note [Join points and beta-redexes]
    
    1092 1025
       | nargs /= 0
    
    1093 1026
       = lintLambda var $ lintCoreFun body (nargs - 1)
    
    1094 1027
     
    
    1095 1028
     lintCoreFun expr nargs
    
    1096
    -  = markAllJoinsBadIf (nargs /= 0) $
    
    1097
    -      -- See Note [Join points are less general than the paper]
    
    1098
    -    lintCoreExpr expr
    
    1029
    +  = do { mark_bad_joins
    
    1030
    +           <- if nargs == 0
    
    1031
    +              then -- Saturated lambda
    
    1032
    +                   -- See Note [Join points and beta-redexes]
    
    1033
    +                   do { flags <- getLintFlags
    
    1034
    +                      ; return (not (lf_allow_beta_joins flags)) }
    
    1035
    +              else -- Something else
    
    1036
    +                   -- See Note [Join points are less general than the paper]
    
    1037
    +                   return True
    
    1038
    +
    
    1039
    +       ; markAllJoinsBadIf mark_bad_joins $
    
    1040
    +         lintCoreExpr expr }
    
    1041
    +
    
    1099 1042
     ------------------
    
    1100 1043
     lintLambda :: Var -> LintM (Type, UsageEnv) -> LintM (Type, UsageEnv)
    
    1101 1044
     lintLambda var lintBody =
    
    1102 1045
         addLoc (LambdaBodyOf var) $
    
    1103
    -    lintBinder LambdaBind var $ \ var' ->
    
    1046
    +    lintBinder LambdaBind var $
    
    1104 1047
         do { (body_ty, ue) <- lintBody
    
    1105
    -       ; ue' <- checkLinearity ue var'
    
    1106
    -       ; return (mkLamType var' body_ty, ue') }
    
    1048
    +       ; ue' <- checkLinearity ue var
    
    1049
    +       ; return (mkLamType var body_ty, ue') }
    
    1107 1050
     ------------------
    
    1108 1051
     checkDeadIdOcc :: Id -> LintM ()
    
    1109 1052
     -- Occurrences of an Id should never be dead....
    
    ... ... @@ -1117,8 +1060,8 @@ checkDeadIdOcc id
    1117 1060
       = return ()
    
    1118 1061
     
    
    1119 1062
     ------------------
    
    1120
    -lintJoinBndrType :: OutType -- Type of the body
    
    1121
    -                 -> OutId   -- Possibly a join Id
    
    1063
    +lintJoinBndrType :: Type -- Type of the body
    
    1064
    +                 -> Id   -- Possibly a join Id
    
    1122 1065
                      -> LintM ()
    
    1123 1066
     -- Checks that the return type of a join Id matches the body
    
    1124 1067
     -- E.g. join j x = rhs in body
    
    ... ... @@ -1337,8 +1280,51 @@ checkLinearity body_ue lam_var =
    1337 1280
           return body_ue'
    
    1338 1281
         Nothing    -> return body_ue -- A type variable
    
    1339 1282
     
    
    1340
    -{- Note [Linting join points with casts or ticks]
    
    1341
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1283
    +{- Note [Join points and beta-redexes]
    
    1284
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1285
    +In the worker/wrapper pass, the worker invokes the original function by calling
    
    1286
    +it with arguments, thus producing a beta-redex for the simplifier to munch away:
    
    1287
    +
    
    1288
    +  \x y z -> e   =>    (\x y z -> e) wx wy wz
    
    1289
    +
    
    1290
    +But we need to take care if `e` invokes a join point.  For example:
    
    1291
    +
    
    1292
    +  join j1 x = ...
    
    1293
    +  join j2 y = if y == 0 then 0 else j1 y
    
    1294
    +=>
    
    1295
    +  join j1 x = ...
    
    1296
    +  join $wj2 y# = (\y -> if y == 0 then 0 else jump j1 y) (I# y#)
    
    1297
    +  join j2 y = case y of I# y# -> jump $wj2 y#
    
    1298
    +
    
    1299
    +Now the jump to `j1` is inside a lambda and inside an application. That is ill-typed
    
    1300
    +from Lint's point of view.  And yet, after one round of simplification it'll all be
    
    1301
    +fine.
    
    1302
    +
    
    1303
    +You might wonder if we could use a `let` instead of a lambda for the worker:
    
    1304
    +
    
    1305
    +  join $wj2 y# = let y = I# y#
    
    1306
    +                 in  if y == 0 then 0 else jump j1 y
    
    1307
    +
    
    1308
    +That would solve the join-point problem, but it really doesn't work because the
    
    1309
    +lets shadow each other.  The lambda arguments should not "see" any of the
    
    1310
    +lambda-bound variables.
    
    1311
    +
    
    1312
    +So our solution is this:
    
    1313
    +
    
    1314
    +* Use straightforward applicaion in the worker-wrapper pass, creating a eta-redex.
    
    1315
    +  See the call to `mkApps` in GHC.Core.Opt.WorkWrap.Utils.mkWwBodies.
    
    1316
    +
    
    1317
    +* Tell Lint not to complain about a join-point invocation hidden under a
    
    1318
    +  saturated beta-redex.  The code is rather simple: see `lintCoreFun`.
    
    1319
    +
    
    1320
    +* We guard this with a Lint flag `lf_allow_beta_joins`.
    
    1321
    +
    
    1322
    +* Teach occurrence analysis that `j1` is still a join point, despite its
    
    1323
    +  call being nested inside the beta-redex.  See Note [occAnal for applications]
    
    1324
    +  in GHC.Core.Opt.OccurAnal.
    
    1325
    +
    
    1326
    +Note [Linting join points with casts or ticks]
    
    1327
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1342 1328
     As per Note [Join points, casts, and ticks] in GHC.Core, we have to be careful
    
    1343 1329
     when a cast or tick occurs in between a join point binding and a corresponding
    
    1344 1330
     join point occurrence.
    
    ... ... @@ -1409,33 +1395,6 @@ lose track of why an expression is bottom, so we shouldn't make too
    1409 1395
     much fuss when that happens.
    
    1410 1396
     
    
    1411 1397
     
    
    1412
    -Note [Beta redexes]
    
    1413
    -~~~~~~~~~~~~~~~~~~~
    
    1414
    -Consider:
    
    1415
    -
    
    1416
    -  join j @x y z = ... in
    
    1417
    -  (\@x y z -> jump j @x y z) @t e1 e2
    
    1418
    -
    
    1419
    -This is clearly ill-typed, since the jump is inside both an application and a
    
    1420
    -lambda, either of which is enough to disqualify it as a tail call (see Note
    
    1421
    -[Invariants on join points] in GHC.Core). However, strictly from a
    
    1422
    -lambda-calculus perspective, the term doesn't go wrong---after the two beta
    
    1423
    -reductions, the jump *is* a tail call and everything is fine.
    
    1424
    -
    
    1425
    -Why would we want to allow this when we have let? One reason is that a compound
    
    1426
    -beta redex (that is, one with more than one argument) has different scoping
    
    1427
    -rules: naively reducing the above example using lets will capture any free
    
    1428
    -occurrence of y in e2. More fundamentally, type lets are tricky; many passes,
    
    1429
    -such as Float Out, tacitly assume that the incoming program's type lets have
    
    1430
    -all been dealt with by the simplifier. Thus we don't want to let-bind any types
    
    1431
    -in, say, GHC.Core.Subst.simpleOptPgm, which in some circumstances can run immediately
    
    1432
    -before Float Out.
    
    1433
    -
    
    1434
    -All that said, currently GHC.Core.Subst.simpleOptPgm is the only thing using this
    
    1435
    -loophole, doing so to avoid re-traversing large functions (beta-reducing a type
    
    1436
    -lambda without introducing a type let requires a substitution). TODO: Improve
    
    1437
    -simpleOptPgm so that we can forget all this ever happened.
    
    1438
    -
    
    1439 1398
     ************************************************************************
    
    1440 1399
     *                                                                      *
    
    1441 1400
     \subsection[lintCoreArgs]{lintCoreArgs}
    
    ... ... @@ -1449,23 +1408,23 @@ subtype of the required type, as one would expect.
    1449 1408
     -- Takes the functions type and arguments as argument.
    
    1450 1409
     -- Returns the *result* of applying the function to arguments.
    
    1451 1410
     -- e.g. f :: Int -> Bool -> Int would return `Int` as result type.
    
    1452
    -lintCoreArgs  :: (OutType, UsageEnv) -> [InExpr] -> LintM (OutType, UsageEnv)
    
    1411
    +lintCoreArgs  :: (Type, UsageEnv) -> [CoreExpr] -> LintM (Type, UsageEnv)
    
    1453 1412
     lintCoreArgs (fun_ty, fun_ue) args
    
    1454
    -  = lintApp (text "expression")
    
    1455
    -              lintTyArg lintValArg fun_ty args fun_ue
    
    1413
    +  = lintApp (text "expression") lintTyArg lintValArg fun_ty args fun_ue
    
    1456 1414
     
    
    1457
    -lintTyArg :: InExpr -> LintM OutType
    
    1415
    +lintTyArg :: CoreExpr -> LintM Type
    
    1458 1416
     
    
    1459 1417
     -- Type argument
    
    1460 1418
     lintTyArg (Type arg_ty)
    
    1461 1419
       = do { checkL (not (isCoercionTy arg_ty))
    
    1462 1420
                     (text "Unnecessary coercion-to-type injection:"
    
    1463 1421
                       <+> ppr arg_ty)
    
    1464
    -       ; lintTypeAndSubst arg_ty }
    
    1422
    +       ; lintType arg_ty
    
    1423
    +       ; return arg_ty }
    
    1465 1424
     lintTyArg arg
    
    1466 1425
       = failWithL (hang (text "Expected type argument but found") 2 (ppr arg))
    
    1467 1426
     
    
    1468
    -lintValArg  :: InExpr -> Mult -> UsageEnv -> LintM (OutType, UsageEnv)
    
    1427
    +lintValArg  :: CoreExpr -> Mult -> UsageEnv -> LintM (Type, UsageEnv)
    
    1469 1428
     lintValArg arg mult fun_ue
    
    1470 1429
       = do { (arg_ty, arg_ue) <- markAllJoinsBad $ lintCoreExpr arg
    
    1471 1430
                -- See Note [Representation polymorphism invariants] in GHC.Core
    
    ... ... @@ -1485,12 +1444,18 @@ lintValArg arg mult fun_ue
    1485 1444
     -----------------
    
    1486 1445
     lintAltBinders :: UsageEnv
    
    1487 1446
                    -> Var         -- Case binder
    
    1488
    -               -> OutType     -- Scrutinee type
    
    1489
    -               -> OutType     -- Constructor type
    
    1447
    +               -> Type     -- Scrutinee type
    
    1448
    +               -> Type     -- Constructor type
    
    1490 1449
                    -> [(Mult, OutVar)]    -- Binders
    
    1491 1450
                    -> LintM UsageEnv
    
    1492 1451
     -- If you edit this function, you may need to update the GHC formalism
    
    1493 1452
     -- See Note [GHC Formalism]
    
    1453
    +{-
    
    1454
    +lintAltBinders rhs_ue _case_bndr scrut_ty con_ty bndrs
    
    1455
    +  = do { (res_ty, rhs_ue') <- lintApp (text ".") lintTyBndr lintValBndr con_ty bndrs
    
    1456
    +       ; ensureEqTys res_ty scrut_ty (mkBadPatMsg con_ty scrut_ty)
    
    1457
    +       ; return rhs_ue }
    
    1458
    +-}
    
    1494 1459
     lintAltBinders rhs_ue _case_bndr scrut_ty con_ty []
    
    1495 1460
       = do { ensureEqTys con_ty scrut_ty (mkBadPatMsg con_ty scrut_ty)
    
    1496 1461
            ; return rhs_ue }
    
    ... ... @@ -1505,6 +1470,7 @@ lintAltBinders rhs_ue case_bndr scrut_ty con_ty ((var_w, bndr):bndrs)
    1505 1470
            ; rhs_ue' <- checkCaseLinearity rhs_ue case_bndr var_w bndr
    
    1506 1471
            ; lintAltBinders rhs_ue' case_bndr scrut_ty con_ty' bndrs }
    
    1507 1472
     
    
    1473
    +
    
    1508 1474
     -- | Implements the case rules for linearity
    
    1509 1475
     checkCaseLinearity :: UsageEnv -> Var -> Mult -> Var -> LintM UsageEnv
    
    1510 1476
     checkCaseLinearity ue case_bndr var_w bndr = do
    
    ... ... @@ -1529,7 +1495,7 @@ checkCaseLinearity ue case_bndr var_w bndr = do
    1529 1495
     
    
    1530 1496
     
    
    1531 1497
     -----------------
    
    1532
    -lintTyApp :: OutType -> OutType -> LintM OutType
    
    1498
    +lintTyApp :: Type -> Type -> LintM Type
    
    1533 1499
     lintTyApp fun_ty arg_ty
    
    1534 1500
       | Just (tv,body_ty) <- splitForAllTyVar_maybe fun_ty
    
    1535 1501
       = do  { lintTyKind tv arg_ty
    
    ... ... @@ -1547,8 +1513,8 @@ lintTyApp fun_ty arg_ty
    1547 1513
     -- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@
    
    1548 1514
     -- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the
    
    1549 1515
     -- application.
    
    1550
    -lintValApp :: CoreExpr -> OutType -> OutType -> UsageEnv -> UsageEnv
    
    1551
    -           -> LintM (OutType, UsageEnv)
    
    1516
    +lintValApp :: CoreExpr -> Type -> Type -> UsageEnv -> UsageEnv
    
    1517
    +           -> LintM (Type, UsageEnv)
    
    1552 1518
     lintValApp arg fun_ty arg_ty fun_ue arg_ue
    
    1553 1519
       | Just (_, w, arg_ty', res_ty') <- splitFunTy_maybe fun_ty
    
    1554 1520
       = do { ensureEqTys arg_ty' arg_ty (mkAppMsg arg_ty' arg_ty arg)
    
    ... ... @@ -1559,9 +1525,7 @@ lintValApp arg fun_ty arg_ty fun_ue arg_ue
    1559 1525
       where
    
    1560 1526
         err2 = mkNonFunAppMsg fun_ty arg_ty arg
    
    1561 1527
     
    
    1562
    -lintTyKind :: OutTyVar -> OutType -> LintM ()
    
    1563
    --- Both args have had substitution applied
    
    1564
    -
    
    1528
    +lintTyKind :: OutTyVar -> Type -> LintM ()
    
    1565 1529
     -- If you edit this function, you may need to update the GHC formalism
    
    1566 1530
     -- See Note [GHC Formalism]
    
    1567 1531
     lintTyKind tyvar arg_ty
    
    ... ... @@ -1579,36 +1543,36 @@ lintTyKind tyvar arg_ty
    1579 1543
     ************************************************************************
    
    1580 1544
     -}
    
    1581 1545
     
    
    1582
    -lintCaseExpr :: CoreExpr -> InId -> InType -> [CoreAlt] -> LintM (OutType, UsageEnv)
    
    1546
    +lintCaseExpr :: CoreExpr -> Id -> Type -> [CoreAlt] -> LintM (Type, UsageEnv)
    
    1583 1547
     lintCaseExpr scrut case_bndr alt_ty alts
    
    1584 1548
       = do { let e = Case scrut case_bndr alt_ty alts   -- Just for error messages
    
    1585 1549
     
    
    1586 1550
            -- Check the scrutinee
    
    1587
    -       ; (scrut_ty', scrut_ue) <- markAllJoinsBad $ lintCoreExpr scrut
    
    1551
    +       ; (scrut_ty, scrut_ue) <- markAllJoinsBad $ lintCoreExpr scrut
    
    1588 1552
                 -- See Note [Join points are less general than the paper]
    
    1589 1553
                 -- in GHC.Core
    
    1590 1554
     
    
    1591
    -       ; alt_ty' <- addLoc (CaseTy scrut) $ lintValueType alt_ty
    
    1555
    +       ; addLoc (CaseTy scrut) $ lintValueType alt_ty
    
    1592 1556
     
    
    1593
    -       ; checkCaseAlts e scrut scrut_ty' alts
    
    1557
    +       ; checkCaseAlts e scrut scrut_ty alts
    
    1594 1558
     
    
    1595 1559
            -- Lint the case-binder. Must do this after linting the scrutinee
    
    1596 1560
            -- because the case-binder isn't in scope in the scrutineex
    
    1597
    -       ; lintBinder CaseBind case_bndr $ \case_bndr' ->
    
    1561
    +       ; lintBinder CaseBind case_bndr $
    
    1598 1562
           -- Don't use lintIdBndr on case_bndr, because unboxed tuple is legitimate
    
    1599 1563
     
    
    1600
    -    do { let case_bndr_ty' = idType case_bndr'
    
    1601
    -             scrut_mult    = idMult case_bndr'
    
    1564
    +    do { let case_bndr_ty = idType case_bndr
    
    1565
    +             scrut_mult   = idMult case_bndr
    
    1602 1566
     
    
    1603
    -       ; ensureEqTys case_bndr_ty' scrut_ty' (mkScrutMsg case_bndr case_bndr_ty' scrut_ty')
    
    1567
    +       ; ensureEqTys case_bndr_ty scrut_ty (mkScrutMsg case_bndr case_bndr_ty scrut_ty)
    
    1604 1568
              -- See GHC.Core Note [Case expression invariants] item (7)
    
    1605 1569
     
    
    1606 1570
            ; -- Check the alternatives
    
    1607
    -       ; alt_ues <- mapM (lintCoreAlt case_bndr' scrut_ty' scrut_mult alt_ty') alts
    
    1571
    +       ; alt_ues <- mapM (lintCoreAlt case_bndr scrut_ty scrut_mult alt_ty) alts
    
    1608 1572
            ; let case_ue = (scaleUE scrut_mult scrut_ue) `addUE` supUEs alt_ues
    
    1609
    -       ; return (alt_ty', case_ue) } }
    
    1573
    +       ; return (alt_ty, case_ue) } }
    
    1610 1574
     
    
    1611
    -checkCaseAlts :: InExpr -> InExpr -> OutType -> [CoreAlt] -> LintM ()
    
    1575
    +checkCaseAlts :: CoreExpr -> CoreExpr -> Type -> [CoreAlt] -> LintM ()
    
    1612 1576
     -- a) Check that the alts are non-empty
    
    1613 1577
     -- b1) Check that the DEFAULT comes first, if it exists
    
    1614 1578
     -- b2) Check that the others are in increasing order
    
    ... ... @@ -1683,17 +1647,17 @@ checkCaseAlts e scrut scrut_ty alts
    1683 1647
         is_lit_alt (Alt (LitAlt _) _  _) = True
    
    1684 1648
         is_lit_alt _                     = False
    
    1685 1649
     
    
    1686
    -lintAltExpr :: CoreExpr -> OutType -> LintM UsageEnv
    
    1650
    +lintAltExpr :: CoreExpr -> Type -> LintM UsageEnv
    
    1687 1651
     lintAltExpr expr ann_ty
    
    1688 1652
       = do { (actual_ty, ue) <- lintCoreExpr expr
    
    1689 1653
            ; ensureEqTys actual_ty ann_ty (mkCaseAltMsg expr actual_ty ann_ty)
    
    1690 1654
            ; return ue }
    
    1691 1655
              -- See GHC.Core Note [Case expression invariants] item (6)
    
    1692 1656
     
    
    1693
    -lintCoreAlt :: OutId         -- Case binder
    
    1694
    -            -> OutType       -- Type of scrutinee
    
    1657
    +lintCoreAlt :: Id         -- Case binder
    
    1658
    +            -> Type       -- Type of scrutinee
    
    1695 1659
                 -> Mult          -- Multiplicity of scrutinee
    
    1696
    -            -> OutType       -- Type of the alternative
    
    1660
    +            -> Type       -- Type of the alternative
    
    1697 1661
                 -> CoreAlt
    
    1698 1662
                 -> LintM UsageEnv
    
    1699 1663
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -1738,11 +1702,11 @@ lintCoreAlt case_bndr scrut_ty _scrut_mult alt_ty alt@(Alt (DataAlt con) args rh
    1738 1702
               ; multiplicities = map binderMult $ fst $ splitPiTys con_payload_ty }
    
    1739 1703
     
    
    1740 1704
             -- And now bring the new binders into scope
    
    1741
    -    ; lintBinders CasePatBind args $ \ args' -> do
    
    1705
    +    ; lintBinders CasePatBind args $ do
    
    1742 1706
           { rhs_ue <- lintAltExpr rhs alt_ty
    
    1743 1707
           ; rhs_ue' <- addLoc (CasePat alt) $
    
    1744 1708
                        lintAltBinders rhs_ue case_bndr scrut_ty con_payload_ty
    
    1745
    -                                  (zipEqual multiplicities  args')
    
    1709
    +                                  (zipEqual multiplicities  args)
    
    1746 1710
           ; return $ deleteUE rhs_ue' case_bndr
    
    1747 1711
           }
    
    1748 1712
        }
    
    ... ... @@ -1784,54 +1748,52 @@ lintLinearBinder doc actual_usage described_usage
    1784 1748
     -}
    
    1785 1749
     
    
    1786 1750
     -- When we lint binders, we (one at a time and in order):
    
    1787
    ---  1. Lint var types or kinds (possibly substituting)
    
    1788
    ---  2. Add the binder to the in scope set, and if its a coercion var,
    
    1789
    ---     we may extend the substitution to reflect its (possibly) new kind
    
    1790
    -lintBinders :: HasDebugCallStack => BindingSite -> [InVar] -> ([OutVar] -> LintM a) -> LintM a
    
    1791
    -lintBinders _    []         linterF = linterF []
    
    1792
    -lintBinders site (var:vars) linterF = lintBinder site var $ \var' ->
    
    1793
    -                                      lintBinders site vars $ \ vars' ->
    
    1794
    -                                      linterF (var':vars')
    
    1751
    +--  1. Lint var types or kinds
    
    1752
    +--  2. Add the binder to the in scope set
    
    1753
    +lintBinders :: HasDebugCallStack => BindingSite -> [Var] -> LintM a -> LintM a
    
    1754
    +lintBinders _    []         linterF = linterF
    
    1755
    +lintBinders site (var:vars) linterF = lintBinder site var $
    
    1756
    +                                      lintBinders site vars $
    
    1757
    +                                      linterF
    
    1795 1758
     
    
    1796 1759
     -- If you edit this function, you may need to update the GHC formalism
    
    1797 1760
     -- See Note [GHC Formalism]
    
    1798
    -lintBinder :: HasDebugCallStack => BindingSite -> InVar -> (OutVar -> LintM a) -> LintM a
    
    1761
    +lintBinder :: HasDebugCallStack => BindingSite -> Var -> LintM a -> LintM a
    
    1799 1762
     lintBinder site var linterF
    
    1800 1763
       | isTyCoVar var = lintTyCoBndr var linterF
    
    1801 1764
       | otherwise     = lintIdBndr NotTopLevel site var linterF
    
    1802 1765
     
    
    1803
    -lintTyCoBndr :: HasDebugCallStack => TyCoVar -> (OutTyCoVar -> LintM a) -> LintM a
    
    1766
    +lintTyCoBndr :: HasDebugCallStack => TyCoVar -> LintM a -> LintM a
    
    1804 1767
     lintTyCoBndr tcv thing_inside
    
    1805
    -  = do { tcv_type' <- lintTypeAndSubst (varType tcv)
    
    1806
    -       ; let tcv_kind' = typeKind tcv_type'
    
    1768
    +  = do { let tcv_type = varType tcv
    
    1769
    +             tcv_kind = typeKind tcv_type
    
    1807 1770
     
    
    1771
    +       ; lintType (varType tcv)
    
    1808 1772
              -- See (FORALL1) and (FORALL2) in GHC.Core.Type
    
    1809 1773
            ; if (isTyVar tcv)
    
    1810 1774
              then -- Check that in (forall (a:ki). blah) we have ki:Type
    
    1811
    -              lintL (isLiftedTypeKind tcv_kind') $
    
    1775
    +              lintL (isLiftedTypeKind tcv_kind) $
    
    1812 1776
                   hang (text "TyVar whose kind does not have kind Type:")
    
    1813
    -                 2 (ppr tcv <+> dcolon <+> ppr tcv_type' <+> dcolon <+> ppr tcv_kind')
    
    1777
    +                 2 (ppr tcv <+> dcolon <+> ppr tcv_type <+> dcolon <+> ppr tcv_kind)
    
    1814 1778
              else -- Check that in (forall (cv::ty). blah),
    
    1815 1779
                   -- then ty looks like (t1 ~# t2)
    
    1816
    -              lintL (isCoVarType tcv_type') $
    
    1780
    +              lintL (isCoVarType tcv_type) $
    
    1817 1781
                   text "CoVar with non-coercion type:" <+> pprTyVar tcv
    
    1818 1782
     
    
    1819
    -       ; addInScopeTyCoVar tcv tcv_type' thing_inside }
    
    1783
    +       ; addInScopeTyCoVar tcv thing_inside }
    
    1820 1784
     
    
    1821
    -lintIdBndrs :: forall a. TopLevelFlag -> [InId] -> ([OutId] -> LintM a) -> LintM a
    
    1785
    +lintIdBndrs :: forall a. TopLevelFlag -> [Id] -> LintM a -> LintM a
    
    1822 1786
     lintIdBndrs top_lvl ids thing_inside
    
    1823 1787
       = go ids thing_inside
    
    1824 1788
       where
    
    1825
    -    go :: [Id] -> ([Id] -> LintM a) -> LintM a
    
    1826
    -    go []       thing_inside = thing_inside []
    
    1827
    -    go (id:ids) thing_inside = lintIdBndr top_lvl LetBind id  $ \id' ->
    
    1828
    -                               go ids                         $ \ids' ->
    
    1829
    -                               thing_inside (id' : ids')
    
    1789
    +    go :: [Id] -> LintM a -> LintM a
    
    1790
    +    go []       thing_inside = thing_inside
    
    1791
    +    go (id:ids) thing_inside = lintIdBndr top_lvl LetBind id  $
    
    1792
    +                               go ids                         $
    
    1793
    +                               thing_inside
    
    1830 1794
     
    
    1831 1795
     lintIdBndr :: TopLevelFlag -> BindingSite
    
    1832
    -           -> InVar -> (OutVar -> LintM a) -> LintM a
    
    1833
    --- Do substitution on the type of a binder and add the var with this
    
    1834
    --- new type to the in-scope set of the second argument
    
    1796
    +           -> Var -> LintM a -> LintM a
    
    1835 1797
     -- ToDo: lint its rules
    
    1836 1798
     lintIdBndr top_lvl bind_site id thing_inside
    
    1837 1799
       = assertPpr (isId id) (ppr id) $
    
    ... ... @@ -1869,9 +1831,9 @@ lintIdBndr top_lvl bind_site id thing_inside
    1869 1831
            ; lintL (not (bind_site == LambdaBind && isEvaldUnfolding (idUnfolding id)))
    
    1870 1832
                     (text "Lambda binder with value or OtherCon unfolding.")
    
    1871 1833
     
    
    1872
    -       ; out_ty <- addLoc (IdTy id) (lintValueType id_ty)
    
    1834
    +       ; addLoc (IdTy id) (lintValueType id_ty)
    
    1873 1835
     
    
    1874
    -       ; addInScopeId id out_ty thing_inside }
    
    1836
    +       ; addInScopeId id thing_inside }
    
    1875 1837
       where
    
    1876 1838
         id_ty = idType id
    
    1877 1839
     
    
    ... ... @@ -1891,62 +1853,44 @@ lintIdBndr top_lvl bind_site id thing_inside
    1891 1853
     {- Note [Linting types and coercions]
    
    1892 1854
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1893 1855
     Notice that
    
    1894
    -   lintType     :: InType     -> LintM ()
    
    1895
    -   lintCoercion :: InCoercion -> LintM ()
    
    1856
    +   lintType     :: Type     -> LintM ()
    
    1857
    +   lintCoercion :: Coercion -> LintM ()
    
    1896 1858
     Neither returns anything.
    
    1897 1859
     
    
    1898
    -If you need the kind of the type, then do `typeKind` and then apply
    
    1899
    -the ambient substitution using `substTyM`.  Note that the substitution
    
    1900
    -empty unless there is shadowing or type-lets; and if the substitution is
    
    1901
    -empty, the `substTyM` is a no-op.
    
    1902
    -
    
    1903
    -It is better to take the kind and then substitute, rather than substitute
    
    1904
    -and then take the kind, becaues the kind is usually smaller.
    
    1905
    -
    
    1906
    -Note: you might wonder if we should apply the same logic to expressions.
    
    1907
    -Why do we have
    
    1908
    -  lintExpr :: InExpr -> LintM OutType
    
    1909
    -Partly inertia; but also taking the type of an expresison involve looking
    
    1910
    -down a deep chain of let's, whereas that is not true of taking the kind
    
    1911
    -of a type.  It'd be worth an experiment though.
    
    1912
    -
    
    1913
    -Historical note: in the olden days we had
    
    1914
    -   lintType :: InType -> LintM OutType
    
    1915
    -but that burned a huge amount of allocation building an OutType that was
    
    1916
    -often discarded, or used only to get its kind.
    
    1917
    -
    
    1918
    -I also experimented with
    
    1919
    -   lintType :: InType -> LintM OutKind
    
    1920
    -but that too was slower.  It is also much simpler to return ()!  If we
    
    1921
    -return the kind we have to duplicate the logic in `typeKind`; and it is
    
    1922
    -much worse for coercions.
    
    1860
    +Note: you might wonder why we have
    
    1861
    +  lintExpr :: CoreExpr -> LintM Type
    
    1862
    +  lintType :: Type     -> LintM ()
    
    1863
    +
    
    1864
    +That is, linting an expression yields its type, but linting a type does not
    
    1865
    +yield its kind. Partly inertia; but:
    
    1866
    +
    
    1867
    +* Taking the type of an expresison involves looking down a deep chain of let's,
    
    1868
    +  whereas that is not true of taking the kind of a type.  It'd be worth an
    
    1869
    +  experiment though.
    
    1870
    +
    
    1871
    +* I did experiment with
    
    1872
    +   lintType :: Type -> LintM Kind
    
    1873
    +  but that too was slower.  It is also much simpler to return ()!  If we return
    
    1874
    +  the kind we have to duplicate the logic in `typeKind`; and it is much worse
    
    1875
    +  for coercions.
    
    1923 1876
     -}
    
    1924 1877
     
    
    1925
    -lintValueType :: Type -> LintM OutType
    
    1878
    +lintValueType :: Type -> LintM ()
    
    1926 1879
     -- Types only, not kinds
    
    1927
    --- Check the type, and apply the substitution to it
    
    1928
    --- See Note [Linting type lets]
    
    1929 1880
     lintValueType ty
    
    1930 1881
       = addLoc (InType ty) $
    
    1931
    -    do  { ty' <- lintTypeAndSubst ty
    
    1932
    -        ; let sk = typeKind ty'
    
    1882
    +    do  { lintType ty
    
    1883
    +        ; let sk = typeKind ty
    
    1933 1884
             ; lintL (isTYPEorCONSTRAINT sk) $
    
    1934 1885
               hang (text "Ill-kinded type:" <+> ppr ty)
    
    1935
    -             2 (text "has kind:" <+> ppr sk)
    
    1936
    -        ; return ty' }
    
    1886
    +             2 (text "has kind:" <+> ppr sk)}
    
    1937 1887
     
    
    1938 1888
     checkTyCon :: TyCon -> LintM ()
    
    1939 1889
     checkTyCon tc
    
    1940 1890
       = checkL (not (isTcTyCon tc)) (text "Found TcTyCon:" <+> ppr tc)
    
    1941 1891
     
    
    1942 1892
     -------------------
    
    1943
    -lintTypeAndSubst :: InType -> LintM OutType
    
    1944
    -lintTypeAndSubst ty = do { lintType ty; substTyM ty }
    
    1945
    -           -- In GHCi we may lint an expression with a free
    
    1946
    -           -- type variable.  Then it won't be in the
    
    1947
    -           -- substitution, but it should be in scope
    
    1948
    -
    
    1949
    -lintType :: InType -> LintM ()
    
    1893
    +lintType :: Type -> LintM ()
    
    1950 1894
     -- See Note [Linting types and coercions]
    
    1951 1895
     --
    
    1952 1896
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -1956,8 +1900,7 @@ lintType (TyVarTy tv)
    1956 1900
       = failWithL (mkBadTyVarMsg tv)
    
    1957 1901
     
    
    1958 1902
       | otherwise
    
    1959
    -  = do { _ <- lintVarOcc tv
    
    1960
    -       ; return () }
    
    1903
    +  = lintVarOcc tv
    
    1961 1904
     
    
    1962 1905
     lintType ty@(AppTy t1 t2)
    
    1963 1906
       | TyConApp {} <- t1
    
    ... ... @@ -1965,7 +1908,7 @@ lintType ty@(AppTy t1 t2)
    1965 1908
       | otherwise
    
    1966 1909
       = do { let (fun_ty, arg_tys) = collect t1 [t2]
    
    1967 1910
            ; lintType fun_ty
    
    1968
    -       ; fun_kind <- substTyM (typeKind fun_ty)
    
    1911
    +       ; let fun_kind = typeKind fun_ty
    
    1969 1912
            ; lint_ty_app ty fun_kind arg_tys }
    
    1970 1913
       where
    
    1971 1914
         collect (AppTy f a) as = collect f (a:as)
    
    ... ... @@ -1997,21 +1940,21 @@ lintType ty@(FunTy af tw t1 t2)
    1997 1940
     lintType ty@(ForAllTy {})
    
    1998 1941
       = go [] ty
    
    1999 1942
       where
    
    2000
    -    go :: [OutTyCoVar] -> InType -> LintM ()
    
    1943
    +    go :: [OutTyCoVar] -> Type -> LintM ()
    
    2001 1944
         -- Loop, collecting the forall-binders
    
    2002 1945
         go tcvs ty@(ForAllTy (Bndr tcv _) body_ty)
    
    2003 1946
           | not (isTyCoVar tcv)
    
    2004 1947
           = failWithL (text "Non-TyVar or Non-CoVar bound in type:" <+> ppr ty)
    
    2005 1948
     
    
    2006 1949
           | otherwise
    
    2007
    -      = lintTyCoBndr tcv $ \tcv' ->
    
    1950
    +      = lintTyCoBndr tcv $
    
    2008 1951
             do { -- See GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy]
    
    2009 1952
                  -- Suspicious because it works on InTyCoVar; c.f. ForAllCo
    
    2010 1953
                  when (isCoVar tcv) $
    
    2011 1954
                  lintL (anyFreeVarsOfType (== tcv) body_ty) $
    
    2012 1955
                  text "Covar does not occur in the body:" <+> (ppr tcv $$ ppr body_ty)
    
    2013 1956
     
    
    2014
    -           ; go (tcv' : tcvs) body_ty }
    
    1957
    +           ; go (tcv : tcvs) body_ty }
    
    2015 1958
     
    
    2016 1959
         go tcvs body_ty
    
    2017 1960
           = do { lintType body_ty
    
    ... ... @@ -2019,7 +1962,7 @@ lintType ty@(ForAllTy {})
    2019 1962
     
    
    2020 1963
     lintType (CastTy ty co)
    
    2021 1964
       = do { lintType ty
    
    2022
    -       ; ty_kind <- substTyM (typeKind ty)
    
    1965
    +       ; let ty_kind = typeKind ty
    
    2023 1966
            ; co_lk <- lintStarCoercion co
    
    2024 1967
            ; ensureEqTys ty_kind co_lk (mkCastTyErr ty co ty_kind co_lk) }
    
    2025 1968
     
    
    ... ... @@ -2027,14 +1970,14 @@ lintType (LitTy l) = lintTyLit l
    2027 1970
     lintType (CoercionTy co) = lintCoercion co
    
    2028 1971
     
    
    2029 1972
     -----------------
    
    2030
    -lintForAllBody :: [OutTyCoVar] -> InType -> LintM ()
    
    1973
    +lintForAllBody :: [OutTyCoVar] -> Type -> LintM ()
    
    2031 1974
     -- Do the checks for the body of a forall-type
    
    2032 1975
     lintForAllBody tcvs body_ty
    
    2033 1976
       = do { -- For type variables, check for skolem escape
    
    2034 1977
              -- See Note [Phantom type variables in kinds] in GHC.Core.Type
    
    2035 1978
              -- The kind of (forall cv. th) is liftedTypeKind, so no
    
    2036 1979
              -- need to check for skolem-escape in the CoVar case
    
    2037
    -         body_kind <- substTyM (typeKind body_ty)
    
    1980
    +         let body_kind = typeKind body_ty
    
    2038 1981
            ; case occCheckExpand tcvs body_kind of
    
    2039 1982
                Just {} -> return ()
    
    2040 1983
                Nothing -> failWithL $
    
    ... ... @@ -2045,7 +1988,7 @@ lintForAllBody tcvs body_ty
    2045 1988
            ; checkValueType body_kind (text "the body of forall:" <+> ppr body_ty) }
    
    2046 1989
     
    
    2047 1990
     -----------------
    
    2048
    -lintTySynFamApp :: Bool -> InType -> TyCon -> [InType] -> LintM ()
    
    1991
    +lintTySynFamApp :: Bool -> Type -> TyCon -> [Type] -> LintM ()
    
    2049 1992
     -- The TyCon is a type synonym or a type family (not a data family)
    
    2050 1993
     -- See Note [Linting type synonym applications]
    
    2051 1994
     -- c.f. GHC.Tc.Validity.check_syn_tc_app
    
    ... ... @@ -2071,21 +2014,21 @@ lintTySynFamApp report_unsat ty tc tys
    2071 2014
     
    
    2072 2015
     -----------------
    
    2073 2016
     -- Confirms that a kind is really TYPE r or Constraint
    
    2074
    -checkValueType :: OutKind -> SDoc -> LintM ()
    
    2017
    +checkValueType :: Kind -> SDoc -> LintM ()
    
    2075 2018
     checkValueType kind doc
    
    2076 2019
       = lintL (isTYPEorCONSTRAINT kind)
    
    2077 2020
               (text "Non-Type-like kind when Type-like expected:" <+> ppr kind $$
    
    2078 2021
                text "when checking" <+> doc)
    
    2079 2022
     
    
    2080 2023
     -----------------
    
    2081
    -lintArrow :: SDoc -> FunTyFlag -> InType -> InType -> InType -> LintM ()
    
    2024
    +lintArrow :: SDoc -> FunTyFlag -> Type -> Type -> Type -> LintM ()
    
    2082 2025
     -- If you edit this function, you may need to update the GHC formalism
    
    2083 2026
     -- See Note [GHC Formalism]
    
    2084 2027
     lintArrow what af t1 t2 tw  -- Eg lintArrow "type or kind `blah'" k1 k2 kw
    
    2085 2028
                                 -- or lintArrow "coercion `blah'" k1 k2 kw
    
    2086
    -  = do { k1 <- substTyM (typeKind t1)
    
    2087
    -       ; k2 <- substTyM (typeKind t2)
    
    2088
    -       ; kw <- substTyM (typeKind tw)
    
    2029
    +  = do { let k1 = typeKind t1
    
    2030
    +             k2 = typeKind t2
    
    2031
    +             kw = typeKind tw
    
    2089 2032
            ; unless (isTYPEorCONSTRAINT k1) (report (text "argument")     t1 k1)
    
    2090 2033
            ; unless (isTYPEorCONSTRAINT k2) (report (text "result")       t2 k2)
    
    2091 2034
            ; unless (isMultiplicityTy kw)   (report (text "multiplicity") tw kw)
    
    ... ... @@ -2111,29 +2054,29 @@ lintTyLit (StrTyLit _) = return ()
    2111 2054
     lintTyLit (CharTyLit _) = return ()
    
    2112 2055
     
    
    2113 2056
     -----------------
    
    2114
    -lint_ty_app :: InType -> OutKind -> [InType] -> LintM ()
    
    2057
    +lint_ty_app :: Type -> Kind -> [Type] -> LintM ()
    
    2115 2058
     lint_ty_app ty = lint_tyco_app (text "type" <+> quotes (ppr ty))
    
    2116 2059
     
    
    2117
    -lint_co_app :: HasDebugCallStack => Coercion -> OutKind -> [InType] -> LintM ()
    
    2060
    +lint_co_app :: HasDebugCallStack => Coercion -> Kind -> [Type] -> LintM ()
    
    2118 2061
     lint_co_app co = lint_tyco_app (text "coercion" <+> quotes (ppr co))
    
    2119 2062
     
    
    2120
    -lint_tyco_app :: SDoc -> OutKind -> [InType] -> LintM ()
    
    2063
    +lint_tyco_app :: SDoc -> Kind -> [Type] -> LintM ()
    
    2121 2064
     lint_tyco_app msg fun_kind arg_tys
    
    2122 2065
         -- See Note [Avoiding compiler perf traps when constructing error messages.]
    
    2123
    -  = do { _ <- lintApp msg (\ty     -> do { lintType ty; substTyM ty })
    
    2124
    -                            (\ty _ _ -> do { lintType ty; ki <- substTyM (typeKind ty); return (ki,()) })
    
    2125
    -                            fun_kind arg_tys ()
    
    2066
    +  = do { _ <- lintApp msg (\ty     -> do { lintType ty; return ty })
    
    2067
    +                          (\ty _ _ -> do { lintType ty; return (typeKind ty,()) })
    
    2068
    +                          fun_kind arg_tys ()
    
    2126 2069
            ; return () }
    
    2127 2070
     
    
    2128 2071
     ----------------
    
    2129 2072
     lintApp :: forall in_a acc. Outputable in_a =>
    
    2130 2073
                  SDoc
    
    2131
    -          -> (in_a -> LintM OutType)                        -- Lint the thing and return its value
    
    2132
    -          -> (in_a -> Mult -> acc -> LintM (OutKind, acc))  -- Lint the thing and return its type
    
    2133
    -          -> OutType
    
    2074
    +          -> (in_a -> LintM Type)                        -- Lint the thing and return its value
    
    2075
    +          -> (in_a -> Mult -> acc -> LintM (Kind, acc))  -- Lint the thing and return its type
    
    2076
    +          -> Type
    
    2134 2077
               -> [in_a]                               -- The arguments, always "In" things
    
    2135 2078
               -> acc                                  -- Used (only) for UsageEnv in /term/ applications
    
    2136
    -          -> LintM (OutType,acc)
    
    2079
    +          -> LintM (Type,acc)
    
    2137 2080
     -- lintApp is a performance-critical function, which deals with multiple
    
    2138 2081
     -- applications such as  (/\a./\b./\c. expr) @ta @tb @tc
    
    2139 2082
     -- When returning the type of this expression we want to avoid substituting a:=ta,
    
    ... ... @@ -2158,7 +2101,7 @@ lintApp msg lint_forall_arg lint_arrow_arg !orig_fun_ty all_args acc
    2158 2101
     
    
    2159 2102
              ; let init_subst = mkEmptySubst in_scope
    
    2160 2103
     
    
    2161
    -               go :: Subst -> OutType -> acc -> [in_a] -> LintM (OutType, acc)
    
    2104
    +               go :: Subst -> Type -> acc -> [in_a] -> LintM (Type, acc)
    
    2162 2105
                          -- The Subst applies (only) to the fun_ty
    
    2163 2106
                          -- c.f. GHC.Core.Type.piResultTys, which has a similar loop
    
    2164 2107
     
    
    ... ... @@ -2202,7 +2145,7 @@ lintApp msg lint_forall_arg lint_arrow_arg !orig_fun_ty all_args acc
    2202 2145
     -- explicitly and don't capture them as free variables. Otherwise this binder might
    
    2203 2146
     -- become a thunk that get's allocated in the hot code path.
    
    2204 2147
     -- See Note [Avoiding compiler perf traps when constructing error messages.]
    
    2205
    -lint_app_fail_msg :: (Outputable a2) => SDoc -> OutType -> a2 -> SDoc -> SDoc
    
    2148
    +lint_app_fail_msg :: (Outputable a2) => SDoc -> Type -> a2 -> SDoc -> SDoc
    
    2206 2149
     lint_app_fail_msg msg kfn arg_tys extra
    
    2207 2150
       = vcat [ hang (text "Application error in") 2 msg
    
    2208 2151
              , nest 2 (text "Function type =" <+> ppr kfn)
    
    ... ... @@ -2215,7 +2158,7 @@ lint_app_fail_msg msg kfn arg_tys extra
    2215 2158
     *                                                                      *
    
    2216 2159
     ********************************************************************* -}
    
    2217 2160
     
    
    2218
    -lintCoreRule :: OutVar -> OutType -> CoreRule -> LintM ()
    
    2161
    +lintCoreRule :: OutVar -> Type -> CoreRule -> LintM ()
    
    2219 2162
     lintCoreRule _ _ (BuiltinRule {})
    
    2220 2163
       = return ()  -- Don't bother
    
    2221 2164
     
    
    ... ... @@ -2223,7 +2166,7 @@ lintCoreRule fun fun_ty rule@(Rule { ru_name = name, ru_bndrs = bndrs
    2223 2166
                                        , ru_args = args, ru_rhs = rhs })
    
    2224 2167
       = noMultiplicityChecks $ -- Skip linearity checking for rules
    
    2225 2168
                                -- See Note [Linting linearity]
    
    2226
    -    lintBinders LambdaBind bndrs $ \ _ ->
    
    2169
    +    lintBinders LambdaBind bndrs $
    
    2227 2170
         do { (lhs_ty, _) <- lintCoreArgs (fun_ty, zeroUE) args
    
    2228 2171
            ; (rhs_ty, _) <- case idJoinPointHood fun of
    
    2229 2172
                          JoinPoint join_arity
    
    ... ... @@ -2311,10 +2254,10 @@ Note [Join points and unfoldings/rules] in "GHC.Core.Opt.OccurAnal" for further
    2311 2254
     
    
    2312 2255
     {- Note [Asymptotic efficiency]
    
    2313 2256
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2314
    -When linting coercions (and types actually) we return a linted
    
    2315
    -(substituted) coercion.  Then we often have to take the coercionKind of
    
    2316
    -that returned coercion. If we get long chains, that can be asymptotically
    
    2317
    -inefficient, notably in
    
    2257
    +When linting coercions we traverse the coercion. Then we often have to take the
    
    2258
    +coercionKind of that returned coercion. If we get long chains, that can be
    
    2259
    +asymptotically inefficient, notably in
    
    2260
    +
    
    2318 2261
     * TransCo
    
    2319 2262
     * InstCo
    
    2320 2263
     * SelCo (cf #9233)
    
    ... ... @@ -2326,30 +2269,23 @@ the bad perf bites us in practice.
    2326 2269
     A solution would be to return the kind and role of the coercion,
    
    2327 2270
     as well as the linted coercion.  Or perhaps even *only* the kind and role,
    
    2328 2271
     which is what used to happen.   But that proved tricky and error prone
    
    2329
    -(#17923), so now we return the coercion.
    
    2272
    +(#17923).
    
    2330 2273
     -}
    
    2331 2274
     
    
    2332 2275
     
    
    2333 2276
     -- lintStarCoercion lints a coercion, confirming that its lh kind and
    
    2334 2277
     -- its rh kind are both *; also ensures that the role is Nominal
    
    2335 2278
     -- Returns the lh kind
    
    2336
    -lintStarCoercion :: InCoercion -> LintM OutType
    
    2279
    +lintStarCoercion :: Coercion -> LintM Type
    
    2337 2280
     lintStarCoercion g
    
    2338 2281
       = do { lintCoercion g
    
    2339
    -       ; Pair t1 t2 <- substCoKindM g
    
    2282
    +       ; let Pair t1 t2 = coercionKind g
    
    2340 2283
            ; checkValueType (typeKind t1) (text "the kind of the left type in" <+> ppr g)
    
    2341 2284
            ; checkValueType (typeKind t2) (text "the kind of the right type in" <+> ppr g)
    
    2342 2285
            ; lintRole g Nominal (coercionRole g)
    
    2343 2286
            ; return t1 }
    
    2344 2287
     
    
    2345
    -substCoKindM :: InCoercion -> LintM (Pair OutType)
    
    2346
    -substCoKindM co
    
    2347
    -  = do { let !(Pair lk rk) = coercionKind co
    
    2348
    -       ; lk' <- substTyM lk
    
    2349
    -       ; rk' <- substTyM rk
    
    2350
    -       ; return (Pair lk' rk') }
    
    2351
    -
    
    2352
    -lintCoercion :: HasDebugCallStack => InCoercion -> LintM ()
    
    2288
    +lintCoercion :: HasDebugCallStack => Coercion -> LintM ()
    
    2353 2289
     -- See Note [Linting types and coercions]
    
    2354 2290
     --
    
    2355 2291
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -2361,7 +2297,7 @@ lintCoercion (CoVarCo cv)
    2361 2297
                       2 (text "With offending type:" <+> ppr (varType cv)))
    
    2362 2298
     
    
    2363 2299
       | otherwise  -- C.f. lintType (TyVarTy tv), which has better docs
    
    2364
    -  = do { _ <- lintVarOcc cv; return () }
    
    2300
    +  = lintVarOcc cv
    
    2365 2301
     
    
    2366 2302
     lintCoercion (Refl ty)          = lintType ty
    
    2367 2303
     lintCoercion (GRefl _r ty MRefl) = lintType ty
    
    ... ... @@ -2369,8 +2305,8 @@ lintCoercion (GRefl _r ty MRefl) = lintType ty
    2369 2305
     lintCoercion (GRefl _r ty (MCo co))
    
    2370 2306
       = do { lintType ty
    
    2371 2307
            ; lintCoercion co
    
    2372
    -       ; tk <- substTyM (typeKind ty)
    
    2373
    -       ; tl <- substTyM (coercionLKind co)
    
    2308
    +       ; let tk = typeKind ty
    
    2309
    +             tl = coercionLKind co
    
    2374 2310
            ; ensureEqTys tk tl $
    
    2375 2311
              hang (text "GRefl coercion kind mis-match:" <+> ppr co)
    
    2376 2312
                 2 (vcat [ppr ty, ppr tk, ppr tl])
    
    ... ... @@ -2403,8 +2339,8 @@ lintCoercion co@(AppCo co1 co2)
    2403 2339
       = do { lintCoercion co1
    
    2404 2340
            ; lintCoercion co2
    
    2405 2341
            ; let !(Pair lt1 rt1) = coercionKind co1
    
    2406
    -       ; lk1 <- substTyM (typeKind lt1)
    
    2407
    -       ; rk1 <- substTyM (typeKind rt1)
    
    2342
    +             lk1 = typeKind lt1
    
    2343
    +             rk1 = typeKind rt1
    
    2408 2344
            ; lint_co_app co lk1 [coercionLKind co2]
    
    2409 2345
            ; lint_co_app co rk1 [coercionRKind co2]
    
    2410 2346
     
    
    ... ... @@ -2421,7 +2357,7 @@ lintCoercion co@(ForAllCo {})
    2421 2357
       = do { _ <- go [] co; return () }
    
    2422 2358
       where
    
    2423 2359
         go :: [OutTyCoVar]   -- Binders in reverse order
    
    2424
    -       -> InCoercion -> LintM Role
    
    2360
    +       -> Coercion -> LintM Role
    
    2425 2361
         go tcvs co@(ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
    
    2426 2362
                              , fco_kind = kind_mco, fco_body = body_co })
    
    2427 2363
           | not (isTyCoVar tcv)
    
    ... ... @@ -2431,15 +2367,15 @@ lintCoercion co@(ForAllCo {})
    2431 2367
           = do { mb_lk <- case kind_mco of
    
    2432 2368
                          MRefl -> return Nothing
    
    2433 2369
                          MCo kind_co -> Just <$> lintStarCoercion kind_co
    
    2434
    -           ; lintTyCoBndr tcv $ \tcv' ->
    
    2370
    +           ; lintTyCoBndr tcv $
    
    2435 2371
             do { case mb_lk of
    
    2436 2372
                     Nothing -> return ()
    
    2437
    -                Just lk -> ensureEqTys (varType tcv') lk $
    
    2373
    +                Just lk -> ensureEqTys (varType tcv) lk $
    
    2438 2374
                                text "Kind mis-match in ForallCo" <+> ppr co
    
    2439 2375
     
    
    2440 2376
                -- I'm not very sure about this part, because it traverses body_co
    
    2441 2377
                -- but at least it's on a cold path (a ForallCo for a CoVar)
    
    2442
    -           -- Also it works on InTyCoVar and InCoercion, which is suspect
    
    2378
    +           -- Also it works on InTyCoVar and Coercion, which is suspect
    
    2443 2379
                ; when (isCoVar tcv) $
    
    2444 2380
                  do { lintL (visL == coreTyLamForAllTyFlag && visR == coreTyLamForAllTyFlag) $
    
    2445 2381
                       text "Invalid visibility flags in CoVar ForAllCo" <+> ppr co
    
    ... ... @@ -2448,7 +2384,7 @@ lintCoercion co@(ForAllCo {})
    2448 2384
                       text "Covar can only appear in Refl and GRefl: " <+> ppr co }
    
    2449 2385
                       -- See (FC6) in Note [ForAllCo] in GHC.Core.TyCo.Rep
    
    2450 2386
     
    
    2451
    -           ; role <- go (tcv':tcvs) body_co
    
    2387
    +           ; role <- go (tcv:tcvs) body_co
    
    2452 2388
     
    
    2453 2389
                ; when (role == Nominal) $
    
    2454 2390
                  lintL (visL `eqForAllVis` visR) $
    
    ... ... @@ -2505,8 +2441,8 @@ lintCoercion co@(UnivCo { uco_role = r, uco_prov = prov
    2505 2441
            -- Check the to and from types
    
    2506 2442
            ; lintType ty1
    
    2507 2443
            ; lintType ty2
    
    2508
    -       ; tk1 <- substTyM (typeKind ty1)
    
    2509
    -       ; tk2 <- substTyM (typeKind ty2)
    
    2444
    +       ; let tk1 = typeKind ty1
    
    2445
    +             tk2 = typeKind ty2
    
    2510 2446
     
    
    2511 2447
            ; when (r /= Phantom && isTYPEorCONSTRAINT tk1 && isTYPEorCONSTRAINT tk2)
    
    2512 2448
                   (checkTypes ty1 ty2)
    
    ... ... @@ -2560,8 +2496,8 @@ lintCoercion (SymCo co) = lintCoercion co
    2560 2496
     lintCoercion co@(TransCo co1 co2)
    
    2561 2497
       = do { lintCoercion co1
    
    2562 2498
            ; lintCoercion co2
    
    2563
    -       ; rk1 <- substTyM (coercionRKind co1)
    
    2564
    -       ; lk2 <- substTyM (coercionLKind co2)
    
    2499
    +       ; let rk1 = coercionRKind co1
    
    2500
    +             lk2 = coercionLKind co2
    
    2565 2501
            ; ensureEqTys rk1 lk2
    
    2566 2502
                    (hang (text "Trans coercion mis-match:" <+> ppr co)
    
    2567 2503
                        2 (vcat [ppr (coercionKind co1), ppr (coercionKind co2)]))
    
    ... ... @@ -2569,7 +2505,7 @@ lintCoercion co@(TransCo co1 co2)
    2569 2505
     
    
    2570 2506
     lintCoercion the_co@(SelCo cs co)
    
    2571 2507
       = do { lintCoercion co
    
    2572
    -       ; Pair s t <- substCoKindM co
    
    2508
    +       ; let Pair s t = coercionKind co
    
    2573 2509
     
    
    2574 2510
            ; if -- forall (both TyVar and CoVar)
    
    2575 2511
                 | Just _ <- splitForAllTyCoVar_maybe s
    
    ... ... @@ -2604,7 +2540,7 @@ lintCoercion the_co@(SelCo cs co)
    2604 2540
     
    
    2605 2541
     lintCoercion the_co@(LRCo _lr co)
    
    2606 2542
       = do { lintCoercion co
    
    2607
    -       ; Pair s t <- substCoKindM co
    
    2543
    +       ; let Pair s t = coercionKind co
    
    2608 2544
            ; lintRole co Nominal (coercionRole co)
    
    2609 2545
            ; case (splitAppTy_maybe s, splitAppTy_maybe t) of
    
    2610 2546
                (Just {}, Just {}) -> return ()
    
    ... ... @@ -2618,14 +2554,12 @@ lintCoercion orig_co@(InstCo co arg)
    2618 2554
         go (InstCo co arg) args = do { lintCoercion arg; go co (arg:args) }
    
    2619 2555
         go co              args = do { lintCoercion co
    
    2620 2556
                                      ; let Pair lty rty = coercionKind co
    
    2621
    -                                 ; lty' <- substTyM lty
    
    2622
    -                                 ; rty' <- substTyM rty
    
    2623 2557
                                      ; in_scope <- getInScope
    
    2624 2558
                                      ; let subst = mkEmptySubst in_scope
    
    2625
    -                                 ; go_args (subst, lty') (subst,rty') args }
    
    2559
    +                                 ; go_args (subst, lty) (subst,rty) args }
    
    2626 2560
     
    
    2627 2561
         -------------
    
    2628
    -    go_args :: (Subst, OutType) -> (Subst,OutType) -> [InCoercion]
    
    2562
    +    go_args :: (Subst, Type) -> (Subst,Type) -> [Coercion]
    
    2629 2563
                -> LintM ()
    
    2630 2564
         go_args _ _ []
    
    2631 2565
           = return ()
    
    ... ... @@ -2634,11 +2568,11 @@ lintCoercion orig_co@(InstCo co arg)
    2634 2568
                ; go_args lty1 rty1 args }
    
    2635 2569
     
    
    2636 2570
         -------------
    
    2637
    -    go_arg :: (Subst, OutType) -> (Subst,OutType) -> InCoercion
    
    2638
    -           -> LintM ((Subst,OutType), (Subst,OutType))
    
    2571
    +    go_arg :: (Subst, Type) -> (Subst,Type) -> Coercion
    
    2572
    +           -> LintM ((Subst,Type), (Subst,Type))
    
    2639 2573
         go_arg (lsubst,lty) (rsubst,rty) arg
    
    2640 2574
           = do { lintRole arg Nominal (coercionRole arg)
    
    2641
    -           ; Pair arg_lty arg_rty <- substCoKindM arg
    
    2575
    +           ; let Pair arg_lty arg_rty = coercionKind arg
    
    2642 2576
     
    
    2643 2577
                ; case (splitForAllTyCoVar_maybe lty, splitForAllTyCoVar_maybe rty) of
    
    2644 2578
                   -- forall over tvar
    
    ... ... @@ -2662,11 +2596,11 @@ lintCoercion orig_co@(InstCo co arg)
    2662 2596
     lintCoercion this_co@(AxiomCo ax cos)
    
    2663 2597
       = do { mapM_ lintCoercion cos
    
    2664 2598
            ; lint_roles 0 (coAxiomRuleArgRoles ax) cos
    
    2665
    -       ; prs <- mapM substCoKindM cos
    
    2599
    +       ; let prs = map coercionKind cos
    
    2666 2600
            ; lint_ax ax prs }
    
    2667 2601
     
    
    2668 2602
       where
    
    2669
    -    lint_ax :: CoAxiomRule -> [Pair OutType] -> LintM ()
    
    2603
    +    lint_ax :: CoAxiomRule -> [Pair Type] -> LintM ()
    
    2670 2604
         lint_ax (BuiltInFamRew  bif) prs
    
    2671 2605
           = checkL (isJust (bifrw_proves bif prs))  bad_bif
    
    2672 2606
         lint_ax (BuiltInFamInj bif) prs
    
    ... ... @@ -2754,8 +2688,8 @@ lintBranch this_co fam_tc branch arg_kinds
    2754 2688
       = do { checkL (arg_kinds `equalLength` (ktvs ++ cvs)) $
    
    2755 2689
                     (bad_ax this_co (text "lengths"))
    
    2756 2690
     
    
    2757
    -       ; subst <- getSubst
    
    2758
    -       ; let empty_subst = zapSubst subst
    
    2691
    +       ; in_scope <- getInScope
    
    2692
    +       ; let empty_subst = mkEmptySubst in_scope
    
    2759 2693
            ; _ <- foldlM check_ki (empty_subst, empty_subst)
    
    2760 2694
                                   (zip (ktvs ++ cvs) arg_kinds)
    
    2761 2695
     
    
    ... ... @@ -2880,12 +2814,12 @@ lint_axiom ax@(CoAxiom { co_ax_tc = tc, co_ax_branches = branches
    2880 2814
     lint_branch :: TyCon -> CoAxBranch -> LintM ()
    
    2881 2815
     lint_branch ax_tc (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs
    
    2882 2816
                                   , cab_lhs = lhs_args, cab_rhs = rhs })
    
    2883
    -  = lintBinders LambdaBind (tvs ++ cvs) $ \_ ->
    
    2817
    +  = lintBinders LambdaBind (tvs ++ cvs) $
    
    2884 2818
         do { let lhs = mkTyConApp ax_tc lhs_args
    
    2885 2819
            ; lintType lhs
    
    2886 2820
            ; lintType rhs
    
    2887
    -       ; lhs_kind <- substTyM (typeKind lhs)
    
    2888
    -       ; rhs_kind <- substTyM (typeKind rhs)
    
    2821
    +       ; let lhs_kind = typeKind lhs
    
    2822
    +             rhs_kind = typeKind rhs
    
    2889 2823
            ; lintL (not (lhs_kind `typesAreApart` rhs_kind)) $
    
    2890 2824
              hang (text "Inhomogeneous axiom")
    
    2891 2825
                 2 (text "lhs:" <+> ppr lhs <+> dcolon <+> ppr lhs_kind $$
    
    ... ... @@ -2969,35 +2903,26 @@ type LintLevel = Int
    2969 2903
     -- If you edit this type, you may need to update the GHC formalism
    
    2970 2904
     -- See Note [GHC Formalism]
    
    2971 2905
     data LintEnv
    
    2972
    -  = LE { le_flags :: LintFlags       -- Linting the result of this pass
    
    2973
    -       , le_loc   :: [LintLocInfo]   -- Locations
    
    2974
    -
    
    2975
    -       , le_subst :: Subst
    
    2976
    -                  -- Current substitution, for TyCoVars only.
    
    2977
    -                  -- Non-CoVar Ids don't appear in here, not even in the InScopeSet
    
    2978
    -                  -- Used for (a) cloning to avoid shadowing of TyCoVars,
    
    2979
    -                  --              so that eqType works ok
    
    2980
    -                  --          (b) substituting for let-bound tyvars, when we have
    
    2981
    -                  --              (let @a = Int -> Int in ...)
    
    2982
    -
    
    2983
    -       , le_level   :: LintLevel
    
    2984
    -       , le_in_vars :: VarEnv (InVar, OutType, LintLevel)
    
    2985
    -                    -- Maps an InVar (i.e. its unique) to its binding InVar
    
    2986
    -                    --    and to its OutType
    
    2987
    -                    -- /All/ in-scope variables are here (term variables,
    
    2988
    -                    --    type variables, and coercion variables)
    
    2989
    -                    -- Used at an occurrence of the InVar
    
    2906
    +  = LE { le_flags    :: LintFlags       -- Linting the result of this pass
    
    2907
    +       , le_loc      :: [LintLocInfo]   -- Locations
    
    2908
    +       , le_level    :: LintLevel
    
    2909
    +       , le_in_scope :: InScopeSet
    
    2910
    +
    
    2911
    +       , le_in_vars  :: VarEnv (Var, LintLevel)
    
    2912
    +                     -- Maps an Var (i.e. its unique) to its binding Var and level
    
    2913
    +                     -- /All/ in-scope variables are here (term variables,
    
    2914
    +                     --    type variables, and coercion variables)
    
    2915
    +                     -- Used at an occurrence of the Var
    
    2990 2916
     
    
    2991 2917
            , le_joins :: UniqMap Id JoinOcc
    
    2992 2918
                -- ^ Join points in scope that are valid
    
    2993
    -           -- A subset of the InScopeSet in le_subst
    
    2994 2919
                -- See Note [Join points]
    
    2995 2920
     
    
    2996 2921
            , le_ue_aliases :: NameEnv UsageEnv
    
    2997 2922
                  -- See Note [Linting linearity]
    
    2998 2923
                  -- Assigns usage environments to the alias-like binders,
    
    2999 2924
                  -- as found in non-recursive lets.
    
    3000
    -             -- Domain is OutIds
    
    2925
    +             -- Domain is Ids
    
    3001 2926
     
    
    3002 2927
            , le_platform   :: Platform         -- ^ Target platform
    
    3003 2928
            , le_diagOpts   :: DiagOpts         -- ^ Target platform
    
    ... ... @@ -3011,7 +2936,8 @@ data LintFlags
    3011 2936
            , lf_check_linearity :: Bool    -- ^ See Note [Linting linearity]
    
    3012 2937
            , lf_check_fixed_rep :: Bool    -- ^ See Note [Checking for representation polymorphism]
    
    3013 2938
            , lf_check_rubbish_lits :: Bool -- ^ See Note [Checking for rubbish literals]
    
    3014
    -       , lf_allow_weak_joins :: Bool -- ^ See Note [Linting join points with casts or ticks]
    
    2939
    +       , lf_allow_weak_joins :: Bool   -- ^ See Note [Linting join points with casts or ticks]
    
    2940
    +       , lf_allow_beta_joins :: Bool   -- ^ See Note [Join points and beta-redexes]
    
    3015 2941
         }
    
    3016 2942
     
    
    3017 2943
     -- See Note [Checking StaticPtrs]
    
    ... ... @@ -3078,20 +3004,6 @@ top-level bindings. See SimplCore Note [Grand plan for static forms].
    3078 3004
     
    
    3079 3005
     The linter checks that no occurrence or `makeStatic` occurs nested.
    
    3080 3006
     
    
    3081
    -Note [Type substitution]
    
    3082
    -~~~~~~~~~~~~~~~~~~~~~~~~
    
    3083
    -Why do we need a type substitution?  Consider
    
    3084
    -        /\(a:*). \(x:a). /\(a:*). id a x
    
    3085
    -This is ill typed, because (renaming variables) it is really
    
    3086
    -        /\(a:*). \(x:a). /\(b:*). id b x
    
    3087
    -Hence, when checking an application, we can't naively compare x's type
    
    3088
    -(at its binding site) with its expected type (at a use site).  So we
    
    3089
    -rename type binders as we go, maintaining a substitution.
    
    3090
    -
    
    3091
    -The same substitution also supports let-type, current expressed as
    
    3092
    -        (/\(a:*). body) ty
    
    3093
    -Here we substitute 'ty' for 'a' in 'body', on the fly.
    
    3094
    -
    
    3095 3007
     Note [Linting type synonym applications]
    
    3096 3008
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3097 3009
     When linting a type-synonym, or type-family, application
    
    ... ... @@ -3353,12 +3265,12 @@ initL cfg m
    3353 3265
       where
    
    3354 3266
         vars = l_vars cfg
    
    3355 3267
         init_level = 0
    
    3356
    -    env = LE { le_flags   = l_flags cfg
    
    3357
    -             , le_subst   = mkEmptySubst (mkInScopeSetList vars)
    
    3358
    -             , le_level   = init_level
    
    3359
    -             , le_in_vars = mkVarEnv [ (v,(v, varType v, init_level)) | v <- vars ]
    
    3360
    -             , le_joins   = emptyUniqMap
    
    3361
    -             , le_loc     = []
    
    3268
    +    env = LE { le_flags    = l_flags cfg
    
    3269
    +             , le_level    = init_level
    
    3270
    +             , le_in_vars  = mkVarEnv [ (v,(v, init_level)) | v <- vars ]
    
    3271
    +             , le_in_scope = mkInScopeSetList vars
    
    3272
    +             , le_joins    = emptyUniqMap
    
    3273
    +             , le_loc      = []
    
    3362 3274
                  , le_ue_aliases = emptyNameEnv
    
    3363 3275
                  , le_platform = l_platform cfg
    
    3364 3276
                  , le_diagOpts = l_diagOpts cfg
    
    ... ... @@ -3421,8 +3333,7 @@ addMsg show_context env msgs msg
    3421 3333
        loc_msgs :: [(SrcLoc, SDoc)]  -- Innermost first
    
    3422 3334
        loc_msgs = map dumpLoc (le_loc env)
    
    3423 3335
     
    
    3424
    -   cxt_doc = vcat [ vcat $ reverse $ map snd loc_msgs
    
    3425
    -                  , text "Substitution:" <+> ppr (le_subst env) ]
    
    3336
    +   cxt_doc = vcat $ reverse $ map snd loc_msgs
    
    3426 3337
     
    
    3427 3338
        context | show_context  = cxt_doc
    
    3428 3339
                | otherwise     = whenPprDebug cxt_doc
    
    ... ... @@ -3449,73 +3360,45 @@ inCasePat = LintM $ \ env errs -> fromBoxedLResult (Just (is_case_pat env), errs
    3449 3360
         is_case_pat (LE { le_loc = CasePat {} : _ }) = True
    
    3450 3361
         is_case_pat _other                           = False
    
    3451 3362
     
    
    3452
    -addInScopeId :: InId -> OutType -> (OutId -> LintM a) -> LintM a
    
    3363
    +addInScopeId :: Id -> LintM a -> LintM a
    
    3453 3364
     -- Unlike addInScopeTyCoVar, this function does no cloning; Ids never get cloned
    
    3454
    -addInScopeId in_id out_ty thing_inside
    
    3365
    +addInScopeId id thing_inside
    
    3455 3366
       = LintM $ \ env errs ->
    
    3456
    -    let !(out_id, env') = add env
    
    3457
    -    in unLintM (thing_inside out_id) env' errs
    
    3458
    -
    
    3367
    +    unLintM thing_inside (add env) errs
    
    3459 3368
       where
    
    3460 3369
         add env@(LE { le_level = level, le_in_vars = id_vars, le_joins = valid_joins
    
    3461
    -                , le_ue_aliases = aliases, le_subst = subst })
    
    3462
    -      = (out_id, env1)
    
    3370
    +                , le_ue_aliases = aliases, le_in_scope = in_scope })
    
    3371
    +      = env { le_level = level1, le_in_vars = in_vars'
    
    3372
    +            , le_in_scope = in_scope `extendInScopeSet` id
    
    3373
    +            , le_joins = valid_joins', le_ue_aliases = aliases' }
    
    3463 3374
           where
    
    3464 3375
             level1 = level + 1
    
    3465
    -        env1 = env { le_level = level1, le_in_vars = in_vars'
    
    3466
    -                   , le_joins = valid_joins', le_ue_aliases = aliases' }
    
    3467 3376
     
    
    3468
    -        in_vars' = extendVarEnv id_vars in_id (in_id, out_ty, level1)
    
    3469
    -        aliases' = delFromNameEnv aliases (idName in_id)
    
    3377
    +        in_vars' = extendVarEnv id_vars id (id, level1)
    
    3378
    +        aliases' = delFromNameEnv aliases (idName id)
    
    3470 3379
                -- aliases': when shadowing an alias, we need to make sure the
    
    3471 3380
                -- Id is no longer classified as such. E.g.
    
    3472 3381
                --   let x = <e1> in case x of x { _DEFAULT -> <e2> }
    
    3473 3382
                -- Occurrences of 'x' in e2 shouldn't count as occurrences of e1.
    
    3474 3383
     
    
    3475
    -        -- A very tiny optimisation, not sure if it's really worth it
    
    3476
    -        -- Short-cut when the substitution is a no-op
    
    3477
    -        out_id | isEmptyTCvSubst subst = in_id
    
    3478
    -               | otherwise             = setIdType in_id out_ty
    
    3479
    -
    
    3480 3384
             valid_joins'
    
    3481
    -          | isJoinId out_id = addToUniqMap   valid_joins in_id NormalJoinOcc -- Overwrite with new arity
    
    3482
    -          | otherwise       = delFromUniqMap valid_joins in_id -- Remove any existing binding
    
    3385
    +          | isJoinId id = addToUniqMap   valid_joins id NormalJoinOcc -- Overwrite with new arity
    
    3386
    +          | otherwise   = delFromUniqMap valid_joins id -- Remove any existing binding
    
    3483 3387
     
    
    3484
    -addInScopeTyCoVar :: InTyCoVar -> OutType -> (OutTyCoVar -> LintM a) -> LintM a
    
    3388
    +addInScopeTyCoVar :: TyCoVar -> LintM a -> LintM a
    
    3485 3389
     -- This function clones to avoid shadowing of TyCoVars
    
    3486
    -addInScopeTyCoVar tcv tcv_type thing_inside
    
    3487
    -  = LintM $ \ env@(LE { le_level = level, le_in_vars = in_vars, le_subst = subst }) errs ->
    
    3488
    -    let (tcv', subst') = subst_bndr subst
    
    3489
    -        level' = level + 1
    
    3390
    +addInScopeTyCoVar tcv thing_inside
    
    3391
    +  = LintM $ \ env@(LE { le_level = level, le_in_vars = in_vars
    
    3392
    +                      , le_in_scope = in_scope }) errs ->
    
    3393
    +    let level' = level + 1
    
    3490 3394
             env' = env { le_level = level'
    
    3491
    -                   , le_in_vars = extendVarEnv in_vars tcv (tcv, tcv_type, level')
    
    3492
    -                   , le_subst = subst' }
    
    3493
    -    in unLintM (thing_inside tcv') env' errs
    
    3494
    -  where
    
    3495
    -    subst_bndr subst
    
    3496
    -      | isEmptyTCvSubst subst                -- No change in kind
    
    3497
    -      , not (tcv `elemInScopeSet` in_scope)  -- Not already in scope
    
    3498
    -      = -- Do not extend the substitution, just the in-scope set
    
    3499
    -        (if (varType tcv `eqType` tcv_type) then (\x->x) else
    
    3500
    -          pprTrace "addInScopeTyCoVar" (
    
    3501
    -            vcat [ text "tcv" <+> ppr tcv <+> dcolon <+> ppr (varType tcv)
    
    3502
    -                 , text "tcv_type" <+> ppr tcv_type ])) $
    
    3503
    -        (tcv, subst `extendSubstInScope` tcv)
    
    3504
    -
    
    3505
    -      -- Clone, and extend the substitution
    
    3506
    -      | let tcv' = uniqAway in_scope (setVarType tcv tcv_type)
    
    3507
    -      = (tcv', extendTCvSubstWithClone subst tcv tcv')
    
    3508
    -      where
    
    3509
    -        in_scope = substInScopeSet subst
    
    3395
    +                   , le_in_scope = in_scope `extendInScopeSet` tcv
    
    3396
    +                   , le_in_vars = extendVarEnv in_vars tcv (tcv, level') }
    
    3397
    +    in unLintM thing_inside env' errs
    
    3510 3398
     
    
    3511
    -getInVarEnv :: LintM (VarEnv (InId, OutType, LintLevel))
    
    3399
    +getInVarEnv :: LintM (VarEnv (Id, LintLevel))
    
    3512 3400
     getInVarEnv = LintM (\env errs -> fromBoxedLResult (Just (le_in_vars env), errs))
    
    3513 3401
     
    
    3514
    -extendTvSubstL :: TyVar -> Type -> LintM a -> LintM a
    
    3515
    -extendTvSubstL tv ty m
    
    3516
    -  = LintM $ \ env errs ->
    
    3517
    -    unLintM m (env { le_subst = Type.extendTvSubst (le_subst env) tv ty }) errs
    
    3518
    -
    
    3519 3402
     markAllJoinsBad :: LintM a -> LintM a
    
    3520 3403
     markAllJoinsBad m
    
    3521 3404
       = LintM $ \ env errs -> unLintM m (env { le_joins = emptyUniqMap }) errs
    
    ... ... @@ -3549,54 +3432,42 @@ markAllJoinsBadIf False m = m
    3549 3432
     getValidJoins :: LintM (UniqMap Id JoinOcc)
    
    3550 3433
     getValidJoins = LintM (\ env errs -> fromBoxedLResult (Just (le_joins env), errs))
    
    3551 3434
     
    
    3552
    -getSubst :: LintM Subst
    
    3553
    -getSubst = LintM (\ env errs -> fromBoxedLResult (Just (le_subst env), errs))
    
    3554
    -
    
    3555
    -substTyM :: InType -> LintM OutType
    
    3556
    --- Apply the substitution to the type
    
    3557
    --- The substitution is often empty, in which case it is a no-op
    
    3558
    -substTyM ty
    
    3559
    -  = do { subst <- getSubst
    
    3560
    -       ; return (substTy subst ty) }
    
    3561
    -
    
    3562 3435
     getUEAliases :: LintM (NameEnv UsageEnv)
    
    3563 3436
     getUEAliases = LintM (\ env errs -> fromBoxedLResult (Just (le_ue_aliases env), errs))
    
    3564 3437
     
    
    3565 3438
     getInScope :: LintM InScopeSet
    
    3566
    -getInScope = LintM (\ env errs -> fromBoxedLResult (Just (substInScopeSet $ le_subst env), errs))
    
    3439
    +getInScope = LintM (\ env errs -> fromBoxedLResult (Just (le_in_scope env), errs))
    
    3567 3440
     
    
    3568
    -lintVarOcc :: InVar -> LintM OutType
    
    3441
    +lintVarOcc :: Var -> LintM ()
    
    3569 3442
     -- Used at an occurrence of a variable: term variables, type variables, and coercion variables
    
    3570 3443
     -- Checks
    
    3571 3444
     --   - that it is in scope
    
    3572 3445
     --   - that it is not a GlobalId bound by a LocalId
    
    3573
    ---   - that the InType at the ocurrence matches the InType at the binding site
    
    3446
    +--   - that the Type at the ocurrence matches the Type at the binding site
    
    3574 3447
     --   - that the variables free in its type are not shadowed at the occurrence site
    
    3575 3448
     lintVarOcc v_occ
    
    3576 3449
       | isGlobalId v_occ
    
    3577
    -  = return (idType v_occ)
    
    3450
    +  = return ()
    
    3578 3451
       | otherwise
    
    3579 3452
       = do { in_var_env <- getInVarEnv
    
    3580 3453
            ; case lookupVarEnv in_var_env v_occ of
    
    3581 3454
                Nothing -> failWithL (text pp_what <+> quotes (ppr v_occ)
    
    3582 3455
                                      <+> text "is out of scope")
    
    3583
    -           Just (v_bndr, out_ty, bind_level)
    
    3456
    +           Just (v_bndr, bind_level)
    
    3584 3457
                  -> do { let bndr_ty = idType v_bndr
    
    3585 3458
                        ; check_bad_global v_bndr
    
    3586 3459
                        ; check_occ_type_match bndr_ty
    
    3587
    -                   ; check_occ_type_scope in_var_env bndr_ty bind_level
    
    3588
    -                   ; return out_ty }
    
    3589
    -
    
    3460
    +                   ; check_occ_type_scope in_var_env bndr_ty bind_level }
    
    3590 3461
         }
    
    3591 3462
       where
    
    3592
    -    occ_ty :: InType
    
    3463
    +    occ_ty :: Type
    
    3593 3464
         occ_ty = idType v_occ
    
    3594 3465
     
    
    3595 3466
         pp_what | isTyVar v_occ = "The type variable"
    
    3596 3467
                 | isCoVar v_occ = "The coercion variable"
    
    3597 3468
                 | otherwise     = "The value variable"
    
    3598 3469
     
    
    3599
    -    check_bad_global :: InVar -> LintM ()
    
    3470
    +    check_bad_global :: Var -> LintM ()
    
    3600 3471
         -- 'check_bad_global' checks for the case where an /occurrence/ is
    
    3601 3472
         -- a GlobalId, but there is an enclosing binding for a LocalId.
    
    3602 3473
         -- NB: the in-scope variables are mostly LocalIds, checked by lintIdBndr,
    
    ... ... @@ -3616,26 +3487,26 @@ lintVarOcc v_occ
    3616 3487
           | otherwise
    
    3617 3488
           = return ()
    
    3618 3489
     
    
    3619
    -    check_occ_type_match :: InType -> LintM ()
    
    3490
    +    check_occ_type_match :: Type -> LintM ()
    
    3620 3491
         -- Check that the type in /binder/ and the type in the /occurrence/ are the same
    
    3621 3492
         check_occ_type_match bndr_ty
    
    3622
    -      = ensureEqTys bndr_ty occ_ty $  -- Compares InTypes
    
    3493
    +      = ensureEqTys bndr_ty occ_ty $  -- Compares Types
    
    3623 3494
             mkBndrOccTypeMismatchMsg v_occ bndr_ty occ_ty
    
    3624 3495
     
    
    3625
    -    check_occ_type_scope :: VarEnv (InVar,OutType,LintLevel) -> InType -> LintLevel -> LintM ()
    
    3496
    +    check_occ_type_scope :: VarEnv (Var,LintLevel) -> Type -> LintLevel -> LintM ()
    
    3626 3497
         -- Check that the free vars of the binder's type
    
    3627 3498
         -- are not shadowed at the occurrence site
    
    3628 3499
         check_occ_type_scope in_var_env bndr_ty bind_level
    
    3629 3500
           = checkL (null bad_fvs) $
    
    3630 3501
             mkBndrOccFreeVarMsg v_occ occ_ty bad_fvs
    
    3631 3502
           where
    
    3632
    -        bad_fvs :: [InVar]
    
    3503
    +        bad_fvs :: [Var]
    
    3633 3504
             bad_fvs = filter is_bad (tyCoVarsOfTypeList bndr_ty)
    
    3634 3505
     
    
    3635
    -        is_bad :: InVar -> Bool
    
    3506
    +        is_bad :: Var -> Bool
    
    3636 3507
             -- True of a variable bound inside bind_level
    
    3637 3508
             is_bad v = case lookupVarEnv in_var_env v of
    
    3638
    -                      Just (_, _, v_level) -> v_level > bind_level
    
    3509
    +                      Just (_, v_level) -> v_level > bind_level
    
    3639 3510
                           Nothing -> True
    
    3640 3511
     
    
    3641 3512
     lookupJoinId :: Id -> LintM (Maybe (JoinArity, JoinOcc))
    
    ... ... @@ -3647,21 +3518,21 @@ lookupJoinId id
    3647 3518
                 Just join_occ -> return $ Just (idJoinArity id, join_occ)
    
    3648 3519
                 Nothing       -> return Nothing }
    
    3649 3520
     
    
    3650
    -addAliasUE :: OutId -> UsageEnv -> LintM a -> LintM a
    
    3521
    +addAliasUE :: Id -> UsageEnv -> LintM a -> LintM a
    
    3651 3522
     addAliasUE id ue thing_inside = LintM $ \ env errs ->
    
    3652 3523
       let new_ue_aliases =
    
    3653 3524
             extendNameEnv (le_ue_aliases env) (getName id) ue
    
    3654 3525
       in
    
    3655 3526
         unLintM thing_inside (env { le_ue_aliases = new_ue_aliases }) errs
    
    3656 3527
     
    
    3657
    -varCallSiteUsage :: OutId -> LintM UsageEnv
    
    3528
    +varCallSiteUsage :: Id -> LintM UsageEnv
    
    3658 3529
     varCallSiteUsage id =
    
    3659 3530
       do m <- getUEAliases
    
    3660 3531
          return $ case lookupNameEnv m (getName id) of
    
    3661 3532
              Nothing    -> singleUsageUE id
    
    3662 3533
              Just id_ue -> id_ue
    
    3663 3534
     
    
    3664
    -ensureEqTys :: OutType -> OutType -> SDoc -> LintM ()
    
    3535
    +ensureEqTys :: Type -> Type -> SDoc -> LintM ()
    
    3665 3536
     -- check ty2 is subtype of ty1 (ie, has same structure but usage
    
    3666 3537
     -- annotations need only be consistent, not equal)
    
    3667 3538
     -- Assumes ty1,ty2 are have already had the substitution applied
    
    ... ... @@ -3885,7 +3756,7 @@ mkLetErr bndr rhs
    3885 3756
               hang (text "Rhs:")
    
    3886 3757
                      4 (ppr rhs)]
    
    3887 3758
     
    
    3888
    -mkTyAppMsg :: OutType -> Type -> SDoc
    
    3759
    +mkTyAppMsg :: Type -> Type -> SDoc
    
    3889 3760
     mkTyAppMsg ty arg_ty
    
    3890 3761
       = vcat [text "Illegal type application:",
    
    3891 3762
                   hang (text "Function type:")
    
    ... ... @@ -4006,13 +3877,13 @@ mkJoinBndrOccMismatchMsg bndr join_arity_bndr join_arity_occ
    4006 3877
              , text "Arity at binding site:" <+> ppr join_arity_bndr
    
    4007 3878
              , text "Arity at occurrence:  " <+> ppr join_arity_occ ]
    
    4008 3879
     
    
    4009
    -mkBndrOccTypeMismatchMsg :: InVar -> InType -> InType -> SDoc
    
    3880
    +mkBndrOccTypeMismatchMsg :: Var -> Type -> Type -> SDoc
    
    4010 3881
     mkBndrOccTypeMismatchMsg var bndr_ty occ_ty
    
    4011 3882
       = vcat [ text "Mismatch in type between binder and occurrence"
    
    4012 3883
              , text "Binder:    " <+> ppr var <+> dcolon <+> ppr bndr_ty
    
    4013 3884
              , text "Occurrence:" <+> ppr var <+> dcolon <+> ppr occ_ty ]
    
    4014 3885
     
    
    4015
    -mkBndrOccFreeVarMsg :: InVar -> InType -> [TyCoVar] -> SDoc
    
    3886
    +mkBndrOccFreeVarMsg :: Var -> Type -> [TyCoVar] -> SDoc
    
    4016 3887
     mkBndrOccFreeVarMsg var occ_ty bad_tvs
    
    4017 3888
       = vcat [ text "Free vars of type are shadowed:" <+> ppr bad_tvs
    
    4018 3889
              , text "Occurrence:"  <+> ppr var <+> dcolon <+> ppr occ_ty ]
    

  • compiler/GHC/Core/Opt/OccurAnal.hs
    ... ... @@ -2676,6 +2676,8 @@ occAnalArgs :: OccEnv -> CoreExpr -> [CoreExpr]
    2676 2676
                 -> WithUsageDetails CoreExpr
    
    2677 2677
     -- The `fun` argument is just an accumulating parameter,
    
    2678 2678
     -- the base for building the application we return
    
    2679
    +--
    
    2680
    +-- We have applied markAllNonTail to the returned usage-details
    
    2679 2681
     occAnalArgs env fun args one_shots
    
    2680 2682
       = go emptyDetails fun args one_shots
    
    2681 2683
       where
    
    ... ... @@ -2686,7 +2688,9 @@ occAnalArgs env fun args one_shots
    2686 2688
         encl | Var f <- fun, isDeadEndSig (idDmdSig f) = OccScrut
    
    2687 2689
              | otherwise                               = OccVanilla
    
    2688 2690
     
    
    2689
    -    go uds fun [] _ = WUD uds fun
    
    2691
    +    go uds fun [] _ = WUD (markAllNonTail uds) fun
    
    2692
    +       -- markAllNonTail: calls in arguments are not tail calls!
    
    2693
    +
    
    2690 2694
         go uds fun (arg:args) one_shots
    
    2691 2695
           = go (uds `andUDs` arg_uds) (fun `App` arg') args one_shots'
    
    2692 2696
           where
    
    ... ... @@ -2778,8 +2782,7 @@ occAnalApp env (Var fun_id, args, ticks)
    2778 2782
     
    
    2779 2783
         all_uds = fun_uds `andUDs` final_args_uds
    
    2780 2784
     
    
    2781
    -    !final_args_uds = markAllNonTail                              $
    
    2782
    -                      markAllInsideLamIf (isRhsEnv env && is_exp) $
    
    2785
    +    !final_args_uds = markAllInsideLamIf (isRhsEnv env && is_exp) $
    
    2783 2786
                             -- isRhsEnv: see Note [OccEncl]
    
    2784 2787
                           args_uds
    
    2785 2788
            -- We mark the free vars of the argument of a constructor or PAP
    
    ... ... @@ -2809,33 +2812,46 @@ occAnalApp env (Var fun_id, args, ticks)
    2809 2812
             -- See Note [Sources of one-shot information], bullet point A']
    
    2810 2813
     
    
    2811 2814
     occAnalApp env (fun, args, ticks)
    
    2812
    -  = let app_out = mkTicks ticks app'
    
    2813
    -    in WUD (markAllNonTail (fun_uds `andUDs` args_uds)) app_out
    
    2814
    -
    
    2815
    +  = WUD (fun_uds `andUDs` args_uds) (mkTicks ticks app')
    
    2815 2816
       where
    
    2816 2817
         !(WUD args_uds app') = occAnalArgs env fun' args []
    
    2817
    -    !(WUD fun_uds fun')  = occAnal (addAppCtxt env args) fun
    
    2818
    -        -- The addAppCtxt is a bit cunning.  One iteration of the simplifier
    
    2819
    -        -- often leaves behind beta redexes like
    
    2820
    -        --      (\x y -> e) a1 a2
    
    2821
    -        -- Here we would like to mark x,y as one-shot, and treat the whole
    
    2822
    -        -- thing much like a let.  We do this by pushing some OneShotLam items
    
    2823
    -        -- onto the context stack.
    
    2824
    -
    
    2825
    -addAppCtxt :: OccEnv -> [Arg CoreBndr] -> OccEnv
    
    2826
    -addAppCtxt env@(OccEnv { occ_one_shots = ctxt }) args
    
    2827
    -  | n_val_args > 0
    
    2828
    -  = env { occ_one_shots = replicate n_val_args OneShotLam ++ ctxt
    
    2829
    -        , occ_encl      = OccVanilla }
    
    2830
    -          -- OccVanilla: the function part of the application
    
    2831
    -          -- is no longer on OccRhs or OccScrut
    
    2832
    -  | otherwise
    
    2833
    -  = env
    
    2834
    -  where
    
    2835
    -    n_val_args = valArgCount args
    
    2818
    +    !(WUD fun_uds fun')  = go_fun env fun args
    
    2819
    +
    
    2820
    +    -- See Note [occAnal for applications]
    
    2821
    +    go_fun env (Lam bndr body) (_ : args)
    
    2822
    +      = addInScopeOne env bndr $ \ env' ->
    
    2823
    +        let !(WUD body_uds body') = go_fun env' body args
    
    2824
    +            !bndr' = tagLamBinder body_uds bndr
    
    2825
    +        in WUD body_uds (Lam bndr' body')
    
    2826
    +    go_fun env fun args
    
    2827
    +      | null args
    
    2828
    +      = occAnal env fun
    
    2829
    +      | otherwise
    
    2830
    +      = let !env' = env { occ_encl = OccVanilla }
    
    2831
    +                    -- OccVanilla: the function part of the
    
    2832
    +                    -- application is no longer OccRhs or OccScrut
    
    2833
    +            !(WUD fun_uds fun') = occAnal env' fun
    
    2834
    +        in WUD (markAllNonTail fun_uds) fun'
    
    2836 2835
     
    
    2836
    +{- Note [occAnal for applications]
    
    2837
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2838
    +One iteration of the simplifier sometimes leaves behind beta redexes like
    
    2839
    +     (\x y -> e) a1 a2
    
    2840
    +This happens particularly in worker/wrapper; see Note [Join points and beta-redexes]
    
    2841
    +in GHC.Core.Lint.  In these cases there are two things we want to take care of
    
    2842
    +in the occurrence analyser:
    
    2843
    +
    
    2844
    +* We don't want to mark variables inside `e` as `InsideLam`; that would just
    
    2845
    +  delay inlining them for another iteration of the Simplifier.
    
    2846
    +
    
    2847
    +* If there is a join-point invocation inside `e`, we don't want to complain about
    
    2848
    +  lost join points.  See Note [Join points and beta-redexes] in GHC.Core.Lint for
    
    2849
    +  more detail.
    
    2850
    +
    
    2851
    +It is easy to address both of these: in `occAnalApp`, simply walk down the
    
    2852
    +function, matching lambdas with arguments.  This is done by the local `go_fun`
    
    2853
    +loop.
    
    2837 2854
     
    
    2838
    -{-
    
    2839 2855
     Note [Sources of one-shot information]
    
    2840 2856
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2841 2857
     The occurrence analyser obtains one-shot-lambda information from two sources:
    

  • compiler/GHC/Core/Opt/WorkWrap/Utils.hs
    ... ... @@ -241,10 +241,10 @@ mkWwBodies opts fun_id ww_arity arg_vars res_ty demands res_cpr
    241 241
                     = (work_args, work_args, work_marks)
    
    242 242
     
    
    243 243
                   call_work work_fn  = mkVarApps (Var work_fn) work_call_args
    
    244
    -              call_rhs fn_rhs = mkAppsBeta fn_rhs fn_args
    
    245
    -                                  -- See Note [Join points and beta-redexes]
    
    244
    +              call_rhs fn_rhs = mkApps fn_rhs fn_args
    
    245
    +                   -- See Note [Join points and beta-redexes] in GHC.Core.Lint
    
    246 246
                   wrapper_body = mkLams cloned_arg_vars . wrap_fn_cpr . wrap_fn_str . call_work
    
    247
    -                                  -- See Note [Call-by-value for worker args]
    
    247
    +                   -- See Note [Call-by-value for worker args]
    
    248 248
                   work_seq_str_flds = mkStrictFieldSeqs (zip work_lam_args work_call_str)
    
    249 249
                   worker_body = mkLams work_lam_args . work_seq_str_flds . work_fn_cpr . call_rhs
    
    250 250
                   worker_args_dmds= [ idDemandInfo v | v <- work_call_args, isId v]
    
    ... ... @@ -280,14 +280,6 @@ mkWwBodies opts fun_id ww_arity arg_vars res_ty demands res_cpr
    280 280
         arity_ok | isJoinId fun_id = ww_arity <= n_dmds
    
    281 281
                  | otherwise       = ww_arity == n_dmds
    
    282 282
     
    
    283
    --- | Version of 'GHC.Core.mkApps' that does beta reduction on-the-fly.
    
    284
    --- PRECONDITION: The arg expressions are not free in any of the lambdas binders.
    
    285
    -mkAppsBeta :: CoreExpr -> [CoreArg] -> CoreExpr
    
    286
    --- The precondition holds for our call site in mkWwBodies, because all the FVs
    
    287
    --- of as are either cloned_arg_vars (and thus fresh) or fresh worker args.
    
    288
    -mkAppsBeta (Lam b body) (a:as) = bindNonRec b a $! mkAppsBeta body as
    
    289
    -mkAppsBeta f            as     = mkApps f as
    
    290
    -
    
    291 283
     -- See Note [Limit w/w arity]
    
    292 284
     isWorkerSmallEnough :: Int -> Int -> [Var] -> Bool
    
    293 285
     isWorkerSmallEnough max_worker_args old_n_args vars
    
    ... ... @@ -525,36 +517,6 @@ Solution is simple: put the void argument /last/:
    525 517
     
    
    526 518
     c.f Note [SpecConstr void argument insertion] in GHC.Core.Opt.SpecConstr
    
    527 519
     
    
    528
    -Note [Join points and beta-redexes]
    
    529
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    530
    -Originally, the worker would invoke the original function by calling it with
    
    531
    -arguments, thus producing a beta-redex for the simplifier to munch away:
    
    532
    -
    
    533
    -  \x y z -> e => (\x y z -> e) wx wy wz
    
    534
    -
    
    535
    -Now that we have special rules about join points, however, this is Not Good if
    
    536
    -the original function is itself a join point, as then it may contain invocations
    
    537
    -of other join points:
    
    538
    -
    
    539
    -  join j1 x = ...
    
    540
    -  join j2 y = if y == 0 then 0 else j1 y
    
    541
    -
    
    542
    -  =>
    
    543
    -
    
    544
    -  join j1 x = ...
    
    545
    -  join $wj2 y# = let wy = I# y# in (\y -> if y == 0 then 0 else jump j1 y) wy
    
    546
    -  join j2 y = case y of I# y# -> jump $wj2 y#
    
    547
    -
    
    548
    -There can't be an intervening lambda between a join point's declaration and its
    
    549
    -occurrences, so $wj2 here is wrong. But of course, this is easy enough to fix:
    
    550
    -
    
    551
    -  ...
    
    552
    -  let join $wj2 y# = let wy = I# y# in let y = wy in if y == 0 then 0 else j1 y
    
    553
    -  ...
    
    554
    -
    
    555
    -Hence we simply do the beta-reduction here. (This would be harder if we had to
    
    556
    -worry about hygiene, but luckily wy is freshly generated.)
    
    557
    -
    
    558 520
     Note [Freshen WW arguments]
    
    559 521
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    560 522
     When we do a worker/wrapper split, we must freshen the arg vars of the original
    

  • compiler/GHC/Core/Subst.hs
    ... ... @@ -13,7 +13,8 @@ module GHC.Core.Subst (
    13 13
     
    
    14 14
             -- ** Substituting into expressions and related types
    
    15 15
             deShadowBinds, substRuleInfo, substRulesForImportedIds,
    
    16
    -        substTyUnchecked, substCo, substExpr, substExprSC, substBind, substBindSC,
    
    16
    +        substTy, substTyUnchecked, substCo,
    
    17
    +        substExpr, substExprSC, substBind, substBindSC,
    
    17 18
             substUnfolding, substUnfoldingSC,
    
    18 19
             lookupIdSubst, lookupIdSubst_maybe, substIdType, substIdOcc,
    
    19 20
             substTickish, substDVarSet, substIdInfo,
    
    ... ... @@ -42,8 +43,7 @@ import GHC.Core.FVs
    42 43
     import GHC.Core.Seq
    
    43 44
     import GHC.Core.Utils
    
    44 45
     
    
    45
    -        -- We are defining local versions
    
    46
    -import GHC.Core.Type hiding ( substTy )
    
    46
    +import GHC.Core.Type
    
    47 47
     import GHC.Core.Coercion( mkCoVarCo, substCoVarBndr )
    
    48 48
     import GHC.Core.TyCo.FVs
    
    49 49
     
    

  • compiler/GHC/Core/SubstTypeLets.hs
    1
    +{-
    
    2
    +(c) The University of Glasgow 2006
    
    3
    +(c) The GRASP/AQUA Project, Glasgow University, 1993-1998
    
    4
    +-}
    
    5
    +
    
    6
    +module GHC.Core.SubstTypeLets(
    
    7
    +         substTypeLets
    
    8
    +     ) where
    
    9
    +
    
    10
    +import GHC.Prelude
    
    11
    +
    
    12
    +import GHC.Core
    
    13
    +import GHC.Core.Subst
    
    14
    +import GHC.Core.Utils( mkInScopeSetBndrs )
    
    15
    +
    
    16
    +import GHC.Types.Var
    
    17
    +
    
    18
    +import GHC.Utils.Misc( mapSnd )
    
    19
    +import GHC.Utils.Outputable
    
    20
    +import GHC.Utils.Panic
    
    21
    +
    
    22
    +{- Note [Substituting type-lets]
    
    23
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    24
    +When desugaring pattern matching we really, really need non-Lint-acceptable type-lets.
    
    25
    +Suppose we have
    
    26
    +   f (MkT a (Just a (x::a)) (y::a)) = rhs1
    
    27
    +   f (MkT b (Nothing b) (z::b)) = rhs2
    
    28
    +where
    
    29
    +   MkT :: ∀ a. Maybe a -> a -> T
    
    30
    +
    
    31
    +We desugar this to
    
    32
    +  f x = case x of
    
    33
    +          MkT w (v :: Maybe w) (p:w)
    
    34
    +              ->  let { a=w, b=w }
    
    35
    +                  in let { y:a=p, z:b=p }
    
    36
    +                  in case v of
    
    37
    +                      Just a (x:a) -> rhs1 [y::a]
    
    38
    +                      Nothing b    -> rhs2 [z::b]
    
    39
    +
    
    40
    +Look at those type-lets { a=w, b=w }.  They make the type variables in the
    
    41
    +/two/ separately-typechecked clauses for `f` line up with the /single/ pattern
    
    42
    +match on `x`, which binds the type variable `w`.
    
    43
    +
    
    44
    +Key point: the body of the let is only type-correct /after/ substituting
    
    45
    +a:=w, b:=w.  Even the next let, { y:a=p } isn't type-correct without that
    
    46
    +substitution, because (p:w).
    
    47
    +
    
    48
    +So the `substTypeLets` pass runs before we Lint the output of the desugarer.
    
    49
    +When it finds a nested type-let
    
    50
    +    let @a = ty in body
    
    51
    +it substitutes a:=ty in `body`
    
    52
    +
    
    53
    +Wrinkles
    
    54
    +
    
    55
    +(STL1) It only substitutes /nested/ type-lets, not top level.
    
    56
    +
    
    57
    +(STL2) You might think that we'd run it unconditionally, after desugaring.  But actually,
    
    58
    +  the Simplifier (or SimpleOpt) will deal with these type-lets, so it is just Lint
    
    59
    +  that we must placate.  We don't want to incur the cost of this pass except when
    
    60
    +  we are Linting.
    
    61
    +
    
    62
    +  TL;DR: we do substTypeLets as a pre-pass to the Lint pass that immediately follows
    
    63
    +  desugaring. See `GHC.Core.lintPassResult`, and the `lpr_preSubst` field in
    
    64
    +  `LintPassResultConfig`.
    
    65
    +-}
    
    66
    +
    
    67
    +substTypeLets :: CoreProgram -> CoreProgram
    
    68
    +substTypeLets binds = map stl_top binds
    
    69
    +  where
    
    70
    +     stl_top (NonRec b r) = NonRec b (stlExpr empty_subst r)
    
    71
    +     stl_top (Rec prs)    = Rec (mapSnd (stlExpr empty_subst) prs)
    
    72
    +
    
    73
    +     empty_subst = mkEmptySubst $
    
    74
    +                   mkInScopeSetBndrs binds
    
    75
    +
    
    76
    +----------------------
    
    77
    +stlBind :: Subst -> CoreBind -> (Subst, CoreBind)
    
    78
    +stlBind subst (Rec prs)
    
    79
    +  = assertPpr (not (any isTyVar bndrs)) (ppr prs) $
    
    80
    +    (subst', Rec prs')
    
    81
    +  where
    
    82
    +    (bndrs,rhss) = unzip prs
    
    83
    +    (subst', bndrs') = substRecBndrs subst bndrs
    
    84
    +    rhss' = map (stlExpr subst') rhss
    
    85
    +    prs'  = bndrs' `zip` rhss'
    
    86
    +
    
    87
    +stlBind subst (NonRec bndr rhs)
    
    88
    +  = (subst', NonRec bndr' (stlExpr subst rhs))
    
    89
    +  where
    
    90
    +    (subst', bndr')  = substBndr subst bndr
    
    91
    +
    
    92
    +----------------------
    
    93
    +stlExpr :: Subst -> CoreExpr -> CoreExpr
    
    94
    +
    
    95
    +stlExpr subst (Let (NonRec tv (Type ty)) body)
    
    96
    +  = -- This equation is the main payload of the entire pass!
    
    97
    +    stlExpr (extendTvSubst subst tv ty) body
    
    98
    +
    
    99
    +stlExpr subst (Let bind body)
    
    100
    +  = Let bind' (stlExpr subst' body)
    
    101
    +  where
    
    102
    +    (subst', bind') = stlBind subst bind
    
    103
    +
    
    104
    +stlExpr subst (Lam bndr body)
    
    105
    +  = Lam bndr' (stlExpr subst' body)
    
    106
    +  where
    
    107
    +    (subst', bndr') = substBndr subst bndr
    
    108
    +
    
    109
    +stlExpr subst (Case scrut bndr ty alts)
    
    110
    +  = Case (stlExpr subst scrut) bndr' (substTy subst ty)
    
    111
    +         (map stl_alt alts)
    
    112
    +  where
    
    113
    +    (subst', bndr') = substBndr subst bndr
    
    114
    +
    
    115
    +    stl_alt (Alt con bndrs rhs)
    
    116
    +       = Alt con bndrs' (stlExpr subst'' rhs)
    
    117
    +       where
    
    118
    +         (subst'', bndrs') = substBndrs subst' bndrs
    
    119
    +
    
    120
    +-- Simple cases
    
    121
    +stlExpr _     (Lit l)       = Lit l
    
    122
    +stlExpr subst (Var v)       = lookupIdSubst subst v
    
    123
    +stlExpr subst (App e1 e2)   = App (stlExpr subst e1) (stlExpr subst e2)
    
    124
    +stlExpr subst (Type ty)     = Type (substTy subst ty)
    
    125
    +stlExpr subst (Tick t e)    = Tick (substTickish subst t) (stlExpr subst e)
    
    126
    +stlExpr subst (Cast e co)   = Cast (stlExpr subst e) (substCo subst co)
    
    127
    +stlExpr subst (Coercion co) = Coercion (substCo subst co)

  • compiler/GHC/Driver/Config/Core/Lint.hs
    ... ... @@ -52,6 +52,7 @@ endPassHscEnvIO hsc_env name_ppr_ctx pass binds rules
    52 52
     
    
    53 53
     -- | Type-check a 'CoreProgram'. See Note [Core Lint guarantee].
    
    54 54
     lintCoreBindings :: DynFlags -> CoreToDo -> [Var] -> CoreProgram -> WarnsAndErrs
    
    55
    +-- ToDo: this function is not called within GHC.  Why does it exist?
    
    55 56
     lintCoreBindings dflags coreToDo vars -- binds
    
    56 57
       = lintCoreBindings' $ LintConfig
    
    57 58
           { l_diagOpts = initDiagOpts dflags
    
    ... ... @@ -104,10 +105,15 @@ initLintPassResultConfig dflags extra_vars pass = LintPassResultConfig
    104 105
       { lpr_diagOpts      = initDiagOpts dflags
    
    105 106
       , lpr_platform      = targetPlatform dflags
    
    106 107
       , lpr_makeLintFlags = perPassFlags dflags pass
    
    107
    -  , lpr_passPpr = ppr pass
    
    108
    +  , lpr_passPpr       = ppr pass
    
    109
    +  , lpr_preSubst      = doPreSubst pass
    
    108 110
       , lpr_localsInScope = extra_vars
    
    109 111
       }
    
    110 112
     
    
    113
    +doPreSubst :: CoreToDo -> Bool
    
    114
    +doPreSubst CoreDesugar = True
    
    115
    +doPreSubst _           = False
    
    116
    +
    
    111 117
     perPassFlags :: DynFlags -> CoreToDo -> LintFlags
    
    112 118
     perPassFlags dflags pass
    
    113 119
       = (defaultLintFlags dflags)
    
    ... ... @@ -116,7 +122,8 @@ perPassFlags dflags pass
    116 122
                    , lf_check_static_ptrs          = check_static_ptrs
    
    117 123
                    , lf_check_linearity            = check_linearity
    
    118 124
                    , lf_check_rubbish_lits         = check_rubbish
    
    119
    -               , lf_allow_weak_joins           = allow_weak_joins }
    
    125
    +               , lf_allow_weak_joins           = allow_weak_joins
    
    126
    +               , lf_allow_beta_joins           = allow_beta_joins }
    
    120 127
       where
    
    121 128
         -- See Note [Checking for global Ids]
    
    122 129
         check_globals = case pass of
    
    ... ... @@ -158,6 +165,11 @@ perPassFlags dflags pass
    158 165
                           CorePrep -> True
    
    159 166
                           _        -> False
    
    160 167
     
    
    168
    +    -- See Note [Join points and beta-redexes] in GHC.Core.Lint
    
    169
    +    allow_beta_joins = case pass of
    
    170
    +                          CoreDoWorkerWrapper -> True
    
    171
    +                          _                   -> False
    
    172
    +
    
    161 173
     initLintConfig :: DynFlags -> [Var] -> LintConfig
    
    162 174
     initLintConfig dflags vars =LintConfig
    
    163 175
       { l_diagOpts = initDiagOpts dflags
    
    ... ... @@ -175,4 +187,5 @@ defaultLintFlags dflags = LF { lf_check_global_ids = False
    175 187
                                  , lf_check_fixed_rep = True
    
    176 188
                                  , lf_check_rubbish_lits = True
    
    177 189
                                  , lf_allow_weak_joins = False
    
    190
    +                             , lf_allow_beta_joins = False
    
    178 191
                                  }

  • compiler/ghc.cabal.in
    ... ... @@ -411,6 +411,7 @@ Library
    411 411
             GHC.Core.SimpleOpt
    
    412 412
             GHC.Core.Stats
    
    413 413
             GHC.Core.Subst
    
    414
    +        GHC.Core.SubstTypeLets
    
    414 415
             GHC.Core.Tidy
    
    415 416
             GHC.CoreToIface
    
    416 417
             GHC.CoreToStg
    

  • testsuite/tests/corelint/LintEtaExpand.stderr
    1 1
     <no location info>: warning:
    
    2 2
         • The first argument of ‘coerce’ does not have a fixed runtime representation:
    
    3 3
             a :: TYPE k
    
    4
    -    Substitution: <InScope = {a q}
    
    5
    -                   IdSubst   = []
    
    6
    -                   TvSubst   = []
    
    7
    -                   CvSubst   = []>
    
    8 4
     in coerce BAD 1
    
    9 5
     <no location info>: warning:
    
    10 6
         • The first argument of ‘coerce’ does not have a fixed runtime representation:
    
    11 7
             ‘q’ is not concrete.
    
    12
    -    Substitution: <InScope = {a q}
    
    13
    -                   IdSubst   = []
    
    14
    -                   TvSubst   = []
    
    15
    -                   CvSubst   = []>
    
    16 8
     in coerce BAD 2
    
    17 9
     <no location info>: warning:
    
    18 10
         • The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
    
    19 11
             a :: TYPE q
    
    20
    -    Substitution: <InScope = {a q}
    
    21
    -                   IdSubst   = []
    
    22
    -                   TvSubst   = []
    
    23
    -                   CvSubst   = []>
    
    24 12
     in catch# BAD 1
    
    25 13
     <no location info>: warning:
    
    26 14
         • The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
    
    27 15
             ‘q’ is not concrete.
    
    28
    -    Substitution: <InScope = {a q}
    
    29
    -                   IdSubst   = []
    
    30
    -                   TvSubst   = []
    
    31
    -                   CvSubst   = []>
    
    32 16
     in catch# BAD 2

  • testsuite/tests/corelint/T21115b.stderr
    ... ... @@ -6,10 +6,6 @@ T21115b.hs:9:1: warning:
    6 6
         In the body of lambda with binder ds :: Double#
    
    7 7
         In the body of a let with binder fail :: (# #) -> Int#
    
    8 8
         In the body of a let with binder fail :: (# #) -> Int#
    
    9
    -    Substitution: <InScope = {}
    
    10
    -                   IdSubst   = []
    
    11
    -                   TvSubst   = []
    
    12
    -                   CvSubst   = []>
    
    13 9
     *** Offending Program ***
    
    14 10
     Rec {
    
    15 11
     $trModule = Module (TrNameS "main"#) (TrNameS "T21115b"#)