Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

19 changed files:

Changes:

  • changelog.d/ghc-pkg-long-path-support
    1
    +section: ghc-pkg
    
    2
    +synopsis: Improve ``ghc-pkg``'s support for long paths on windows.
    
    3
    +issues: #26960
    
    4
    +mrs: !15584
    
    5
    +
    
    6
    +description: {
    
    7
    +    ``ghc-pkg`` can't handle working with file paths longer than the MAX_PATH
    
    8
    +    restrictions on windows as it is not using UNC file paths by default.
    
    9
    +
    
    10
    +    By using UNC file paths whenever possible, we improve ``ghc-pkg`` on windows.
    
    11
    +    Note, this still requires the user to enable the use of long paths in order to opt-in
    
    12
    +    this behaviour on older windows machines.
    
    13
    +}
    
    14
    +
    
    15
    +

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -18,7 +18,7 @@ module GHC.Core.Lint (
    18 18
         LintConfig (..),
    
    19 19
         WarnsAndErrs,
    
    20 20
     
    
    21
    -    lintCoreBindings', lintUnfolding,
    
    21
    +    lintCoreBindings, lintUnfolding,
    
    22 22
         lintPassResult, lintExpr,
    
    23 23
         lintAnnots, lintAxioms,
    
    24 24
     
    
    ... ... @@ -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.Lint.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
    
    ... ... @@ -456,11 +411,11 @@ lint_banner string pass = text "*** Core Lint" <+> text string
    456 411
                               <+> text "***"
    
    457 412
     
    
    458 413
     -- | Type-check a 'CoreProgram'. See Note [Core Lint guarantee].
    
    459
    -lintCoreBindings' :: LintConfig -> CoreProgram -> WarnsAndErrs
    
    414
    +lintCoreBindings :: LintConfig -> CoreProgram -> WarnsAndErrs
    
    460 415
     --   Returns (warnings, errors)
    
    461 416
     -- If you edit this function, you may need to update the GHC formalism
    
    462 417
     -- See Note [GHC Formalism]
    
    463
    -lintCoreBindings' cfg binds
    
    418
    +lintCoreBindings cfg binds
    
    464 419
       = initL cfg $
    
    465 420
         addLoc TopLevelBindings           $
    
    466 421
         do { -- Check that all top-level binders are distinct
    
    ... ... @@ -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,28 +509,28 @@ 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
    
    566
    -    lint_pair bndr' rhs
    
    567
    -      = addLoc (RhsOf bndr') $
    
    568
    -        do { (rhs_ty, ue) <- lintRhs bndr' rhs         -- Check the rhs
    
    569
    -           ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty
    
    520
    +    lint_pair bndr rhs
    
    521
    +      = addLoc (RhsOf bndr) $
    
    522
    +        do { (rhs_ty, ue) <- lintRhs bndr rhs         -- Check the rhs
    
    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
    
    ... ... @@ -651,14 +605,17 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty
    651 605
     
    
    652 606
                _ -> return ()
    
    653 607
     
    
    654
    -       ; addLoc (RuleOf binder) $ mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder)
    
    608
    +       -- Lint any RULES
    
    609
    +       ; addLoc (RuleOf binder) $
    
    610
    +         mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder)
    
    655 611
     
    
    612
    +       -- Lint the unfolding
    
    613
    +       -- Do this here, not in lintIdBinder, so that all the
    
    614
    +       -- binders of the letrec group are in scope
    
    656 615
            ; addLoc (UnfoldingOf binder) $
    
    657 616
              lintIdUnfolding binder binder_ty (idUnfolding binder)
    
    658
    -       ; return () }
    
    659 617
     
    
    660
    -        -- We should check the unfolding, if any, but this is tricky because
    
    661
    -        -- the unfolding is a SimplifiableCoreExpr. Give up for now.
    
    618
    +       ; return () }
    
    662 619
     
    
    663 620
     -- | Checks the RHS of bindings. It only differs from 'lintCoreExpr'
    
    664 621
     -- in that it doesn't reject occurrences of the function 'makeStatic' when they
    
    ... ... @@ -667,7 +624,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty
    667 624
     -- join point.
    
    668 625
     --
    
    669 626
     -- See Note [Checking StaticPtrs].
    
    670
    -lintRhs :: Id -> CoreExpr -> LintM (OutType, UsageEnv)
    
    627
    +lintRhs :: Id -> CoreExpr -> LintM (Type, UsageEnv)
    
    671 628
     -- NB: the Id can be Linted or not -- it's only used for
    
    672 629
     --     its OccInfo and join-pointer-hood
    
    673 630
     lintRhs bndr rhs
    
    ... ... @@ -682,7 +639,7 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go
    682 639
       where
    
    683 640
         -- Allow occurrences of 'makeStatic' at the top-level but produce errors
    
    684 641
         -- otherwise.
    
    685
    -    go :: StaticPtrCheck -> LintM (OutType, UsageEnv)
    
    642
    +    go :: StaticPtrCheck -> LintM (Type, UsageEnv)
    
    686 643
         go AllowAtTopLevel
    
    687 644
           | (binders0, rhs') <- collectTyBinders rhs
    
    688 645
           , Just (fun, t, info, e) <- collectMakeStaticArgs rhs'
    
    ... ... @@ -699,7 +656,7 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go
    699 656
     
    
    700 657
     -- | Lint the RHS of a join point with expected join arity of @n@ (see Note
    
    701 658
     -- [Join points] in "GHC.Core").
    
    702
    -lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (OutType, UsageEnv)
    
    659
    +lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (Type, UsageEnv)
    
    703 660
     lintJoinLams join_arity enforce rhs
    
    704 661
       = go join_arity rhs
    
    705 662
       where
    
    ... ... @@ -715,17 +672,22 @@ lintIdUnfolding :: Id -> Type -> Unfolding -> LintM ()
    715 672
     lintIdUnfolding bndr bndr_ty uf
    
    716 673
       | isStableUnfolding uf
    
    717 674
       , Just rhs <- maybeUnfoldingTemplate uf
    
    718
    -  = noMultiplicityChecks $ -- Skip linearity checking for unfoldings
    
    719
    -                           -- See Note [Linting linearity]
    
    720
    -  do { ty <- fst <$> (if isCompulsoryUnfolding uf
    
    721
    -                        then noFixedRuntimeRepChecks $ lintRhs bndr rhs
    
    722
    -            --               ^^^^^^^^^^^^^^^^^^^^^^^
    
    723
    -            -- See Note [Checking for representation polymorphism]
    
    724
    -                        else lintRhs bndr rhs)
    
    725
    -       ; ensureEqTys bndr_ty ty (mkRhsMsg bndr (text "unfolding") ty) }
    
    726
    -lintIdUnfolding  _ _ _
    
    727
    -  = return ()       -- Do not Lint unstable unfoldings, because that leads
    
    728
    -                    -- to exponential behaviour; c.f. GHC.Core.FVs.idUnfoldingVars
    
    675
    +   = suppress_rr_checks   $
    
    676
    +     noMultiplicityChecks $ -- Skip linearity checking for unfoldings
    
    677
    +                            -- See Note [Linting linearity]
    
    678
    +     do { (unf_ty, _unf_ue) <- lintRhs bndr rhs
    
    679
    +        ; ensureEqTys bndr_ty unf_ty (mkRhsMsg bndr (text "unfolding") unf_ty) }
    
    680
    +
    
    681
    +  | otherwise
    
    682
    +  = -- Do not Lint the body of an unstable unfolding, because that leads
    
    683
    +    -- to exponential behaviour; c.f. GHC.Core.FVs.idUnfoldingVars
    
    684
    +    return ()
    
    685
    +
    
    686
    +  where
    
    687
    +    -- See Note [Checking for representation polymorphism]
    
    688
    +    suppress_rr_checks thing_inside
    
    689
    +      | isCompulsoryUnfolding uf = noFixedRuntimeRepChecks thing_inside
    
    690
    +      | otherwise                = thing_inside
    
    729 691
     
    
    730 692
     {- Note [Checking for INLINE loop breakers]
    
    731 693
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -887,13 +849,8 @@ suspicious and worth investigating if you have a seg-fault or bizarre behaviour.
    887 849
     ************************************************************************
    
    888 850
     -}
    
    889 851
     
    
    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
    -
    
    852
    +lintCoreExpr :: CoreExpr -> LintM (Type, UsageEnv)
    
    853
    +-- The returned type is the type of the expression
    
    897 854
     -- If you edit this function, you may need to update the GHC formalism
    
    898 855
     -- See Note [GHC Formalism]
    
    899 856
     
    
    ... ... @@ -920,7 +877,7 @@ lintCoreExpr (Cast expr co)
    920 877
     
    
    921 878
            ; lintCoercion co
    
    922 879
            ; lintRole co Representational (coercionRole co)
    
    923
    -       ; Pair from_ty to_ty <- substCoKindM co
    
    880
    +       ; let Pair from_ty to_ty = coercionKind co
    
    924 881
            ; checkValueType (typeKind to_ty) $
    
    925 882
              text "target of cast" <+> quotes (ppr co)
    
    926 883
            ; ensureEqTys from_ty expr_ty (mkCastErr expr co from_ty expr_ty)
    
    ... ... @@ -934,27 +891,22 @@ lintCoreExpr (Tick tickish expr)
    934 891
     
    
    935 892
     lintCoreExpr (Let (NonRec tv (Type ty)) body)
    
    936 893
       | 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 } }
    
    894
    +  = do  { lintType ty
    
    895
    +        ; lintTyCoBndr tv              $
    
    896
    +    do  { addLoc (RhsOf tv)     $ lintTyKind tv ty
    
    897
    +        ; addLoc (BodyOfLet tv) $ lintCoreExpr body } }
    
    946 898
     
    
    947 899
     lintCoreExpr (Let (NonRec bndr rhs) body)
    
    948 900
       | isId bndr
    
    949 901
       = do { -- First Lint the RHS, before bringing the binder into scope
    
    950 902
              (rhs_ty, let_ue) <- lintRhs bndr rhs
    
    951 903
     
    
    952
    -          -- See Note [Multiplicity of let binders] in Var
    
    904
    +         -- See Note [Multiplicity of let binders] in Var
    
    953 905
              -- 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 } }
    
    906
    +       ; lintBinder LetBind bndr $
    
    907
    +    do { lintLetBind NotTopLevel NonRecursive bndr rhs rhs_ty
    
    908
    +       ; addAliasUE bndr let_ue $
    
    909
    +         lintLetBody (BodyOfLet bndr) [bndr] body } }
    
    958 910
     
    
    959 911
       | otherwise
    
    960 912
       = failWithL (mkLetErr bndr rhs)       -- Not quite accurate
    
    ... ... @@ -973,8 +925,8 @@ lintCoreExpr e@(Let (Rec pairs) body)
    973 925
     
    
    974 926
               -- See Note [Multiplicity of let binders] in Var
    
    975 927
             ; ((body_type, body_ue), ues) <-
    
    976
    -            lintRecBindings NotTopLevel pairs $ \ bndrs' ->
    
    977
    -            lintLetBody (BodyOfLetRec bndrs') bndrs' body
    
    928
    +            lintRecBindings NotTopLevel pairs $
    
    929
    +            lintLetBody (BodyOfLetRec bndrs) bndrs body
    
    978 930
             ; return (body_type, body_ue  `addUE` scaleUE ManyTy (foldr1WithDefault zeroUE addUE ues)) }
    
    979 931
       where
    
    980 932
         bndrs = map fst pairs
    
    ... ... @@ -986,7 +938,7 @@ lintCoreExpr e@(App _ _)
    986 938
         -- N.B. we may have an over-saturated application of the form:
    
    987 939
         --   runRW (\s -> \x -> ...) y
    
    988 940
       , ty_arg1 : ty_arg2 : cont_arg : rest <- args
    
    989
    -  = do { let lint_rw_cont :: CoreArg -> Mult -> UsageEnv -> LintM (OutType, UsageEnv)
    
    941
    +  = do { let lint_rw_cont :: CoreArg -> Mult -> UsageEnv -> LintM (Type, UsageEnv)
    
    990 942
                  lint_rw_cont expr@(Lam _ _) mult fun_ue
    
    991 943
                     = do { (arg_ty, arg_ue) <- lintJoinLams 1 (Just fun) expr
    
    992 944
                          ; let app_ue = addUE fun_ue (scaleUE mult arg_ue)
    
    ... ... @@ -1036,74 +988,73 @@ lintCoreExpr (Type ty)
    1036 988
     lintCoreExpr (Coercion co)
    
    1037 989
       -- See Note [Coercions in terms]
    
    1038 990
       = do { addLoc (InCo co) $ lintCoercion co
    
    1039
    -       ; ty <- substTyM (coercionType co)
    
    991
    +       ; let ty = coercionType co
    
    1040 992
            ; return (ty, zeroUE) }
    
    1041 993
     
    
    1042 994
     ----------------------
    
    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)
    
    995
    +lintIdOcc :: Id -> Int -- Number of arguments (type or value) being passed
    
    996
    +          -> LintM (Type, UsageEnv) -- returns type of the *variable*
    
    997
    +lintIdOcc id nargs
    
    998
    +  = addLoc (OccOf id) $
    
    999
    +    do  { checkL (isNonCoVarId id)
    
    1000
    +                 (text "Non term variable" <+> ppr id)
    
    1049 1001
                      -- See GHC.Core Note [Variable occurrences in Core]
    
    1050 1002
     
    
    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
    
    1003
    +        ; lintVarOcc id
    
    1063 1004
     
    
    1064 1005
               -- Check for a nested occurrence of the StaticPtr constructor.
    
    1065 1006
               -- See Note [Checking StaticPtrs].
    
    1066 1007
             ; when (nargs /= 0) $
    
    1067
    -          checkL (idName in_id /= makeStaticName) $
    
    1008
    +          checkL (idName id /= makeStaticName) $
    
    1068 1009
               text "Found makeStatic nested in an expression"
    
    1069 1010
     
    
    1070
    -        ; checkDeadIdOcc in_id
    
    1011
    +        ; checkDeadIdOcc id
    
    1071 1012
     
    
    1072
    -        ; case isDataConId_maybe in_id of
    
    1013
    +        ; case isDataConId_maybe id of
    
    1073 1014
                  Nothing -> return ()
    
    1074 1015
                  Just dc -> checkTypeDataConOcc "expression" dc
    
    1075 1016
     
    
    1076
    -        ; checkJoinOcc in_id nargs
    
    1077
    -        ; usage <- varCallSiteUsage in_id
    
    1078
    -
    
    1079
    -        ; return (out_ty, usage) }
    
    1017
    +        ; checkJoinOcc id nargs
    
    1018
    +        ; usage <- varCallSiteUsage id
    
    1080 1019
     
    
    1020
    +        ; return (idType id, usage) }
    
    1081 1021
     
    
    1082 1022
     
    
    1023
    +------------------
    
    1083 1024
     lintCoreFun :: CoreExpr
    
    1084
    -            -> Int                          -- Number of arguments (type or val) being passed
    
    1085
    -            -> LintM (OutType, UsageEnv) -- Returns type of the *function*
    
    1025
    +            -> Int                    -- Number of arguments (type or val) being passed
    
    1026
    +            -> LintM (Type, UsageEnv) -- Returns type of the *function*
    
    1086 1027
     lintCoreFun (Var var) nargs
    
    1087 1028
       = lintIdOcc var nargs
    
    1088 1029
     
    
    1089 1030
     lintCoreFun (Lam var body) nargs
    
    1090
    -  -- Act like lintCoreExpr of Lam, but *don't* call markAllJoinsBad;
    
    1091
    -  -- See Note [Beta redexes]
    
    1031
    +  -- Act like lintCoreExpr of Lam, but *don't* necessarily call markAllJoinsBad;
    
    1032
    +  -- See Note [Join points and beta-redexes]
    
    1092 1033
       | nargs /= 0
    
    1093 1034
       = lintLambda var $ lintCoreFun body (nargs - 1)
    
    1094 1035
     
    
    1095 1036
     lintCoreFun expr nargs
    
    1096
    -  = markAllJoinsBadIf (nargs /= 0) $
    
    1097
    -      -- See Note [Join points are less general than the paper]
    
    1098
    -    lintCoreExpr expr
    
    1037
    +  = do { mark_bad_joins
    
    1038
    +           <- if nargs == 0
    
    1039
    +              then -- Saturated lambda
    
    1040
    +                   -- See Note [Join points and beta-redexes]
    
    1041
    +                   do { flags <- getLintFlags
    
    1042
    +                      ; return (not (lf_allow_beta_joins flags)) }
    
    1043
    +              else -- Something else
    
    1044
    +                   -- See Note [Join points are less general than the paper]
    
    1045
    +                   return True
    
    1046
    +
    
    1047
    +       ; markAllJoinsBadIf mark_bad_joins $
    
    1048
    +         lintCoreExpr expr }
    
    1049
    +
    
    1099 1050
     ------------------
    
    1100 1051
     lintLambda :: Var -> LintM (Type, UsageEnv) -> LintM (Type, UsageEnv)
    
    1101 1052
     lintLambda var lintBody =
    
    1102 1053
         addLoc (LambdaBodyOf var) $
    
    1103
    -    lintBinder LambdaBind var $ \ var' ->
    
    1054
    +    lintBinder LambdaBind var $
    
    1104 1055
         do { (body_ty, ue) <- lintBody
    
    1105
    -       ; ue' <- checkLinearity ue var'
    
    1106
    -       ; return (mkLamType var' body_ty, ue') }
    
    1056
    +       ; ue' <- checkLinearity ue var
    
    1057
    +       ; return (mkLamType var body_ty, ue') }
    
    1107 1058
     ------------------
    
    1108 1059
     checkDeadIdOcc :: Id -> LintM ()
    
    1109 1060
     -- Occurrences of an Id should never be dead....
    
    ... ... @@ -1117,8 +1068,8 @@ checkDeadIdOcc id
    1117 1068
       = return ()
    
    1118 1069
     
    
    1119 1070
     ------------------
    
    1120
    -lintJoinBndrType :: OutType -- Type of the body
    
    1121
    -                 -> OutId   -- Possibly a join Id
    
    1071
    +lintJoinBndrType :: Type -- Type of the body
    
    1072
    +                 -> Id   -- Possibly a join Id
    
    1122 1073
                      -> LintM ()
    
    1123 1074
     -- Checks that the return type of a join Id matches the body
    
    1124 1075
     -- E.g. join j x = rhs in body
    
    ... ... @@ -1337,8 +1288,55 @@ checkLinearity body_ue lam_var =
    1337 1288
           return body_ue'
    
    1338 1289
         Nothing    -> return body_ue -- A type variable
    
    1339 1290
     
    
    1340
    -{- Note [Linting join points with casts or ticks]
    
    1341
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1291
    +{- Note [Join points and beta-redexes]
    
    1292
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1293
    +In the worker/wrapper pass, the worker invokes the original function by calling
    
    1294
    +it with arguments, thus producing a beta-redex for the simplifier to munch away:
    
    1295
    +
    
    1296
    +  \x y z -> e   =>    (\x y z -> e) wx wy wz
    
    1297
    +
    
    1298
    +But we need to take care if `e` invokes a join point.  For example:
    
    1299
    +
    
    1300
    +  join j1 x = ...
    
    1301
    +  join j2 y = if y == 0 then 0 else j1 y
    
    1302
    +=>
    
    1303
    +  join j1 x = ...
    
    1304
    +  join $wj2 y# = (\y -> if y == 0 then 0 else jump j1 y) (I# y#)
    
    1305
    +  join j2 y = case y of I# y# -> jump $wj2 y#
    
    1306
    +
    
    1307
    +Now the jump to `j1` is inside a lambda and inside an application. That is ill-typed
    
    1308
    +from Lint's point of view.  And yet, after one round of simplification it'll all be
    
    1309
    +fine.
    
    1310
    +
    
    1311
    +You might wonder if we could use a `let` instead of a lambda for the worker:
    
    1312
    +
    
    1313
    +  join $wj2 y# = let y = I# y#
    
    1314
    +                 in  if y == 0 then 0 else jump j1 y
    
    1315
    +
    
    1316
    +That would solve the join-point problem, but it really doesn't work because
    
    1317
    + 1. The lets shadow each other
    
    1318
    + 2. In particular the invariant (NoTypeShadowing) is easily broken.
    
    1319
    +    (We might have type lambdas of course.)
    
    1320
    +
    
    1321
    +In short, te lambda arguments should not "see" any of the lambda-bound
    
    1322
    +variables.
    
    1323
    +
    
    1324
    +So our solution is this:
    
    1325
    +
    
    1326
    +* Use straightforward applicaion in the worker-wrapper pass, creating a beta-redex.
    
    1327
    +  See the call to `mkApps` in GHC.Core.Opt.WorkWrap.Utils.mkWwBodies.
    
    1328
    +
    
    1329
    +* Tell Lint not to complain about a join-point invocation hidden under a
    
    1330
    +  saturated beta-redex.  The code is rather simple: see `lintCoreFun`.
    
    1331
    +
    
    1332
    +  We guard this with a Lint flag `lf_allow_beta_joins`.
    
    1333
    +
    
    1334
    +* Teach occurrence analysis that `j1` is still a join point, despite its
    
    1335
    +  call being nested inside the beta-redex.  See Note [occAnal for applications]
    
    1336
    +  in GHC.Core.Opt.OccurAnal.
    
    1337
    +
    
    1338
    +Note [Linting join points with casts or ticks]
    
    1339
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1342 1340
     As per Note [Join points, casts, and ticks] in GHC.Core, we have to be careful
    
    1343 1341
     when a cast or tick occurs in between a join point binding and a corresponding
    
    1344 1342
     join point occurrence.
    
    ... ... @@ -1409,33 +1407,6 @@ lose track of why an expression is bottom, so we shouldn't make too
    1409 1407
     much fuss when that happens.
    
    1410 1408
     
    
    1411 1409
     
    
    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 1410
     ************************************************************************
    
    1440 1411
     *                                                                      *
    
    1441 1412
     \subsection[lintCoreArgs]{lintCoreArgs}
    
    ... ... @@ -1449,23 +1420,23 @@ subtype of the required type, as one would expect.
    1449 1420
     -- Takes the functions type and arguments as argument.
    
    1450 1421
     -- Returns the *result* of applying the function to arguments.
    
    1451 1422
     -- e.g. f :: Int -> Bool -> Int would return `Int` as result type.
    
    1452
    -lintCoreArgs  :: (OutType, UsageEnv) -> [InExpr] -> LintM (OutType, UsageEnv)
    
    1423
    +lintCoreArgs  :: (Type, UsageEnv) -> [CoreExpr] -> LintM (Type, UsageEnv)
    
    1453 1424
     lintCoreArgs (fun_ty, fun_ue) args
    
    1454
    -  = lintApp (text "expression")
    
    1455
    -              lintTyArg lintValArg fun_ty args fun_ue
    
    1425
    +  = lintApp (text "expression") lintTyArg lintValArg fun_ty args fun_ue
    
    1456 1426
     
    
    1457
    -lintTyArg :: InExpr -> LintM OutType
    
    1427
    +lintTyArg :: CoreExpr -> LintM Type
    
    1458 1428
     
    
    1459 1429
     -- Type argument
    
    1460 1430
     lintTyArg (Type arg_ty)
    
    1461 1431
       = do { checkL (not (isCoercionTy arg_ty))
    
    1462 1432
                     (text "Unnecessary coercion-to-type injection:"
    
    1463 1433
                       <+> ppr arg_ty)
    
    1464
    -       ; lintTypeAndSubst arg_ty }
    
    1434
    +       ; lintType arg_ty
    
    1435
    +       ; return arg_ty }
    
    1465 1436
     lintTyArg arg
    
    1466 1437
       = failWithL (hang (text "Expected type argument but found") 2 (ppr arg))
    
    1467 1438
     
    
    1468
    -lintValArg  :: InExpr -> Mult -> UsageEnv -> LintM (OutType, UsageEnv)
    
    1439
    +lintValArg  :: CoreExpr -> Mult -> UsageEnv -> LintM (Type, UsageEnv)
    
    1469 1440
     lintValArg arg mult fun_ue
    
    1470 1441
       = do { (arg_ty, arg_ue) <- markAllJoinsBad $ lintCoreExpr arg
    
    1471 1442
                -- See Note [Representation polymorphism invariants] in GHC.Core
    
    ... ... @@ -1484,9 +1455,9 @@ lintValArg arg mult fun_ue
    1484 1455
     
    
    1485 1456
     -----------------
    
    1486 1457
     lintAltBinders :: UsageEnv
    
    1487
    -               -> Var         -- Case binder
    
    1488
    -               -> OutType     -- Scrutinee type
    
    1489
    -               -> OutType     -- Constructor type
    
    1458
    +               -> Var      -- Case binder
    
    1459
    +               -> Type     -- Scrutinee type
    
    1460
    +               -> Type     -- Constructor type
    
    1490 1461
                    -> [(Mult, OutVar)]    -- Binders
    
    1491 1462
                    -> LintM UsageEnv
    
    1492 1463
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -1505,6 +1476,7 @@ lintAltBinders rhs_ue case_bndr scrut_ty con_ty ((var_w, bndr):bndrs)
    1505 1476
            ; rhs_ue' <- checkCaseLinearity rhs_ue case_bndr var_w bndr
    
    1506 1477
            ; lintAltBinders rhs_ue' case_bndr scrut_ty con_ty' bndrs }
    
    1507 1478
     
    
    1479
    +
    
    1508 1480
     -- | Implements the case rules for linearity
    
    1509 1481
     checkCaseLinearity :: UsageEnv -> Var -> Mult -> Var -> LintM UsageEnv
    
    1510 1482
     checkCaseLinearity ue case_bndr var_w bndr = do
    
    ... ... @@ -1529,7 +1501,7 @@ checkCaseLinearity ue case_bndr var_w bndr = do
    1529 1501
     
    
    1530 1502
     
    
    1531 1503
     -----------------
    
    1532
    -lintTyApp :: OutType -> OutType -> LintM OutType
    
    1504
    +lintTyApp :: Type -> Type -> LintM Type
    
    1533 1505
     lintTyApp fun_ty arg_ty
    
    1534 1506
       | Just (tv,body_ty) <- splitForAllTyVar_maybe fun_ty
    
    1535 1507
       = do  { lintTyKind tv arg_ty
    
    ... ... @@ -1547,8 +1519,8 @@ lintTyApp fun_ty arg_ty
    1547 1519
     -- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@
    
    1548 1520
     -- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the
    
    1549 1521
     -- application.
    
    1550
    -lintValApp :: CoreExpr -> OutType -> OutType -> UsageEnv -> UsageEnv
    
    1551
    -           -> LintM (OutType, UsageEnv)
    
    1522
    +lintValApp :: CoreExpr -> Type -> Type -> UsageEnv -> UsageEnv
    
    1523
    +           -> LintM (Type, UsageEnv)
    
    1552 1524
     lintValApp arg fun_ty arg_ty fun_ue arg_ue
    
    1553 1525
       | Just (_, w, arg_ty', res_ty') <- splitFunTy_maybe fun_ty
    
    1554 1526
       = do { ensureEqTys arg_ty' arg_ty (mkAppMsg arg_ty' arg_ty arg)
    
    ... ... @@ -1559,9 +1531,7 @@ lintValApp arg fun_ty arg_ty fun_ue arg_ue
    1559 1531
       where
    
    1560 1532
         err2 = mkNonFunAppMsg fun_ty arg_ty arg
    
    1561 1533
     
    
    1562
    -lintTyKind :: OutTyVar -> OutType -> LintM ()
    
    1563
    --- Both args have had substitution applied
    
    1564
    -
    
    1534
    +lintTyKind :: OutTyVar -> Type -> LintM ()
    
    1565 1535
     -- If you edit this function, you may need to update the GHC formalism
    
    1566 1536
     -- See Note [GHC Formalism]
    
    1567 1537
     lintTyKind tyvar arg_ty
    
    ... ... @@ -1579,36 +1549,36 @@ lintTyKind tyvar arg_ty
    1579 1549
     ************************************************************************
    
    1580 1550
     -}
    
    1581 1551
     
    
    1582
    -lintCaseExpr :: CoreExpr -> InId -> InType -> [CoreAlt] -> LintM (OutType, UsageEnv)
    
    1552
    +lintCaseExpr :: CoreExpr -> Id -> Type -> [CoreAlt] -> LintM (Type, UsageEnv)
    
    1583 1553
     lintCaseExpr scrut case_bndr alt_ty alts
    
    1584 1554
       = do { let e = Case scrut case_bndr alt_ty alts   -- Just for error messages
    
    1585 1555
     
    
    1586 1556
            -- Check the scrutinee
    
    1587
    -       ; (scrut_ty', scrut_ue) <- markAllJoinsBad $ lintCoreExpr scrut
    
    1557
    +       ; (scrut_ty, scrut_ue) <- markAllJoinsBad $ lintCoreExpr scrut
    
    1588 1558
                 -- See Note [Join points are less general than the paper]
    
    1589 1559
                 -- in GHC.Core
    
    1590 1560
     
    
    1591
    -       ; alt_ty' <- addLoc (CaseTy scrut) $ lintValueType alt_ty
    
    1561
    +       ; addLoc (CaseTy scrut) $ lintValueType alt_ty
    
    1592 1562
     
    
    1593
    -       ; checkCaseAlts e scrut scrut_ty' alts
    
    1563
    +       ; checkCaseAlts e scrut scrut_ty alts
    
    1594 1564
     
    
    1595 1565
            -- Lint the case-binder. Must do this after linting the scrutinee
    
    1596 1566
            -- because the case-binder isn't in scope in the scrutineex
    
    1597
    -       ; lintBinder CaseBind case_bndr $ \case_bndr' ->
    
    1567
    +       ; lintBinder CaseBind case_bndr $
    
    1598 1568
           -- Don't use lintIdBndr on case_bndr, because unboxed tuple is legitimate
    
    1599 1569
     
    
    1600
    -    do { let case_bndr_ty' = idType case_bndr'
    
    1601
    -             scrut_mult    = idMult case_bndr'
    
    1570
    +    do { let case_bndr_ty = idType case_bndr
    
    1571
    +             scrut_mult   = idMult case_bndr
    
    1602 1572
     
    
    1603
    -       ; ensureEqTys case_bndr_ty' scrut_ty' (mkScrutMsg case_bndr case_bndr_ty' scrut_ty')
    
    1573
    +       ; ensureEqTys case_bndr_ty scrut_ty (mkScrutMsg case_bndr case_bndr_ty scrut_ty)
    
    1604 1574
              -- See GHC.Core Note [Case expression invariants] item (7)
    
    1605 1575
     
    
    1606 1576
            ; -- Check the alternatives
    
    1607
    -       ; alt_ues <- mapM (lintCoreAlt case_bndr' scrut_ty' scrut_mult alt_ty') alts
    
    1577
    +       ; alt_ues <- mapM (lintCoreAlt case_bndr scrut_ty scrut_mult alt_ty) alts
    
    1608 1578
            ; let case_ue = (scaleUE scrut_mult scrut_ue) `addUE` supUEs alt_ues
    
    1609
    -       ; return (alt_ty', case_ue) } }
    
    1579
    +       ; return (alt_ty, case_ue) } }
    
    1610 1580
     
    
    1611
    -checkCaseAlts :: InExpr -> InExpr -> OutType -> [CoreAlt] -> LintM ()
    
    1581
    +checkCaseAlts :: CoreExpr -> CoreExpr -> Type -> [CoreAlt] -> LintM ()
    
    1612 1582
     -- a) Check that the alts are non-empty
    
    1613 1583
     -- b1) Check that the DEFAULT comes first, if it exists
    
    1614 1584
     -- b2) Check that the others are in increasing order
    
    ... ... @@ -1683,17 +1653,17 @@ checkCaseAlts e scrut scrut_ty alts
    1683 1653
         is_lit_alt (Alt (LitAlt _) _  _) = True
    
    1684 1654
         is_lit_alt _                     = False
    
    1685 1655
     
    
    1686
    -lintAltExpr :: CoreExpr -> OutType -> LintM UsageEnv
    
    1656
    +lintAltExpr :: CoreExpr -> Type -> LintM UsageEnv
    
    1687 1657
     lintAltExpr expr ann_ty
    
    1688 1658
       = do { (actual_ty, ue) <- lintCoreExpr expr
    
    1689 1659
            ; ensureEqTys actual_ty ann_ty (mkCaseAltMsg expr actual_ty ann_ty)
    
    1690 1660
            ; return ue }
    
    1691 1661
              -- See GHC.Core Note [Case expression invariants] item (6)
    
    1692 1662
     
    
    1693
    -lintCoreAlt :: OutId         -- Case binder
    
    1694
    -            -> OutType       -- Type of scrutinee
    
    1663
    +lintCoreAlt :: Id         -- Case binder
    
    1664
    +            -> Type       -- Type of scrutinee
    
    1695 1665
                 -> Mult          -- Multiplicity of scrutinee
    
    1696
    -            -> OutType       -- Type of the alternative
    
    1666
    +            -> Type       -- Type of the alternative
    
    1697 1667
                 -> CoreAlt
    
    1698 1668
                 -> LintM UsageEnv
    
    1699 1669
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -1738,11 +1708,11 @@ lintCoreAlt case_bndr scrut_ty _scrut_mult alt_ty alt@(Alt (DataAlt con) args rh
    1738 1708
               ; multiplicities = map binderMult $ fst $ splitPiTys con_payload_ty }
    
    1739 1709
     
    
    1740 1710
             -- And now bring the new binders into scope
    
    1741
    -    ; lintBinders CasePatBind args $ \ args' -> do
    
    1711
    +    ; lintBinders CasePatBind args $ do
    
    1742 1712
           { rhs_ue <- lintAltExpr rhs alt_ty
    
    1743 1713
           ; rhs_ue' <- addLoc (CasePat alt) $
    
    1744 1714
                        lintAltBinders rhs_ue case_bndr scrut_ty con_payload_ty
    
    1745
    -                                  (zipEqual multiplicities  args')
    
    1715
    +                                  (zipEqual multiplicities  args)
    
    1746 1716
           ; return $ deleteUE rhs_ue' case_bndr
    
    1747 1717
           }
    
    1748 1718
        }
    
    ... ... @@ -1784,54 +1754,52 @@ lintLinearBinder doc actual_usage described_usage
    1784 1754
     -}
    
    1785 1755
     
    
    1786 1756
     -- 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')
    
    1757
    +--  1. Lint var types or kinds
    
    1758
    +--  2. Add the binder to the in scope set
    
    1759
    +lintBinders :: HasDebugCallStack => BindingSite -> [Var] -> LintM a -> LintM a
    
    1760
    +lintBinders _    []         linterF = linterF
    
    1761
    +lintBinders site (var:vars) linterF = lintBinder site var $
    
    1762
    +                                      lintBinders site vars $
    
    1763
    +                                      linterF
    
    1795 1764
     
    
    1796 1765
     -- If you edit this function, you may need to update the GHC formalism
    
    1797 1766
     -- See Note [GHC Formalism]
    
    1798
    -lintBinder :: HasDebugCallStack => BindingSite -> InVar -> (OutVar -> LintM a) -> LintM a
    
    1767
    +lintBinder :: HasDebugCallStack => BindingSite -> Var -> LintM a -> LintM a
    
    1799 1768
     lintBinder site var linterF
    
    1800 1769
       | isTyCoVar var = lintTyCoBndr var linterF
    
    1801 1770
       | otherwise     = lintIdBndr NotTopLevel site var linterF
    
    1802 1771
     
    
    1803
    -lintTyCoBndr :: HasDebugCallStack => TyCoVar -> (OutTyCoVar -> LintM a) -> LintM a
    
    1772
    +lintTyCoBndr :: HasDebugCallStack => TyCoVar -> LintM a -> LintM a
    
    1804 1773
     lintTyCoBndr tcv thing_inside
    
    1805
    -  = do { tcv_type' <- lintTypeAndSubst (varType tcv)
    
    1806
    -       ; let tcv_kind' = typeKind tcv_type'
    
    1774
    +  = do { let tcv_type = varType tcv
    
    1775
    +             tcv_kind = typeKind tcv_type
    
    1807 1776
     
    
    1777
    +       ; lintType (varType tcv)
    
    1808 1778
              -- See (FORALL1) and (FORALL2) in GHC.Core.Type
    
    1809 1779
            ; if (isTyVar tcv)
    
    1810 1780
              then -- Check that in (forall (a:ki). blah) we have ki:Type
    
    1811
    -              lintL (isLiftedTypeKind tcv_kind') $
    
    1781
    +              lintL (isLiftedTypeKind tcv_kind) $
    
    1812 1782
                   hang (text "TyVar whose kind does not have kind Type:")
    
    1813
    -                 2 (ppr tcv <+> dcolon <+> ppr tcv_type' <+> dcolon <+> ppr tcv_kind')
    
    1783
    +                 2 (ppr tcv <+> dcolon <+> ppr tcv_type <+> dcolon <+> ppr tcv_kind)
    
    1814 1784
              else -- Check that in (forall (cv::ty). blah),
    
    1815 1785
                   -- then ty looks like (t1 ~# t2)
    
    1816
    -              lintL (isCoVarType tcv_type') $
    
    1786
    +              lintL (isCoVarType tcv_type) $
    
    1817 1787
                   text "CoVar with non-coercion type:" <+> pprTyVar tcv
    
    1818 1788
     
    
    1819
    -       ; addInScopeTyCoVar tcv tcv_type' thing_inside }
    
    1789
    +       ; addInScopeTyCoVar tcv thing_inside }
    
    1820 1790
     
    
    1821
    -lintIdBndrs :: forall a. TopLevelFlag -> [InId] -> ([OutId] -> LintM a) -> LintM a
    
    1791
    +lintIdBndrs :: forall a. TopLevelFlag -> [Id] -> LintM a -> LintM a
    
    1822 1792
     lintIdBndrs top_lvl ids thing_inside
    
    1823 1793
       = go ids thing_inside
    
    1824 1794
       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')
    
    1795
    +    go :: [Id] -> LintM a -> LintM a
    
    1796
    +    go []       thing_inside = thing_inside
    
    1797
    +    go (id:ids) thing_inside = lintIdBndr top_lvl LetBind id  $
    
    1798
    +                               go ids                         $
    
    1799
    +                               thing_inside
    
    1830 1800
     
    
    1831 1801
     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
    
    1802
    +           -> Var -> LintM a -> LintM a
    
    1835 1803
     -- ToDo: lint its rules
    
    1836 1804
     lintIdBndr top_lvl bind_site id thing_inside
    
    1837 1805
       = assertPpr (isId id) (ppr id) $
    
    ... ... @@ -1864,14 +1832,16 @@ lintIdBndr top_lvl bind_site id thing_inside
    1864 1832
            ; lintL (not (isCoVarType id_ty))
    
    1865 1833
                    (text "Non-CoVar has coercion type" <+> ppr id <+> dcolon <+> ppr id_ty)
    
    1866 1834
     
    
    1867
    -       -- Check that the lambda binder has no value or OtherCon unfolding.
    
    1835
    +       -- Check that lambda-bound Ids have no unfolding; not even OtherCon
    
    1868 1836
            -- See #21496
    
    1869
    -       ; lintL (not (bind_site == LambdaBind && isEvaldUnfolding (idUnfolding id)))
    
    1870
    -                (text "Lambda binder with value or OtherCon unfolding.")
    
    1837
    +       ; let unf = idUnfolding id
    
    1838
    +       ; checkL (not (bind_site == LambdaBind && hasSomeUnfolding unf)) $
    
    1839
    +         hang (text "Lambda binder" <+> quotes (ppr id) <+> text "has an unfolding")
    
    1840
    +            2 (ppr unf)
    
    1871 1841
     
    
    1872
    -       ; out_ty <- addLoc (IdTy id) (lintValueType id_ty)
    
    1842
    +       ; addLoc (IdTy id) (lintValueType id_ty)
    
    1873 1843
     
    
    1874
    -       ; addInScopeId id out_ty thing_inside }
    
    1844
    +       ; addInScopeId id thing_inside }
    
    1875 1845
       where
    
    1876 1846
         id_ty = idType id
    
    1877 1847
     
    
    ... ... @@ -1891,62 +1861,44 @@ lintIdBndr top_lvl bind_site id thing_inside
    1891 1861
     {- Note [Linting types and coercions]
    
    1892 1862
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1893 1863
     Notice that
    
    1894
    -   lintType     :: InType     -> LintM ()
    
    1895
    -   lintCoercion :: InCoercion -> LintM ()
    
    1864
    +   lintType     :: Type     -> LintM ()
    
    1865
    +   lintCoercion :: Coercion -> LintM ()
    
    1896 1866
     Neither returns anything.
    
    1897 1867
     
    
    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.
    
    1868
    +Note: you might wonder why we have
    
    1869
    +  lintExpr :: CoreExpr -> LintM Type
    
    1870
    +  lintType :: Type     -> LintM ()
    
    1871
    +
    
    1872
    +That is, linting an expression yields its type, but linting a type does not
    
    1873
    +yield its kind. Partly inertia; but:
    
    1874
    +
    
    1875
    +* Taking the type of an expresison involves looking down a deep chain of let's,
    
    1876
    +  whereas that is not true of taking the kind of a type.  It'd be worth an
    
    1877
    +  experiment though.
    
    1878
    +
    
    1879
    +* I did experiment with
    
    1880
    +   lintType :: Type -> LintM Kind
    
    1881
    +  but that too was slower.  It is also much simpler to return ()!  If we return
    
    1882
    +  the kind we have to duplicate the logic in `typeKind`; and it is much worse
    
    1883
    +  for coercions.
    
    1923 1884
     -}
    
    1924 1885
     
    
    1925
    -lintValueType :: Type -> LintM OutType
    
    1886
    +lintValueType :: Type -> LintM ()
    
    1926 1887
     -- Types only, not kinds
    
    1927
    --- Check the type, and apply the substitution to it
    
    1928
    --- See Note [Linting type lets]
    
    1929 1888
     lintValueType ty
    
    1930 1889
       = addLoc (InType ty) $
    
    1931
    -    do  { ty' <- lintTypeAndSubst ty
    
    1932
    -        ; let sk = typeKind ty'
    
    1890
    +    do  { lintType ty
    
    1891
    +        ; let sk = typeKind ty
    
    1933 1892
             ; lintL (isTYPEorCONSTRAINT sk) $
    
    1934 1893
               hang (text "Ill-kinded type:" <+> ppr ty)
    
    1935
    -             2 (text "has kind:" <+> ppr sk)
    
    1936
    -        ; return ty' }
    
    1894
    +             2 (text "has kind:" <+> ppr sk)}
    
    1937 1895
     
    
    1938 1896
     checkTyCon :: TyCon -> LintM ()
    
    1939 1897
     checkTyCon tc
    
    1940 1898
       = checkL (not (isTcTyCon tc)) (text "Found TcTyCon:" <+> ppr tc)
    
    1941 1899
     
    
    1942 1900
     -------------------
    
    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 ()
    
    1901
    +lintType :: Type -> LintM ()
    
    1950 1902
     -- See Note [Linting types and coercions]
    
    1951 1903
     --
    
    1952 1904
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -1956,8 +1908,7 @@ lintType (TyVarTy tv)
    1956 1908
       = failWithL (mkBadTyVarMsg tv)
    
    1957 1909
     
    
    1958 1910
       | otherwise
    
    1959
    -  = do { _ <- lintVarOcc tv
    
    1960
    -       ; return () }
    
    1911
    +  = lintVarOcc tv
    
    1961 1912
     
    
    1962 1913
     lintType ty@(AppTy t1 t2)
    
    1963 1914
       | TyConApp {} <- t1
    
    ... ... @@ -1965,7 +1916,7 @@ lintType ty@(AppTy t1 t2)
    1965 1916
       | otherwise
    
    1966 1917
       = do { let (fun_ty, arg_tys) = collect t1 [t2]
    
    1967 1918
            ; lintType fun_ty
    
    1968
    -       ; fun_kind <- substTyM (typeKind fun_ty)
    
    1919
    +       ; let fun_kind = typeKind fun_ty
    
    1969 1920
            ; lint_ty_app ty fun_kind arg_tys }
    
    1970 1921
       where
    
    1971 1922
         collect (AppTy f a) as = collect f (a:as)
    
    ... ... @@ -1997,21 +1948,21 @@ lintType ty@(FunTy af tw t1 t2)
    1997 1948
     lintType ty@(ForAllTy {})
    
    1998 1949
       = go [] ty
    
    1999 1950
       where
    
    2000
    -    go :: [OutTyCoVar] -> InType -> LintM ()
    
    1951
    +    go :: [OutTyCoVar] -> Type -> LintM ()
    
    2001 1952
         -- Loop, collecting the forall-binders
    
    2002 1953
         go tcvs ty@(ForAllTy (Bndr tcv _) body_ty)
    
    2003 1954
           | not (isTyCoVar tcv)
    
    2004 1955
           = failWithL (text "Non-TyVar or Non-CoVar bound in type:" <+> ppr ty)
    
    2005 1956
     
    
    2006 1957
           | otherwise
    
    2007
    -      = lintTyCoBndr tcv $ \tcv' ->
    
    1958
    +      = lintTyCoBndr tcv $
    
    2008 1959
             do { -- See GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy]
    
    2009 1960
                  -- Suspicious because it works on InTyCoVar; c.f. ForAllCo
    
    2010 1961
                  when (isCoVar tcv) $
    
    2011 1962
                  lintL (anyFreeVarsOfType (== tcv) body_ty) $
    
    2012 1963
                  text "Covar does not occur in the body:" <+> (ppr tcv $$ ppr body_ty)
    
    2013 1964
     
    
    2014
    -           ; go (tcv' : tcvs) body_ty }
    
    1965
    +           ; go (tcv : tcvs) body_ty }
    
    2015 1966
     
    
    2016 1967
         go tcvs body_ty
    
    2017 1968
           = do { lintType body_ty
    
    ... ... @@ -2019,7 +1970,7 @@ lintType ty@(ForAllTy {})
    2019 1970
     
    
    2020 1971
     lintType (CastTy ty co)
    
    2021 1972
       = do { lintType ty
    
    2022
    -       ; ty_kind <- substTyM (typeKind ty)
    
    1973
    +       ; let ty_kind = typeKind ty
    
    2023 1974
            ; co_lk <- lintStarCoercion co
    
    2024 1975
            ; ensureEqTys ty_kind co_lk (mkCastTyErr ty co ty_kind co_lk) }
    
    2025 1976
     
    
    ... ... @@ -2027,14 +1978,14 @@ lintType (LitTy l) = lintTyLit l
    2027 1978
     lintType (CoercionTy co) = lintCoercion co
    
    2028 1979
     
    
    2029 1980
     -----------------
    
    2030
    -lintForAllBody :: [OutTyCoVar] -> InType -> LintM ()
    
    1981
    +lintForAllBody :: [OutTyCoVar] -> Type -> LintM ()
    
    2031 1982
     -- Do the checks for the body of a forall-type
    
    2032 1983
     lintForAllBody tcvs body_ty
    
    2033 1984
       = do { -- For type variables, check for skolem escape
    
    2034 1985
              -- See Note [Phantom type variables in kinds] in GHC.Core.Type
    
    2035 1986
              -- The kind of (forall cv. th) is liftedTypeKind, so no
    
    2036 1987
              -- need to check for skolem-escape in the CoVar case
    
    2037
    -         body_kind <- substTyM (typeKind body_ty)
    
    1988
    +         let body_kind = typeKind body_ty
    
    2038 1989
            ; case occCheckExpand tcvs body_kind of
    
    2039 1990
                Just {} -> return ()
    
    2040 1991
                Nothing -> failWithL $
    
    ... ... @@ -2045,7 +1996,7 @@ lintForAllBody tcvs body_ty
    2045 1996
            ; checkValueType body_kind (text "the body of forall:" <+> ppr body_ty) }
    
    2046 1997
     
    
    2047 1998
     -----------------
    
    2048
    -lintTySynFamApp :: Bool -> InType -> TyCon -> [InType] -> LintM ()
    
    1999
    +lintTySynFamApp :: Bool -> Type -> TyCon -> [Type] -> LintM ()
    
    2049 2000
     -- The TyCon is a type synonym or a type family (not a data family)
    
    2050 2001
     -- See Note [Linting type synonym applications]
    
    2051 2002
     -- c.f. GHC.Tc.Validity.check_syn_tc_app
    
    ... ... @@ -2071,21 +2022,21 @@ lintTySynFamApp report_unsat ty tc tys
    2071 2022
     
    
    2072 2023
     -----------------
    
    2073 2024
     -- Confirms that a kind is really TYPE r or Constraint
    
    2074
    -checkValueType :: OutKind -> SDoc -> LintM ()
    
    2025
    +checkValueType :: Kind -> SDoc -> LintM ()
    
    2075 2026
     checkValueType kind doc
    
    2076 2027
       = lintL (isTYPEorCONSTRAINT kind)
    
    2077 2028
               (text "Non-Type-like kind when Type-like expected:" <+> ppr kind $$
    
    2078 2029
                text "when checking" <+> doc)
    
    2079 2030
     
    
    2080 2031
     -----------------
    
    2081
    -lintArrow :: SDoc -> FunTyFlag -> InType -> InType -> InType -> LintM ()
    
    2032
    +lintArrow :: SDoc -> FunTyFlag -> Type -> Type -> Type -> LintM ()
    
    2082 2033
     -- If you edit this function, you may need to update the GHC formalism
    
    2083 2034
     -- See Note [GHC Formalism]
    
    2084 2035
     lintArrow what af t1 t2 tw  -- Eg lintArrow "type or kind `blah'" k1 k2 kw
    
    2085 2036
                                 -- or lintArrow "coercion `blah'" k1 k2 kw
    
    2086
    -  = do { k1 <- substTyM (typeKind t1)
    
    2087
    -       ; k2 <- substTyM (typeKind t2)
    
    2088
    -       ; kw <- substTyM (typeKind tw)
    
    2037
    +  = do { let k1 = typeKind t1
    
    2038
    +             k2 = typeKind t2
    
    2039
    +             kw = typeKind tw
    
    2089 2040
            ; unless (isTYPEorCONSTRAINT k1) (report (text "argument")     t1 k1)
    
    2090 2041
            ; unless (isTYPEorCONSTRAINT k2) (report (text "result")       t2 k2)
    
    2091 2042
            ; unless (isMultiplicityTy kw)   (report (text "multiplicity") tw kw)
    
    ... ... @@ -2111,34 +2062,34 @@ lintTyLit (StrTyLit _) = return ()
    2111 2062
     lintTyLit (CharTyLit _) = return ()
    
    2112 2063
     
    
    2113 2064
     -----------------
    
    2114
    -lint_ty_app :: InType -> OutKind -> [InType] -> LintM ()
    
    2065
    +lint_ty_app :: Type -> Kind -> [Type] -> LintM ()
    
    2115 2066
     lint_ty_app ty = lint_tyco_app (text "type" <+> quotes (ppr ty))
    
    2116 2067
     
    
    2117
    -lint_co_app :: HasDebugCallStack => Coercion -> OutKind -> [InType] -> LintM ()
    
    2068
    +lint_co_app :: HasDebugCallStack => Coercion -> Kind -> [Type] -> LintM ()
    
    2118 2069
     lint_co_app co = lint_tyco_app (text "coercion" <+> quotes (ppr co))
    
    2119 2070
     
    
    2120
    -lint_tyco_app :: SDoc -> OutKind -> [InType] -> LintM ()
    
    2071
    +lint_tyco_app :: SDoc -> Kind -> [Type] -> LintM ()
    
    2121 2072
     lint_tyco_app msg fun_kind arg_tys
    
    2122 2073
         -- 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 ()
    
    2074
    +  = do { _ <- lintApp msg (\ty     -> do { lintType ty; return ty })
    
    2075
    +                          (\ty _ _ -> do { lintType ty; return (typeKind ty,()) })
    
    2076
    +                          fun_kind arg_tys ()
    
    2126 2077
            ; return () }
    
    2127 2078
     
    
    2128 2079
     ----------------
    
    2129
    -lintApp :: forall in_a acc. Outputable in_a =>
    
    2080
    +lintApp :: forall a acc. Outputable a =>
    
    2130 2081
                  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
    
    2134
    -          -> [in_a]                               -- The arguments, always "In" things
    
    2135
    -          -> acc                                  -- Used (only) for UsageEnv in /term/ applications
    
    2136
    -          -> LintM (OutType,acc)
    
    2082
    +          -> (a -> LintM Type)                        -- Lint the thing and return its value
    
    2083
    +          -> (a -> Mult -> acc -> LintM (Kind, acc))  -- Lint the thing and return its type
    
    2084
    +          -> Type
    
    2085
    +          -> [a]                          -- The arguments
    
    2086
    +          -> acc                          -- Used (only) for UsageEnv in /term/ applications
    
    2087
    +          -> LintM (Type,acc)
    
    2137 2088
     -- lintApp is a performance-critical function, which deals with multiple
    
    2138 2089
     -- applications such as  (/\a./\b./\c. expr) @ta @tb @tc
    
    2139 2090
     -- When returning the type of this expression we want to avoid substituting a:=ta,
    
    2140 2091
     -- and /then/ substituting b:=tb, etc.  That's quadratic, and can be a huge
    
    2141
    --- perf hole.  So we gather all the arguments [in_a], and then gather the
    
    2092
    +-- perf hole.  So we gather all the arguments [a], and then gather the
    
    2142 2093
     -- substitution incrementally in the `go` loop.
    
    2143 2094
     --
    
    2144 2095
     -- lintApp is used:
    
    ... ... @@ -2158,7 +2109,7 @@ lintApp msg lint_forall_arg lint_arrow_arg !orig_fun_ty all_args acc
    2158 2109
     
    
    2159 2110
              ; let init_subst = mkEmptySubst in_scope
    
    2160 2111
     
    
    2161
    -               go :: Subst -> OutType -> acc -> [in_a] -> LintM (OutType, acc)
    
    2112
    +               go :: Subst -> Type -> acc -> [a] -> LintM (Type, acc)
    
    2162 2113
                          -- The Subst applies (only) to the fun_ty
    
    2163 2114
                          -- c.f. GHC.Core.Type.piResultTys, which has a similar loop
    
    2164 2115
     
    
    ... ... @@ -2202,7 +2153,7 @@ lintApp msg lint_forall_arg lint_arrow_arg !orig_fun_ty all_args acc
    2202 2153
     -- explicitly and don't capture them as free variables. Otherwise this binder might
    
    2203 2154
     -- become a thunk that get's allocated in the hot code path.
    
    2204 2155
     -- See Note [Avoiding compiler perf traps when constructing error messages.]
    
    2205
    -lint_app_fail_msg :: (Outputable a2) => SDoc -> OutType -> a2 -> SDoc -> SDoc
    
    2156
    +lint_app_fail_msg :: (Outputable a2) => SDoc -> Type -> a2 -> SDoc -> SDoc
    
    2206 2157
     lint_app_fail_msg msg kfn arg_tys extra
    
    2207 2158
       = vcat [ hang (text "Application error in") 2 msg
    
    2208 2159
              , nest 2 (text "Function type =" <+> ppr kfn)
    
    ... ... @@ -2215,7 +2166,7 @@ lint_app_fail_msg msg kfn arg_tys extra
    2215 2166
     *                                                                      *
    
    2216 2167
     ********************************************************************* -}
    
    2217 2168
     
    
    2218
    -lintCoreRule :: OutVar -> OutType -> CoreRule -> LintM ()
    
    2169
    +lintCoreRule :: OutVar -> Type -> CoreRule -> LintM ()
    
    2219 2170
     lintCoreRule _ _ (BuiltinRule {})
    
    2220 2171
       = return ()  -- Don't bother
    
    2221 2172
     
    
    ... ... @@ -2223,7 +2174,7 @@ lintCoreRule fun fun_ty rule@(Rule { ru_name = name, ru_bndrs = bndrs
    2223 2174
                                        , ru_args = args, ru_rhs = rhs })
    
    2224 2175
       = noMultiplicityChecks $ -- Skip linearity checking for rules
    
    2225 2176
                                -- See Note [Linting linearity]
    
    2226
    -    lintBinders LambdaBind bndrs $ \ _ ->
    
    2177
    +    lintBinders LambdaBind bndrs $
    
    2227 2178
         do { (lhs_ty, _) <- lintCoreArgs (fun_ty, zeroUE) args
    
    2228 2179
            ; (rhs_ty, _) <- case idJoinPointHood fun of
    
    2229 2180
                          JoinPoint join_arity
    
    ... ... @@ -2311,10 +2262,10 @@ Note [Join points and unfoldings/rules] in "GHC.Core.Opt.OccurAnal" for further
    2311 2262
     
    
    2312 2263
     {- Note [Asymptotic efficiency]
    
    2313 2264
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    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
    
    2265
    +When linting coercions we traverse the coercion. Then we often have to take the
    
    2266
    +coercionKind of that returned coercion. If we get long chains, that can be
    
    2267
    +asymptotically inefficient, notably in
    
    2268
    +
    
    2318 2269
     * TransCo
    
    2319 2270
     * InstCo
    
    2320 2271
     * SelCo (cf #9233)
    
    ... ... @@ -2326,30 +2277,23 @@ the bad perf bites us in practice.
    2326 2277
     A solution would be to return the kind and role of the coercion,
    
    2327 2278
     as well as the linted coercion.  Or perhaps even *only* the kind and role,
    
    2328 2279
     which is what used to happen.   But that proved tricky and error prone
    
    2329
    -(#17923), so now we return the coercion.
    
    2280
    +(#17923).
    
    2330 2281
     -}
    
    2331 2282
     
    
    2332 2283
     
    
    2333 2284
     -- lintStarCoercion lints a coercion, confirming that its lh kind and
    
    2334 2285
     -- its rh kind are both *; also ensures that the role is Nominal
    
    2335 2286
     -- Returns the lh kind
    
    2336
    -lintStarCoercion :: InCoercion -> LintM OutType
    
    2287
    +lintStarCoercion :: Coercion -> LintM Type
    
    2337 2288
     lintStarCoercion g
    
    2338 2289
       = do { lintCoercion g
    
    2339
    -       ; Pair t1 t2 <- substCoKindM g
    
    2290
    +       ; let Pair t1 t2 = coercionKind g
    
    2340 2291
            ; checkValueType (typeKind t1) (text "the kind of the left type in" <+> ppr g)
    
    2341 2292
            ; checkValueType (typeKind t2) (text "the kind of the right type in" <+> ppr g)
    
    2342 2293
            ; lintRole g Nominal (coercionRole g)
    
    2343 2294
            ; return t1 }
    
    2344 2295
     
    
    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 ()
    
    2296
    +lintCoercion :: HasDebugCallStack => Coercion -> LintM ()
    
    2353 2297
     -- See Note [Linting types and coercions]
    
    2354 2298
     --
    
    2355 2299
     -- If you edit this function, you may need to update the GHC formalism
    
    ... ... @@ -2361,7 +2305,7 @@ lintCoercion (CoVarCo cv)
    2361 2305
                       2 (text "With offending type:" <+> ppr (varType cv)))
    
    2362 2306
     
    
    2363 2307
       | otherwise  -- C.f. lintType (TyVarTy tv), which has better docs
    
    2364
    -  = do { _ <- lintVarOcc cv; return () }
    
    2308
    +  = lintVarOcc cv
    
    2365 2309
     
    
    2366 2310
     lintCoercion (Refl ty)          = lintType ty
    
    2367 2311
     lintCoercion (GRefl _r ty MRefl) = lintType ty
    
    ... ... @@ -2369,8 +2313,8 @@ lintCoercion (GRefl _r ty MRefl) = lintType ty
    2369 2313
     lintCoercion (GRefl _r ty (MCo co))
    
    2370 2314
       = do { lintType ty
    
    2371 2315
            ; lintCoercion co
    
    2372
    -       ; tk <- substTyM (typeKind ty)
    
    2373
    -       ; tl <- substTyM (coercionLKind co)
    
    2316
    +       ; let tk = typeKind ty
    
    2317
    +             tl = coercionLKind co
    
    2374 2318
            ; ensureEqTys tk tl $
    
    2375 2319
              hang (text "GRefl coercion kind mis-match:" <+> ppr co)
    
    2376 2320
                 2 (vcat [ppr ty, ppr tk, ppr tl])
    
    ... ... @@ -2403,8 +2347,8 @@ lintCoercion co@(AppCo co1 co2)
    2403 2347
       = do { lintCoercion co1
    
    2404 2348
            ; lintCoercion co2
    
    2405 2349
            ; let !(Pair lt1 rt1) = coercionKind co1
    
    2406
    -       ; lk1 <- substTyM (typeKind lt1)
    
    2407
    -       ; rk1 <- substTyM (typeKind rt1)
    
    2350
    +             lk1 = typeKind lt1
    
    2351
    +             rk1 = typeKind rt1
    
    2408 2352
            ; lint_co_app co lk1 [coercionLKind co2]
    
    2409 2353
            ; lint_co_app co rk1 [coercionRKind co2]
    
    2410 2354
     
    
    ... ... @@ -2421,7 +2365,7 @@ lintCoercion co@(ForAllCo {})
    2421 2365
       = do { _ <- go [] co; return () }
    
    2422 2366
       where
    
    2423 2367
         go :: [OutTyCoVar]   -- Binders in reverse order
    
    2424
    -       -> InCoercion -> LintM Role
    
    2368
    +       -> Coercion -> LintM Role
    
    2425 2369
         go tcvs co@(ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
    
    2426 2370
                              , fco_kind = kind_mco, fco_body = body_co })
    
    2427 2371
           | not (isTyCoVar tcv)
    
    ... ... @@ -2431,15 +2375,15 @@ lintCoercion co@(ForAllCo {})
    2431 2375
           = do { mb_lk <- case kind_mco of
    
    2432 2376
                          MRefl -> return Nothing
    
    2433 2377
                          MCo kind_co -> Just <$> lintStarCoercion kind_co
    
    2434
    -           ; lintTyCoBndr tcv $ \tcv' ->
    
    2378
    +           ; lintTyCoBndr tcv $
    
    2435 2379
             do { case mb_lk of
    
    2436 2380
                     Nothing -> return ()
    
    2437
    -                Just lk -> ensureEqTys (varType tcv') lk $
    
    2381
    +                Just lk -> ensureEqTys (varType tcv) lk $
    
    2438 2382
                                text "Kind mis-match in ForallCo" <+> ppr co
    
    2439 2383
     
    
    2440 2384
                -- I'm not very sure about this part, because it traverses body_co
    
    2441 2385
                -- 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
    
    2386
    +           -- Also it works on InTyCoVar and Coercion, which is suspect
    
    2443 2387
                ; when (isCoVar tcv) $
    
    2444 2388
                  do { lintL (visL == coreTyLamForAllTyFlag && visR == coreTyLamForAllTyFlag) $
    
    2445 2389
                       text "Invalid visibility flags in CoVar ForAllCo" <+> ppr co
    
    ... ... @@ -2448,7 +2392,7 @@ lintCoercion co@(ForAllCo {})
    2448 2392
                       text "Covar can only appear in Refl and GRefl: " <+> ppr co }
    
    2449 2393
                       -- See (FC6) in Note [ForAllCo] in GHC.Core.TyCo.Rep
    
    2450 2394
     
    
    2451
    -           ; role <- go (tcv':tcvs) body_co
    
    2395
    +           ; role <- go (tcv:tcvs) body_co
    
    2452 2396
     
    
    2453 2397
                ; when (role == Nominal) $
    
    2454 2398
                  lintL (visL `eqForAllVis` visR) $
    
    ... ... @@ -2505,8 +2449,8 @@ lintCoercion co@(UnivCo { uco_role = r, uco_prov = prov
    2505 2449
            -- Check the to and from types
    
    2506 2450
            ; lintType ty1
    
    2507 2451
            ; lintType ty2
    
    2508
    -       ; tk1 <- substTyM (typeKind ty1)
    
    2509
    -       ; tk2 <- substTyM (typeKind ty2)
    
    2452
    +       ; let tk1 = typeKind ty1
    
    2453
    +             tk2 = typeKind ty2
    
    2510 2454
     
    
    2511 2455
            ; when (r /= Phantom && isTYPEorCONSTRAINT tk1 && isTYPEorCONSTRAINT tk2)
    
    2512 2456
                   (checkTypes ty1 ty2)
    
    ... ... @@ -2560,8 +2504,8 @@ lintCoercion (SymCo co) = lintCoercion co
    2560 2504
     lintCoercion co@(TransCo co1 co2)
    
    2561 2505
       = do { lintCoercion co1
    
    2562 2506
            ; lintCoercion co2
    
    2563
    -       ; rk1 <- substTyM (coercionRKind co1)
    
    2564
    -       ; lk2 <- substTyM (coercionLKind co2)
    
    2507
    +       ; let rk1 = coercionRKind co1
    
    2508
    +             lk2 = coercionLKind co2
    
    2565 2509
            ; ensureEqTys rk1 lk2
    
    2566 2510
                    (hang (text "Trans coercion mis-match:" <+> ppr co)
    
    2567 2511
                        2 (vcat [ppr (coercionKind co1), ppr (coercionKind co2)]))
    
    ... ... @@ -2569,7 +2513,7 @@ lintCoercion co@(TransCo co1 co2)
    2569 2513
     
    
    2570 2514
     lintCoercion the_co@(SelCo cs co)
    
    2571 2515
       = do { lintCoercion co
    
    2572
    -       ; Pair s t <- substCoKindM co
    
    2516
    +       ; let Pair s t = coercionKind co
    
    2573 2517
     
    
    2574 2518
            ; if -- forall (both TyVar and CoVar)
    
    2575 2519
                 | Just _ <- splitForAllTyCoVar_maybe s
    
    ... ... @@ -2604,7 +2548,7 @@ lintCoercion the_co@(SelCo cs co)
    2604 2548
     
    
    2605 2549
     lintCoercion the_co@(LRCo _lr co)
    
    2606 2550
       = do { lintCoercion co
    
    2607
    -       ; Pair s t <- substCoKindM co
    
    2551
    +       ; let Pair s t = coercionKind co
    
    2608 2552
            ; lintRole co Nominal (coercionRole co)
    
    2609 2553
            ; case (splitAppTy_maybe s, splitAppTy_maybe t) of
    
    2610 2554
                (Just {}, Just {}) -> return ()
    
    ... ... @@ -2618,14 +2562,12 @@ lintCoercion orig_co@(InstCo co arg)
    2618 2562
         go (InstCo co arg) args = do { lintCoercion arg; go co (arg:args) }
    
    2619 2563
         go co              args = do { lintCoercion co
    
    2620 2564
                                      ; let Pair lty rty = coercionKind co
    
    2621
    -                                 ; lty' <- substTyM lty
    
    2622
    -                                 ; rty' <- substTyM rty
    
    2623 2565
                                      ; in_scope <- getInScope
    
    2624 2566
                                      ; let subst = mkEmptySubst in_scope
    
    2625
    -                                 ; go_args (subst, lty') (subst,rty') args }
    
    2567
    +                                 ; go_args (subst, lty) (subst,rty) args }
    
    2626 2568
     
    
    2627 2569
         -------------
    
    2628
    -    go_args :: (Subst, OutType) -> (Subst,OutType) -> [InCoercion]
    
    2570
    +    go_args :: (Subst, Type) -> (Subst,Type) -> [Coercion]
    
    2629 2571
                -> LintM ()
    
    2630 2572
         go_args _ _ []
    
    2631 2573
           = return ()
    
    ... ... @@ -2634,11 +2576,11 @@ lintCoercion orig_co@(InstCo co arg)
    2634 2576
                ; go_args lty1 rty1 args }
    
    2635 2577
     
    
    2636 2578
         -------------
    
    2637
    -    go_arg :: (Subst, OutType) -> (Subst,OutType) -> InCoercion
    
    2638
    -           -> LintM ((Subst,OutType), (Subst,OutType))
    
    2579
    +    go_arg :: (Subst, Type) -> (Subst,Type) -> Coercion
    
    2580
    +           -> LintM ((Subst,Type), (Subst,Type))
    
    2639 2581
         go_arg (lsubst,lty) (rsubst,rty) arg
    
    2640 2582
           = do { lintRole arg Nominal (coercionRole arg)
    
    2641
    -           ; Pair arg_lty arg_rty <- substCoKindM arg
    
    2583
    +           ; let Pair arg_lty arg_rty = coercionKind arg
    
    2642 2584
     
    
    2643 2585
                ; case (splitForAllTyCoVar_maybe lty, splitForAllTyCoVar_maybe rty) of
    
    2644 2586
                   -- forall over tvar
    
    ... ... @@ -2662,11 +2604,11 @@ lintCoercion orig_co@(InstCo co arg)
    2662 2604
     lintCoercion this_co@(AxiomCo ax cos)
    
    2663 2605
       = do { mapM_ lintCoercion cos
    
    2664 2606
            ; lint_roles 0 (coAxiomRuleArgRoles ax) cos
    
    2665
    -       ; prs <- mapM substCoKindM cos
    
    2607
    +       ; let prs = map coercionKind cos
    
    2666 2608
            ; lint_ax ax prs }
    
    2667 2609
     
    
    2668 2610
       where
    
    2669
    -    lint_ax :: CoAxiomRule -> [Pair OutType] -> LintM ()
    
    2611
    +    lint_ax :: CoAxiomRule -> [Pair Type] -> LintM ()
    
    2670 2612
         lint_ax (BuiltInFamRew  bif) prs
    
    2671 2613
           = checkL (isJust (bifrw_proves bif prs))  bad_bif
    
    2672 2614
         lint_ax (BuiltInFamInj bif) prs
    
    ... ... @@ -2754,8 +2696,8 @@ lintBranch this_co fam_tc branch arg_kinds
    2754 2696
       = do { checkL (arg_kinds `equalLength` (ktvs ++ cvs)) $
    
    2755 2697
                     (bad_ax this_co (text "lengths"))
    
    2756 2698
     
    
    2757
    -       ; subst <- getSubst
    
    2758
    -       ; let empty_subst = zapSubst subst
    
    2699
    +       ; in_scope <- getInScope
    
    2700
    +       ; let empty_subst = mkEmptySubst in_scope
    
    2759 2701
            ; _ <- foldlM check_ki (empty_subst, empty_subst)
    
    2760 2702
                                   (zip (ktvs ++ cvs) arg_kinds)
    
    2761 2703
     
    
    ... ... @@ -2880,12 +2822,12 @@ lint_axiom ax@(CoAxiom { co_ax_tc = tc, co_ax_branches = branches
    2880 2822
     lint_branch :: TyCon -> CoAxBranch -> LintM ()
    
    2881 2823
     lint_branch ax_tc (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs
    
    2882 2824
                                   , cab_lhs = lhs_args, cab_rhs = rhs })
    
    2883
    -  = lintBinders LambdaBind (tvs ++ cvs) $ \_ ->
    
    2825
    +  = lintBinders LambdaBind (tvs ++ cvs) $
    
    2884 2826
         do { let lhs = mkTyConApp ax_tc lhs_args
    
    2885 2827
            ; lintType lhs
    
    2886 2828
            ; lintType rhs
    
    2887
    -       ; lhs_kind <- substTyM (typeKind lhs)
    
    2888
    -       ; rhs_kind <- substTyM (typeKind rhs)
    
    2829
    +       ; let lhs_kind = typeKind lhs
    
    2830
    +             rhs_kind = typeKind rhs
    
    2889 2831
            ; lintL (not (lhs_kind `typesAreApart` rhs_kind)) $
    
    2890 2832
              hang (text "Inhomogeneous axiom")
    
    2891 2833
                 2 (text "lhs:" <+> ppr lhs <+> dcolon <+> ppr lhs_kind $$
    
    ... ... @@ -2969,35 +2911,26 @@ type LintLevel = Int
    2969 2911
     -- If you edit this type, you may need to update the GHC formalism
    
    2970 2912
     -- See Note [GHC Formalism]
    
    2971 2913
     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
    
    2914
    +  = LE { le_flags    :: LintFlags       -- Linting the result of this pass
    
    2915
    +       , le_loc      :: [LintLocInfo]   -- Locations
    
    2916
    +       , le_level    :: LintLevel
    
    2917
    +       , le_in_scope :: InScopeSet
    
    2918
    +
    
    2919
    +       , le_vars     :: VarEnv (Var, LintLevel)
    
    2920
    +                     -- Maps a Var (i.e. its unique) to its binding Var and level
    
    2921
    +                     -- /All/ in-scope variables are here (term variables,
    
    2922
    +                     --    type variables, and coercion variables)
    
    2923
    +                     -- So the domain is the same as the le_in_scope in-scope set
    
    2924
    +                     -- Used at an occurrence of the Var
    
    2990 2925
     
    
    2991 2926
            , le_joins :: UniqMap Id JoinOcc
    
    2992 2927
                -- ^ Join points in scope that are valid
    
    2993
    -           -- A subset of the InScopeSet in le_subst
    
    2994 2928
                -- See Note [Join points]
    
    2995 2929
     
    
    2996 2930
            , le_ue_aliases :: NameEnv UsageEnv
    
    2997 2931
                  -- See Note [Linting linearity]
    
    2998 2932
                  -- Assigns usage environments to the alias-like binders,
    
    2999 2933
                  -- as found in non-recursive lets.
    
    3000
    -             -- Domain is OutIds
    
    3001 2934
     
    
    3002 2935
            , le_platform   :: Platform         -- ^ Target platform
    
    3003 2936
            , le_diagOpts   :: DiagOpts         -- ^ Target platform
    
    ... ... @@ -3011,7 +2944,8 @@ data LintFlags
    3011 2944
            , lf_check_linearity :: Bool    -- ^ See Note [Linting linearity]
    
    3012 2945
            , lf_check_fixed_rep :: Bool    -- ^ See Note [Checking for representation polymorphism]
    
    3013 2946
            , 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]
    
    2947
    +       , lf_allow_weak_joins :: Bool   -- ^ See Note [Linting join points with casts or ticks]
    
    2948
    +       , lf_allow_beta_joins :: Bool   -- ^ See Note [Join points and beta-redexes]
    
    3015 2949
         }
    
    3016 2950
     
    
    3017 2951
     -- See Note [Checking StaticPtrs]
    
    ... ... @@ -3078,20 +3012,6 @@ top-level bindings. See SimplCore Note [Grand plan for static forms].
    3078 3012
     
    
    3079 3013
     The linter checks that no occurrence or `makeStatic` occurs nested.
    
    3080 3014
     
    
    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 3015
     Note [Linting type synonym applications]
    
    3096 3016
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3097 3017
     When linting a type-synonym, or type-family, application
    
    ... ... @@ -3353,12 +3273,12 @@ initL cfg m
    3353 3273
       where
    
    3354 3274
         vars = l_vars cfg
    
    3355 3275
         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     = []
    
    3276
    +    env = LE { le_flags    = l_flags cfg
    
    3277
    +             , le_level    = init_level
    
    3278
    +             , le_vars     = mkVarEnv [ (v,(v, init_level)) | v <- vars ]
    
    3279
    +             , le_in_scope = mkInScopeSetList vars
    
    3280
    +             , le_joins    = emptyUniqMap
    
    3281
    +             , le_loc      = []
    
    3362 3282
                  , le_ue_aliases = emptyNameEnv
    
    3363 3283
                  , le_platform = l_platform cfg
    
    3364 3284
                  , le_diagOpts = l_diagOpts cfg
    
    ... ... @@ -3421,8 +3341,7 @@ addMsg show_context env msgs msg
    3421 3341
        loc_msgs :: [(SrcLoc, SDoc)]  -- Innermost first
    
    3422 3342
        loc_msgs = map dumpLoc (le_loc env)
    
    3423 3343
     
    
    3424
    -   cxt_doc = vcat [ vcat $ reverse $ map snd loc_msgs
    
    3425
    -                  , text "Substitution:" <+> ppr (le_subst env) ]
    
    3344
    +   cxt_doc = vcat $ reverse $ map snd loc_msgs
    
    3426 3345
     
    
    3427 3346
        context | show_context  = cxt_doc
    
    3428 3347
                | otherwise     = whenPprDebug cxt_doc
    
    ... ... @@ -3449,72 +3368,44 @@ inCasePat = LintM $ \ env errs -> fromBoxedLResult (Just (is_case_pat env), errs
    3449 3368
         is_case_pat (LE { le_loc = CasePat {} : _ }) = True
    
    3450 3369
         is_case_pat _other                           = False
    
    3451 3370
     
    
    3452
    -addInScopeId :: InId -> OutType -> (OutId -> LintM a) -> LintM a
    
    3371
    +addInScopeId :: Id -> LintM a -> LintM a
    
    3453 3372
     -- Unlike addInScopeTyCoVar, this function does no cloning; Ids never get cloned
    
    3454
    -addInScopeId in_id out_ty thing_inside
    
    3373
    +addInScopeId id thing_inside
    
    3455 3374
       = LintM $ \ env errs ->
    
    3456
    -    let !(out_id, env') = add env
    
    3457
    -    in unLintM (thing_inside out_id) env' errs
    
    3458
    -
    
    3375
    +    unLintM thing_inside (add env) errs
    
    3459 3376
       where
    
    3460
    -    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)
    
    3377
    +    add env@(LE { le_level = level, le_vars = id_vars, le_joins = valid_joins
    
    3378
    +                , le_ue_aliases = aliases, le_in_scope = in_scope })
    
    3379
    +      = env { le_level = level1, le_vars = in_vars'
    
    3380
    +            , le_in_scope = in_scope `extendInScopeSet` id
    
    3381
    +            , le_joins = valid_joins', le_ue_aliases = aliases' }
    
    3463 3382
           where
    
    3464 3383
             level1 = level + 1
    
    3465
    -        env1 = env { le_level = level1, le_in_vars = in_vars'
    
    3466
    -                   , le_joins = valid_joins', le_ue_aliases = aliases' }
    
    3467 3384
     
    
    3468
    -        in_vars' = extendVarEnv id_vars in_id (in_id, out_ty, level1)
    
    3469
    -        aliases' = delFromNameEnv aliases (idName in_id)
    
    3385
    +        in_vars' = extendVarEnv id_vars id (id, level1)
    
    3386
    +        aliases' = delFromNameEnv aliases (idName id)
    
    3470 3387
                -- aliases': when shadowing an alias, we need to make sure the
    
    3471 3388
                -- Id is no longer classified as such. E.g.
    
    3472 3389
                --   let x = <e1> in case x of x { _DEFAULT -> <e2> }
    
    3473 3390
                -- Occurrences of 'x' in e2 shouldn't count as occurrences of e1.
    
    3474 3391
     
    
    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 3392
             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
    
    3393
    +          | isJoinId id = addToUniqMap   valid_joins id NormalJoinOcc -- Overwrite with new arity
    
    3394
    +          | otherwise   = delFromUniqMap valid_joins id -- Remove any existing binding
    
    3483 3395
     
    
    3484
    -addInScopeTyCoVar :: InTyCoVar -> OutType -> (OutTyCoVar -> LintM a) -> LintM a
    
    3396
    +addInScopeTyCoVar :: TyCoVar -> LintM a -> LintM a
    
    3485 3397
     -- 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
    
    3398
    +addInScopeTyCoVar tcv thing_inside
    
    3399
    +  = LintM $ \ env@(LE { le_level = level, le_vars = in_vars
    
    3400
    +                      , le_in_scope = in_scope }) errs ->
    
    3401
    +    let level' = level + 1
    
    3490 3402
             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
    
    3510
    -
    
    3511
    -getInVarEnv :: LintM (VarEnv (InId, OutType, LintLevel))
    
    3512
    -getInVarEnv = LintM (\env errs -> fromBoxedLResult (Just (le_in_vars env), errs))
    
    3403
    +                   , le_in_scope = in_scope `extendInScopeSet` tcv
    
    3404
    +                   , le_vars = extendVarEnv in_vars tcv (tcv, level') }
    
    3405
    +    in unLintM thing_inside env' errs
    
    3513 3406
     
    
    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
    
    3407
    +getInVarEnv :: LintM (VarEnv (Id, LintLevel))
    
    3408
    +getInVarEnv = LintM (\env errs -> fromBoxedLResult (Just (le_vars env), errs))
    
    3518 3409
     
    
    3519 3410
     markAllJoinsBad :: LintM a -> LintM a
    
    3520 3411
     markAllJoinsBad m
    
    ... ... @@ -3549,54 +3440,42 @@ markAllJoinsBadIf False m = m
    3549 3440
     getValidJoins :: LintM (UniqMap Id JoinOcc)
    
    3550 3441
     getValidJoins = LintM (\ env errs -> fromBoxedLResult (Just (le_joins env), errs))
    
    3551 3442
     
    
    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 3443
     getUEAliases :: LintM (NameEnv UsageEnv)
    
    3563 3444
     getUEAliases = LintM (\ env errs -> fromBoxedLResult (Just (le_ue_aliases env), errs))
    
    3564 3445
     
    
    3565 3446
     getInScope :: LintM InScopeSet
    
    3566
    -getInScope = LintM (\ env errs -> fromBoxedLResult (Just (substInScopeSet $ le_subst env), errs))
    
    3447
    +getInScope = LintM (\ env errs -> fromBoxedLResult (Just (le_in_scope env), errs))
    
    3567 3448
     
    
    3568
    -lintVarOcc :: InVar -> LintM OutType
    
    3449
    +lintVarOcc :: Var -> LintM ()
    
    3569 3450
     -- Used at an occurrence of a variable: term variables, type variables, and coercion variables
    
    3570 3451
     -- Checks
    
    3571 3452
     --   - that it is in scope
    
    3572 3453
     --   - that it is not a GlobalId bound by a LocalId
    
    3573
    ---   - that the InType at the ocurrence matches the InType at the binding site
    
    3454
    +--   - that the Type at the ocurrence matches the Type at the binding site
    
    3574 3455
     --   - that the variables free in its type are not shadowed at the occurrence site
    
    3575 3456
     lintVarOcc v_occ
    
    3576 3457
       | isGlobalId v_occ
    
    3577
    -  = return (idType v_occ)
    
    3458
    +  = return ()
    
    3578 3459
       | otherwise
    
    3579 3460
       = do { in_var_env <- getInVarEnv
    
    3580 3461
            ; case lookupVarEnv in_var_env v_occ of
    
    3581 3462
                Nothing -> failWithL (text pp_what <+> quotes (ppr v_occ)
    
    3582 3463
                                      <+> text "is out of scope")
    
    3583
    -           Just (v_bndr, out_ty, bind_level)
    
    3464
    +           Just (v_bndr, bind_level)
    
    3584 3465
                  -> do { let bndr_ty = idType v_bndr
    
    3585 3466
                        ; check_bad_global v_bndr
    
    3586 3467
                        ; check_occ_type_match bndr_ty
    
    3587
    -                   ; check_occ_type_scope in_var_env bndr_ty bind_level
    
    3588
    -                   ; return out_ty }
    
    3589
    -
    
    3468
    +                   ; check_occ_type_scope in_var_env bndr_ty bind_level }
    
    3590 3469
         }
    
    3591 3470
       where
    
    3592
    -    occ_ty :: InType
    
    3471
    +    occ_ty :: Type
    
    3593 3472
         occ_ty = idType v_occ
    
    3594 3473
     
    
    3595 3474
         pp_what | isTyVar v_occ = "The type variable"
    
    3596 3475
                 | isCoVar v_occ = "The coercion variable"
    
    3597 3476
                 | otherwise     = "The value variable"
    
    3598 3477
     
    
    3599
    -    check_bad_global :: InVar -> LintM ()
    
    3478
    +    check_bad_global :: Var -> LintM ()
    
    3600 3479
         -- 'check_bad_global' checks for the case where an /occurrence/ is
    
    3601 3480
         -- a GlobalId, but there is an enclosing binding for a LocalId.
    
    3602 3481
         -- NB: the in-scope variables are mostly LocalIds, checked by lintIdBndr,
    
    ... ... @@ -3616,26 +3495,26 @@ lintVarOcc v_occ
    3616 3495
           | otherwise
    
    3617 3496
           = return ()
    
    3618 3497
     
    
    3619
    -    check_occ_type_match :: InType -> LintM ()
    
    3498
    +    check_occ_type_match :: Type -> LintM ()
    
    3620 3499
         -- Check that the type in /binder/ and the type in the /occurrence/ are the same
    
    3621 3500
         check_occ_type_match bndr_ty
    
    3622
    -      = ensureEqTys bndr_ty occ_ty $  -- Compares InTypes
    
    3501
    +      = ensureEqTys bndr_ty occ_ty $  -- Compares Types
    
    3623 3502
             mkBndrOccTypeMismatchMsg v_occ bndr_ty occ_ty
    
    3624 3503
     
    
    3625
    -    check_occ_type_scope :: VarEnv (InVar,OutType,LintLevel) -> InType -> LintLevel -> LintM ()
    
    3504
    +    check_occ_type_scope :: VarEnv (Var,LintLevel) -> Type -> LintLevel -> LintM ()
    
    3626 3505
         -- Check that the free vars of the binder's type
    
    3627 3506
         -- are not shadowed at the occurrence site
    
    3628 3507
         check_occ_type_scope in_var_env bndr_ty bind_level
    
    3629 3508
           = checkL (null bad_fvs) $
    
    3630 3509
             mkBndrOccFreeVarMsg v_occ occ_ty bad_fvs
    
    3631 3510
           where
    
    3632
    -        bad_fvs :: [InVar]
    
    3511
    +        bad_fvs :: [Var]
    
    3633 3512
             bad_fvs = filter is_bad (tyCoVarsOfTypeList bndr_ty)
    
    3634 3513
     
    
    3635
    -        is_bad :: InVar -> Bool
    
    3514
    +        is_bad :: Var -> Bool
    
    3636 3515
             -- True of a variable bound inside bind_level
    
    3637 3516
             is_bad v = case lookupVarEnv in_var_env v of
    
    3638
    -                      Just (_, _, v_level) -> v_level > bind_level
    
    3517
    +                      Just (_, v_level) -> v_level > bind_level
    
    3639 3518
                           Nothing -> True
    
    3640 3519
     
    
    3641 3520
     lookupJoinId :: Id -> LintM (Maybe (JoinArity, JoinOcc))
    
    ... ... @@ -3647,21 +3526,21 @@ lookupJoinId id
    3647 3526
                 Just join_occ -> return $ Just (idJoinArity id, join_occ)
    
    3648 3527
                 Nothing       -> return Nothing }
    
    3649 3528
     
    
    3650
    -addAliasUE :: OutId -> UsageEnv -> LintM a -> LintM a
    
    3529
    +addAliasUE :: Id -> UsageEnv -> LintM a -> LintM a
    
    3651 3530
     addAliasUE id ue thing_inside = LintM $ \ env errs ->
    
    3652 3531
       let new_ue_aliases =
    
    3653 3532
             extendNameEnv (le_ue_aliases env) (getName id) ue
    
    3654 3533
       in
    
    3655 3534
         unLintM thing_inside (env { le_ue_aliases = new_ue_aliases }) errs
    
    3656 3535
     
    
    3657
    -varCallSiteUsage :: OutId -> LintM UsageEnv
    
    3536
    +varCallSiteUsage :: Id -> LintM UsageEnv
    
    3658 3537
     varCallSiteUsage id =
    
    3659 3538
       do m <- getUEAliases
    
    3660 3539
          return $ case lookupNameEnv m (getName id) of
    
    3661 3540
              Nothing    -> singleUsageUE id
    
    3662 3541
              Just id_ue -> id_ue
    
    3663 3542
     
    
    3664
    -ensureEqTys :: OutType -> OutType -> SDoc -> LintM ()
    
    3543
    +ensureEqTys :: Type -> Type -> SDoc -> LintM ()
    
    3665 3544
     -- check ty2 is subtype of ty1 (ie, has same structure but usage
    
    3666 3545
     -- annotations need only be consistent, not equal)
    
    3667 3546
     -- Assumes ty1,ty2 are have already had the substitution applied
    
    ... ... @@ -3885,7 +3764,7 @@ mkLetErr bndr rhs
    3885 3764
               hang (text "Rhs:")
    
    3886 3765
                      4 (ppr rhs)]
    
    3887 3766
     
    
    3888
    -mkTyAppMsg :: OutType -> Type -> SDoc
    
    3767
    +mkTyAppMsg :: Type -> Type -> SDoc
    
    3889 3768
     mkTyAppMsg ty arg_ty
    
    3890 3769
       = vcat [text "Illegal type application:",
    
    3891 3770
                   hang (text "Function type:")
    
    ... ... @@ -4006,13 +3885,13 @@ mkJoinBndrOccMismatchMsg bndr join_arity_bndr join_arity_occ
    4006 3885
              , text "Arity at binding site:" <+> ppr join_arity_bndr
    
    4007 3886
              , text "Arity at occurrence:  " <+> ppr join_arity_occ ]
    
    4008 3887
     
    
    4009
    -mkBndrOccTypeMismatchMsg :: InVar -> InType -> InType -> SDoc
    
    3888
    +mkBndrOccTypeMismatchMsg :: Var -> Type -> Type -> SDoc
    
    4010 3889
     mkBndrOccTypeMismatchMsg var bndr_ty occ_ty
    
    4011 3890
       = vcat [ text "Mismatch in type between binder and occurrence"
    
    4012 3891
              , text "Binder:    " <+> ppr var <+> dcolon <+> ppr bndr_ty
    
    4013 3892
              , text "Occurrence:" <+> ppr var <+> dcolon <+> ppr occ_ty ]
    
    4014 3893
     
    
    4015
    -mkBndrOccFreeVarMsg :: InVar -> InType -> [TyCoVar] -> SDoc
    
    3894
    +mkBndrOccFreeVarMsg :: Var -> Type -> [TyCoVar] -> SDoc
    
    4016 3895
     mkBndrOccFreeVarMsg var occ_ty bad_tvs
    
    4017 3896
       = vcat [ text "Free vars of type are shadowed:" <+> ppr bad_tvs
    
    4018 3897
              , text "Occurrence:"  <+> ppr var <+> dcolon <+> ppr occ_ty ]
    

  • compiler/GHC/Core/Lint/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.Lint.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 does this:
    
    49
    +  - It runs as part of Lint, as a pre-pass before the main Lint
    
    50
    +  - It runs only when we are Linting the output of the desugarer
    
    51
    +  - The result of substTypeLets is discarded after linting
    
    52
    +
    
    53
    +When it finds a nested type-let
    
    54
    +    let @a = ty in body
    
    55
    +it substitutes a:=ty in `body`
    
    56
    +
    
    57
    +Wrinkles
    
    58
    +
    
    59
    +(STL1) It only substitutes /nested/ type-lets, not top level.
    
    60
    +
    
    61
    +(STL2) You might think that we'd run it unconditionally, after desugaring.  But actually,
    
    62
    +  the Simplifier (or SimpleOpt) will deal with these type-lets, so it is just Lint
    
    63
    +  that we must placate.  We don't want to incur the cost of this pass except when
    
    64
    +  we are Linting.
    
    65
    +
    
    66
    +  TL;DR: we do substTypeLets as a pre-pass to the Lint pass that immediately follows
    
    67
    +  desugaring. See `GHC.Core.lintPassResult`, and the `lpr_preSubst` field in
    
    68
    +  `LintPassResultConfig`.
    
    69
    +
    
    70
    +(STL3) Should `substTypeLets` process (stable) unfoldings? It does not need to
    
    71
    +  because all unfoldings have `simpleOptExpr` applied to them, so the tricky
    
    72
    +  type-lets will already be substituted.
    
    73
    +
    
    74
    +  Of course we stil need to apply the current substitution, but that is done
    
    75
    +  automatically by `substBndr`.
    
    76
    +-}
    
    77
    +
    
    78
    +substTypeLets :: CoreProgram -> CoreProgram
    
    79
    +substTypeLets binds = map stl_top binds
    
    80
    +  where
    
    81
    +     stl_top (NonRec b r) = NonRec b (stlExpr empty_subst r)
    
    82
    +     stl_top (Rec prs)    = Rec (mapSnd (stlExpr empty_subst) prs)
    
    83
    +
    
    84
    +     empty_subst = mkEmptySubst $
    
    85
    +                   mkInScopeSetBndrs binds
    
    86
    +
    
    87
    +----------------------
    
    88
    +stlBind :: Subst -> CoreBind -> (Subst, CoreBind)
    
    89
    +stlBind subst (Rec prs)
    
    90
    +  = assertPpr (not (any isTyVar bndrs)) (ppr prs) $
    
    91
    +    (subst', Rec prs')
    
    92
    +  where
    
    93
    +    (bndrs,rhss) = unzip prs
    
    94
    +    (subst', bndrs') = substRecBndrs subst bndrs
    
    95
    +       -- substRecBndrs: see (STL3) in Note [Substituting type-lets]
    
    96
    +    rhss' = map (stlExpr subst') rhss
    
    97
    +    prs'  = bndrs' `zip` rhss'
    
    98
    +
    
    99
    +stlBind subst (NonRec bndr rhs)
    
    100
    +  = (subst', NonRec bndr' (stlExpr subst rhs))
    
    101
    +  where
    
    102
    +    (subst', bndr')  = substBndr subst bndr
    
    103
    +      -- substBndr: see (STL3) in Note [Substituting type-lets]
    
    104
    +
    
    105
    +----------------------
    
    106
    +stlExpr :: Subst -> CoreExpr -> CoreExpr
    
    107
    +
    
    108
    +stlExpr subst (Let (NonRec tv (Type ty)) body)
    
    109
    +  = -- This equation is the main payload of the entire pass!
    
    110
    +    stlExpr (extendTvSubst subst tv (substTy subst ty)) body
    
    111
    +
    
    112
    +stlExpr subst (Let bind body)
    
    113
    +  = Let bind' (stlExpr subst' body)
    
    114
    +  where
    
    115
    +    (subst', bind') = stlBind subst bind
    
    116
    +
    
    117
    +stlExpr subst (Lam bndr body)
    
    118
    +  = Lam bndr' (stlExpr subst' body)
    
    119
    +  where
    
    120
    +    (subst', bndr') = substBndr subst bndr
    
    121
    +
    
    122
    +stlExpr subst (Case scrut bndr ty alts)
    
    123
    +  = Case (stlExpr subst scrut) bndr' (substTy subst ty)
    
    124
    +         (map stl_alt alts)
    
    125
    +  where
    
    126
    +    (subst', bndr') = substBndr subst bndr
    
    127
    +
    
    128
    +    stl_alt (Alt con bndrs rhs)
    
    129
    +       = Alt con bndrs' (stlExpr subst'' rhs)
    
    130
    +       where
    
    131
    +         (subst'', bndrs') = substBndrs subst' bndrs
    
    132
    +
    
    133
    +-- Simple cases
    
    134
    +stlExpr _     (Lit l)       = Lit l
    
    135
    +stlExpr subst (Var v)       = lookupIdSubst subst v
    
    136
    +stlExpr subst (App e1 e2)   = App (stlExpr subst e1) (stlExpr subst e2)
    
    137
    +stlExpr subst (Type ty)     = Type (substTy subst ty)
    
    138
    +stlExpr subst (Tick t e)    = Tick (substTickish subst t) (stlExpr subst e)
    
    139
    +stlExpr subst (Cast e co)   = Cast (stlExpr subst e) (substCo subst co)
    
    140
    +stlExpr subst (Coercion co) = Coercion (substCo subst co)

  • 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,20 +2812,27 @@ 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.
    
    2818
    +    !(WUD fun_uds fun')  = go_fun env fun args
    
    2819
    +
    
    2820
    +    -- See (A2) in 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' = addAppCtxt env args
    
    2831
    +            !(WUD fun_uds fun') = occAnal env' fun
    
    2832
    +        in WUD (markAllNonTail fun_uds) fun'
    
    2824 2833
     
    
    2825 2834
     addAppCtxt :: OccEnv -> [Arg CoreBndr] -> OccEnv
    
    2835
    +-- See (A3) in Note [occAnal for applications]
    
    2826 2836
     addAppCtxt env@(OccEnv { occ_one_shots = ctxt }) args
    
    2827 2837
       | n_val_args > 0
    
    2828 2838
       = env { occ_one_shots = replicate n_val_args OneShotLam ++ ctxt
    
    ... ... @@ -2834,8 +2844,40 @@ addAppCtxt env@(OccEnv { occ_one_shots = ctxt }) args
    2834 2844
       where
    
    2835 2845
         n_val_args = valArgCount args
    
    2836 2846
     
    
    2847
    +{- Note [occAnal for applications]
    
    2848
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2849
    +One iteration of the simplifier sometimes leaves behind beta redexes like
    
    2850
    +     (\x y -> e) a1 a2
    
    2851
    +This happens particularly in worker/wrapper; see Note [Join points and beta-redexes]
    
    2852
    +in GHC.Core.Lint.  In these cases there are three things we want to take care of
    
    2853
    +in the occurrence analyser:
    
    2854
    +
    
    2855
    +(A1) We don't want to mark variables inside `e` as `InsideLam`; that would just
    
    2856
    +  delay inlining them for another iteration of the Simplifier.
    
    2857
    +
    
    2858
    +(A2) If there is a join-point invocation inside `e`, we don't want to complain about
    
    2859
    +  lost join points.  See Note [Join points and beta-redexes] in GHC.Core.Lint for
    
    2860
    +  more detail.
    
    2861
    +
    
    2862
    +(A3) Suppose we have something like
    
    2863
    +     (case e of (a,b) -> (\x.blah) |> co) arg
    
    2864
    +  which can happen during 'gentle' simplification when we don't do case-of-case,
    
    2865
    +  not push arguments into cases.  Then we'd still like to mark that lambda
    
    2866
    +  as one-shot, so that things can get inlined inside it.  We can to this
    
    2867
    +  by pushing OneShotLam items onto the context stack.
    
    2868
    +
    
    2869
    +  Live example: `read_tup4` in test CoOpt_Read.
    
    2870
    +
    
    2871
    +How we address these:
    
    2872
    +
    
    2873
    +* (A2): we focus narrowly on visible beta-redexes ((\x.e) arg), since that
    
    2874
    +  is what is needed for Note [Join points and beta-redexes].  We do this
    
    2875
    +  via the `go_fun` loop in `occAnalApp`.
    
    2876
    +
    
    2877
    +* (A1) and (A3): for visible beta-redexes, the `go_fun` loop does the job.
    
    2878
    +  But for less-visible ones, like in (A3) we push `OneShotLam` items onto
    
    2879
    +  the context stack, in `addAppCtxt`.
    
    2837 2880
     
    
    2838
    -{-
    
    2839 2881
     Note [Sources of one-shot information]
    
    2840 2882
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2841 2883
     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/Driver/Config/Core/Lint.hs
    1 1
     module GHC.Driver.Config.Core.Lint
    
    2 2
       ( endPass
    
    3 3
       , endPassHscEnvIO
    
    4
    -  , lintCoreBindings
    
    5 4
       , initEndPassConfig
    
    6 5
       , initLintPassResultConfig
    
    7 6
       , initLintConfig
    
    ... ... @@ -50,16 +49,6 @@ endPassHscEnvIO hsc_env name_ppr_ctx pass binds rules
    50 49
                binds rules
    
    51 50
            }
    
    52 51
     
    
    53
    --- | Type-check a 'CoreProgram'. See Note [Core Lint guarantee].
    
    54
    -lintCoreBindings :: DynFlags -> CoreToDo -> [Var] -> CoreProgram -> WarnsAndErrs
    
    55
    -lintCoreBindings dflags coreToDo vars -- binds
    
    56
    -  = lintCoreBindings' $ LintConfig
    
    57
    -      { l_diagOpts = initDiagOpts dflags
    
    58
    -      , l_platform = targetPlatform dflags
    
    59
    -      , l_flags    = perPassFlags dflags coreToDo
    
    60
    -      , l_vars     = vars
    
    61
    -      }
    
    62
    -
    
    63 52
     initEndPassConfig :: DynFlags -> [Var] -> NamePprCtx -> CoreToDo -> EndPassConfig
    
    64 53
     initEndPassConfig dflags extra_vars name_ppr_ctx pass = EndPassConfig
    
    65 54
       { ep_dumpCoreSizes = not (gopt Opt_SuppressCoreSizes dflags)
    
    ... ... @@ -104,10 +93,17 @@ initLintPassResultConfig dflags extra_vars pass = LintPassResultConfig
    104 93
       { lpr_diagOpts      = initDiagOpts dflags
    
    105 94
       , lpr_platform      = targetPlatform dflags
    
    106 95
       , lpr_makeLintFlags = perPassFlags dflags pass
    
    107
    -  , lpr_passPpr = ppr pass
    
    96
    +  , lpr_passPpr       = ppr pass
    
    97
    +  , lpr_preSubst      = doPreSubst pass
    
    108 98
       , lpr_localsInScope = extra_vars
    
    109 99
       }
    
    110 100
     
    
    101
    +doPreSubst :: CoreToDo -> Bool
    
    102
    +doPreSubst CoreDesugar = True   -- Output of desugarer, /before/ running any optimisation,
    
    103
    +                                -- not even simpleOpt. See Note Note [Substituting type-lets]
    
    104
    +                                -- in GHC.Core.SubstTypeLets
    
    105
    +doPreSubst _           = False
    
    106
    +
    
    111 107
     perPassFlags :: DynFlags -> CoreToDo -> LintFlags
    
    112 108
     perPassFlags dflags pass
    
    113 109
       = (defaultLintFlags dflags)
    
    ... ... @@ -116,7 +112,8 @@ perPassFlags dflags pass
    116 112
                    , lf_check_static_ptrs          = check_static_ptrs
    
    117 113
                    , lf_check_linearity            = check_linearity
    
    118 114
                    , lf_check_rubbish_lits         = check_rubbish
    
    119
    -               , lf_allow_weak_joins           = allow_weak_joins }
    
    115
    +               , lf_allow_weak_joins           = allow_weak_joins
    
    116
    +               , lf_allow_beta_joins           = allow_beta_joins }
    
    120 117
       where
    
    121 118
         -- See Note [Checking for global Ids]
    
    122 119
         check_globals = case pass of
    
    ... ... @@ -158,6 +155,11 @@ perPassFlags dflags pass
    158 155
                           CorePrep -> True
    
    159 156
                           _        -> False
    
    160 157
     
    
    158
    +    -- See Note [Join points and beta-redexes] in GHC.Core.Lint
    
    159
    +    allow_beta_joins = case pass of
    
    160
    +                          CoreDoWorkerWrapper -> True
    
    161
    +                          _                   -> False
    
    162
    +
    
    161 163
     initLintConfig :: DynFlags -> [Var] -> LintConfig
    
    162 164
     initLintConfig dflags vars =LintConfig
    
    163 165
       { l_diagOpts = initDiagOpts dflags
    
    ... ... @@ -175,4 +177,5 @@ defaultLintFlags dflags = LF { lf_check_global_ids = False
    175 177
                                  , lf_check_fixed_rep = True
    
    176 178
                                  , lf_check_rubbish_lits = True
    
    177 179
                                  , lf_allow_weak_joins = False
    
    180
    +                             , lf_allow_beta_joins = False
    
    178 181
                                  }

  • compiler/GHC/Unit/State.hs
    ... ... @@ -802,7 +802,7 @@ readUnitDatabase logger cfg conf_file = do
    802 802
           if cache_exists
    
    803 803
             then do
    
    804 804
               debugTraceMsg logger 2 $ text "Using binary package database:" <+> ppr filename
    
    805
    -          readPackageDbForGhc (OsPath.unsafeDecodeUtf filename)
    
    805
    +          readPackageDbForGhc filename
    
    806 806
             else do
    
    807 807
               -- If there is no package.cache file, we check if the database is not
    
    808 808
               -- empty by inspecting if the directory contains any .conf file. If it
    

  • compiler/ghc.cabal.in
    ... ... @@ -361,6 +361,7 @@ Library
    361 361
             GHC.Core.InstEnv
    
    362 362
             GHC.Core.Lint
    
    363 363
             GHC.Core.Lint.Interactive
    
    364
    +        GHC.Core.Lint.SubstTypeLets
    
    364 365
             GHC.Core.LateCC
    
    365 366
             GHC.Core.LateCC.Types
    
    366 367
             GHC.Core.LateCC.TopLevelBinds
    

  • libraries/base/tests/perf/all.T
    ... ... @@ -5,15 +5,13 @@ setTestOpts(js_skip)
    5 5
     # Check optimization of `elem`
    
    6 6
     #--------------------------------------
    
    7 7
     
    
    8
    -elemCoreFilter = "sed -En '/^(is|fusion|noFusion)[A-Za-z]*($| )/,/^$/p'"
    
    9
    -
    
    10 8
     def elemCoreTest(test_name, module_name, opt):
    
    11 9
         test(test_name,
    
    12 10
              [only_ways(['normal']), extra_files([module_name + '.hs'])],
    
    13 11
              multimod_compile_filter,
    
    14 12
              [module_name,
    
    15 13
               f'{opt} -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds',
    
    16
    -          elemCoreFilter])
    
    14
    +          "sed -En '/^(is|fusion|noFusion)[A-Za-z]*($| )/,/^$/p'"])
    
    17 15
     
    
    18 16
     elemCoreTest('T17752_O1', 'T17752', '-O1')
    
    19 17
     elemCoreTest('T17752_O2', 'T17752', '-O2')
    

  • libraries/ghc-boot/GHC/Unit/Database.hs
    ... ... @@ -68,6 +68,8 @@ module GHC.Unit.Database
    68 68
        -- * Misc
    
    69 69
        , mkMungePathUrl
    
    70 70
        , mungeUnitInfoPaths
    
    71
    +   , writeFileAtomic
    
    72
    +   , unsafeDecodeUtf
    
    71 73
        )
    
    72 74
     where
    
    73 75
     
    
    ... ... @@ -86,18 +88,23 @@ import Data.Binary.Get as Bin
    86 88
     import Data.List (intersperse)
    
    87 89
     import Control.Exception as Exception
    
    88 90
     import Control.Monad (when)
    
    89
    -import System.FilePath as FilePath
    
    91
    +import qualified System.FilePath as FilePath
    
    90 92
     #if !defined(mingw32_HOST_OS)
    
    91 93
     import Data.Bits ((.|.))
    
    92
    -import System.Posix.Files
    
    94
    +import System.Posix.Files.PosixString
    
    93 95
     import System.Posix.Types (FileMode)
    
    96
    +import System.OsString.Internal.Types (getOsString)
    
    94 97
     #endif
    
    95 98
     import System.IO
    
    96 99
     import System.IO.Error
    
    97 100
     import GHC.IO.Exception (IOErrorType(InappropriateType))
    
    98 101
     import qualified GHC.Data.ShortText as ST
    
    99 102
     import GHC.IO.Handle.Lock
    
    100
    -import System.Directory
    
    103
    +import GHC.Stack.Types (HasCallStack)
    
    104
    +import System.OsPath
    
    105
    +import qualified System.Directory.OsPath as OsPath
    
    106
    +import qualified System.Directory.Internal as OsPath.Internal
    
    107
    +import qualified System.File.OsPath as FileIO
    
    101 108
     
    
    102 109
     -- | @ghc-boot@'s UnitInfo, serialized to the database.
    
    103 110
     type DbUnitInfo      = GenericUnitInfo BS.ByteString BS.ByteString BS.ByteString BS.ByteString DbModule
    
    ... ... @@ -314,13 +321,13 @@ data DbInstUnitId
    314 321
     newtype PackageDbLock = PackageDbLock Handle
    
    315 322
     
    
    316 323
     -- | Acquire an exclusive lock related to package DB under given location.
    
    317
    -lockPackageDb :: FilePath -> IO PackageDbLock
    
    324
    +lockPackageDb :: OsPath -> IO PackageDbLock
    
    318 325
     
    
    319 326
     -- | Release the lock related to package DB.
    
    320 327
     unlockPackageDb :: PackageDbLock -> IO ()
    
    321 328
     
    
    322 329
     -- | Acquire a lock of given type related to package DB under given location.
    
    323
    -lockPackageDbWith :: LockMode -> FilePath -> IO PackageDbLock
    
    330
    +lockPackageDbWith :: LockMode -> OsPath -> IO PackageDbLock
    
    324 331
     lockPackageDbWith mode file = do
    
    325 332
       -- We are trying to open the lock file and then lock it. Thus the lock file
    
    326 333
       -- needs to either exist or we need to be able to create it. Ideally we
    
    ... ... @@ -350,10 +357,10 @@ lockPackageDbWith mode file = do
    350 357
         (lockFileOpenIn ReadWriteMode)
    
    351 358
         (const $ lockFileOpenIn ReadMode)
    
    352 359
       where
    
    353
    -    lock = file <.> "lock"
    
    360
    +    lock = file <.> OsPath.Internal.os "lock"
    
    354 361
     
    
    355 362
         lockFileOpenIn io_mode = bracketOnError
    
    356
    -      (openBinaryFile lock io_mode)
    
    363
    +      (FileIO.openBinaryFile lock io_mode)
    
    357 364
           hClose
    
    358 365
           -- If file locking support is not available, ignore the error and proceed
    
    359 366
           -- normally. Without it the only thing we lose on non-Windows platforms is
    
    ... ... @@ -387,7 +394,7 @@ isDbOpenReadMode = \case
    387 394
     
    
    388 395
     -- | Read the part of the package DB that GHC is interested in.
    
    389 396
     --
    
    390
    -readPackageDbForGhc :: FilePath -> IO [DbUnitInfo]
    
    397
    +readPackageDbForGhc :: OsPath -> IO [DbUnitInfo]
    
    391 398
     readPackageDbForGhc file =
    
    392 399
       decodeFromFile file DbOpenReadOnly getDbForGhc >>= \case
    
    393 400
         (pkgs, DbOpenReadOnly) -> return pkgs
    
    ... ... @@ -409,7 +416,7 @@ readPackageDbForGhc file =
    409 416
     -- we additionally receive a PackageDbLock that represents a lock on the
    
    410 417
     -- database, so that we can safely update it later.
    
    411 418
     --
    
    412
    -readPackageDbForGhcPkg :: Binary pkgs => FilePath -> DbOpenMode mode t ->
    
    419
    +readPackageDbForGhcPkg :: Binary pkgs => OsPath -> DbOpenMode mode t ->
    
    413 420
                               IO (pkgs, DbOpenMode mode PackageDbLock)
    
    414 421
     readPackageDbForGhcPkg file mode =
    
    415 422
         decodeFromFile file mode getDbForGhcPkg
    
    ... ... @@ -425,7 +432,7 @@ readPackageDbForGhcPkg file mode =
    425 432
     
    
    426 433
     -- | Write the whole of the package DB, both parts.
    
    427 434
     --
    
    428
    -writePackageDb :: Binary pkgs => FilePath -> [DbUnitInfo] -> pkgs -> IO ()
    
    435
    +writePackageDb :: Binary pkgs => OsPath -> [DbUnitInfo] -> pkgs -> IO ()
    
    429 436
     writePackageDb file ghcPkgs ghcPkgPart = do
    
    430 437
       writeFileAtomic file (runPut putDbForGhcPkg)
    
    431 438
     #if !defined(mingw32_HOST_OS)
    
    ... ... @@ -446,10 +453,10 @@ writePackageDb file ghcPkgs ghcPkgPart = do
    446 453
             ghcPart    = encode ghcPkgs
    
    447 454
     
    
    448 455
     #if !defined(mingw32_HOST_OS)
    
    449
    -addFileMode :: FilePath -> FileMode -> IO ()
    
    456
    +addFileMode :: OsPath -> FileMode -> IO ()
    
    450 457
     addFileMode file m = do
    
    451
    -  o <- fileMode <$> getFileStatus file
    
    452
    -  setFileMode file (m .|. o)
    
    458
    +  o <- fileMode <$> getFileStatus (getOsString file)
    
    459
    +  setFileMode (getOsString file) (m .|. o)
    
    453 460
     #endif
    
    454 461
     
    
    455 462
     getHeader :: Get (Word32, Word32)
    
    ... ... @@ -496,7 +503,7 @@ headerMagic = BS.Char8.pack "\0ghcpkg\0"
    496 503
     
    
    497 504
     -- | Feed a 'Get' decoder with data chunks from a file.
    
    498 505
     --
    
    499
    -decodeFromFile :: FilePath -> DbOpenMode mode t -> Get pkgs ->
    
    506
    +decodeFromFile :: OsPath -> DbOpenMode mode t -> Get pkgs ->
    
    500 507
                       IO (pkgs, DbOpenMode mode PackageDbLock)
    
    501 508
     decodeFromFile file mode decoder = case mode of
    
    502 509
       DbOpenReadOnly -> do
    
    ... ... @@ -517,7 +524,7 @@ decodeFromFile file mode decoder = case mode of
    517 524
         bracketOnError (lockPackageDb file) unlockPackageDb $ \lock -> do
    
    518 525
           (, DbOpenReadWrite lock) <$> decodeFileContents
    
    519 526
       where
    
    520
    -    decodeFileContents = withBinaryFile file ReadMode $ \hnd ->
    
    527
    +    decodeFileContents = FileIO.withBinaryFile file ReadMode $ \hnd ->
    
    521 528
           feed hnd (runGetIncremental decoder)
    
    522 529
     
    
    523 530
         feed hnd (Partial k)  = do chunk <- BS.hGet hnd BS.Lazy.defaultChunkSize
    
    ... ... @@ -527,21 +534,21 @@ decodeFromFile file mode decoder = case mode of
    527 534
         feed _ (Done _ _ res) = return res
    
    528 535
         feed _ (Fail _ _ msg) = ioError err
    
    529 536
           where
    
    530
    -        err = mkIOError InappropriateType loc Nothing (Just file)
    
    537
    +        err = mkIOError InappropriateType loc Nothing (Just $ unsafeDecodeUtf file)
    
    531 538
                   `ioeSetErrorString` msg
    
    532 539
             loc = "GHC.Unit.Database.readPackageDb"
    
    533 540
     
    
    534 541
     -- Copied from Cabal's Distribution.Simple.Utils.
    
    535
    -writeFileAtomic :: FilePath -> BS.Lazy.ByteString -> IO ()
    
    542
    +writeFileAtomic :: OsPath -> BS.Lazy.ByteString -> IO ()
    
    536 543
     writeFileAtomic targetPath content = do
    
    537 544
       let (targetDir, targetFile) = splitFileName targetPath
    
    538 545
       Exception.bracketOnError
    
    539
    -    (openBinaryTempFileWithDefaultPermissions targetDir $ targetFile <.> "tmp")
    
    540
    -    (\(tmpPath, handle) -> hClose handle >> removeFile tmpPath)
    
    546
    +    (FileIO.openBinaryTempFileWithDefaultPermissions targetDir $ targetFile <.> OsPath.Internal.os "tmp")
    
    547
    +    (\(tmpPath, handle) -> hClose handle >> OsPath.removeFile tmpPath)
    
    541 548
         (\(tmpPath, handle) -> do
    
    542 549
             BS.Lazy.hPut handle content
    
    543 550
             hClose handle
    
    544
    -        renameFile tmpPath targetPath)
    
    551
    +        OsPath.renameFile tmpPath targetPath)
    
    545 552
     
    
    546 553
     instance Binary DbUnitInfo where
    
    547 554
       put (GenericUnitInfo
    
    ... ... @@ -711,7 +718,7 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    711 718
         -- rather than letting FilePath change it to use \ as the separator
    
    712 719
         stripVarPrefix var path = case ST.stripPrefix var path of
    
    713 720
                                   Just "" -> Just ""
    
    714
    -                              Just cs | isPathSeparator (ST.head cs) -> Just cs
    
    721
    +                              Just cs | FilePath.isPathSeparator (ST.head cs) -> Just cs
    
    715 722
                                   _ -> Nothing
    
    716 723
     
    
    717 724
     
    
    ... ... @@ -742,3 +749,8 @@ mungeUnitInfoPaths top_dir pkgroot pkg =
    742 749
           munge_paths = map munge_path
    
    743 750
           munge_urls  = map munge_url
    
    744 751
           (munge_path,munge_url) = mkMungePathUrl top_dir pkgroot
    
    752
    +
    
    753
    +-- | Decode an 'OsPath' to 'FilePath', throwing an 'error' if decoding failed.
    
    754
    +-- Prefer 'decodeUtf' and gracious error handling.
    
    755
    +unsafeDecodeUtf :: HasCallStack => OsPath -> FilePath
    
    756
    +unsafeDecodeUtf = OsPath.Internal.so

  • libraries/ghc-boot/ghc-boot.cabal.in
    ... ... @@ -82,6 +82,8 @@ Library
    82 82
                        containers >= 0.5 && < 0.9,
    
    83 83
                        directory  >= 1.2 && < 1.4,
    
    84 84
                        filepath   >= 1.3 && < 1.6,
    
    85
    +                   file-io    >= 0.1.6 && < 0.3,
    
    86
    +                   os-string  >= 2.0.1 && < 2.1,
    
    85 87
                        deepseq    >= 1.4 && < 1.6,
    
    86 88
                        ghc-platform  >= 0.1,
    
    87 89
                        ghc-toolchain >= 0.1
    

  • testsuite/tests/cabal/Makefile
    ... ... @@ -79,6 +79,25 @@ ghcpkg04 :
    79 79
     	@: # testpkg-1.2.3.4 and newtestpkg-2.0 are both exposed now
    
    80 80
     	'$(TEST_HC)' $(TEST_HC_OPTS) -package-db $(PKGCONF04) -c ghcpkg04.hs || true
    
    81 81
     
    
    82
    +PKGCONF20=local20.package.conf
    
    83
    +LOCAL_GHC_PKG20 = '$(GHC_PKG)' --no-user-package-db
    
    84
    +
    
    85
    +DIR1=asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf
    
    86
    +DIR2=zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv
    
    87
    +DIR3=uiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiop
    
    88
    +DIR4=qwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwer
    
    89
    +WDIR=$(DIR1)/$(DIR2)/$(DIR3)/$(DIR4)
    
    90
    +.PHONY: ghcpkg10
    
    91
    +ghcpkg10 :
    
    92
    +	@mkdir -p $(WDIR)
    
    93
    +	@rm -rf $(WDIR)/$(PKGCONF20)
    
    94
    +	$(LOCAL_GHC_PKG20) -f $(WDIR)/$(PKGCONF20) init $(WDIR)/$(PKGCONF20)
    
    95
    +	$(LOCAL_GHC_PKG20) -f $(WDIR)/$(PKGCONF20) list
    
    96
    +	$(LOCAL_GHC_PKG20) -f $(WDIR)/$(PKGCONF20) register --force test.pkg 2>/dev/null
    
    97
    +	$(LOCAL_GHC_PKG20) -f $(WDIR)/$(PKGCONF20) describe testpkg         | $(STRIP_PKGROOT)
    
    98
    +	$(LOCAL_GHC_PKG20) -f $(WDIR)/$(PKGCONF20) describe testpkg-1.2.3.4 | $(STRIP_PKGROOT)
    
    99
    +	$(LOCAL_GHC_PKG20) -f $(WDIR)/$(PKGCONF20) field testpkg-1.2.3.4 import-dirs
    
    100
    +
    
    82 101
     # Test stacking of package.confs (also #2441)
    
    83 102
     PKGCONF05a=local05a.package.conf
    
    84 103
     PKGCONF05b=local05b.package.conf
    

  • testsuite/tests/cabal/all.T
    ... ... @@ -5,6 +5,7 @@ def ignore_warnings(str):
    5 5
         return re.sub(r'Warning:.*\n', '', str)
    
    6 6
     
    
    7 7
     test('ghcpkg01', [extra_files(['test.pkg', 'test2.pkg', 'test3.pkg'])], makefile_test, [])
    
    8
    +test('ghcpkg10', [extra_files(['test.pkg', 'test2.pkg', 'test3.pkg'])], makefile_test, [])
    
    8 9
     
    
    9 10
     # Use ignore_stderr to prevent (when HADDOCK_DOCS=NO):
    
    10 11
     #  warning: haddock-interfaces .. doesn't exist or isn't a file
    

  • testsuite/tests/cabal/ghcpkg10.stdout
    1
    +asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf/zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv/uiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiop/qwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwerqwer/local20.package.conf
    
    2
    +    (no packages)
    
    3
    +Reading package info from "test.pkg" ... done.
    
    4
    +name:            testpkg
    
    5
    +version:         1.2.3.4
    
    6
    +visibility:      public
    
    7
    +id:              testpkg-1.2.3.4-XXX
    
    8
    +key:             testpkg-1.2.3.4-XXX
    
    9
    +license:         BSD3
    
    10
    +copyright:       (c) The Univsersity of Glasgow 2004
    
    11
    +maintainer:      glasgow-haskell-users@haskell.org
    
    12
    +author:          simonmar@microsoft.com
    
    13
    +stability:       stable
    
    14
    +homepage:        http://www.haskell.org/ghc
    
    15
    +package-url:     http://www.haskell.org/ghc
    
    16
    +description:     A Test Package
    
    17
    +category:        none
    
    18
    +exposed:         True
    
    19
    +exposed-modules: A
    
    20
    +hidden-modules:  B C.D
    
    21
    +import-dirs:     /usr/local/lib/testpkg "c:/Program Files/testpkg"
    
    22
    +library-dirs:    /usr/local/lib/testpkg "c:/Program Files/testpkg"
    
    23
    +hs-libraries:    testpkg-1.2.3.4-XXX
    
    24
    +include-dirs:    /usr/local/include/testpkg "c:/Program Files/testpkg"
    
    25
    +pkgroot: 
    
    26
    +
    
    27
    +name:            testpkg
    
    28
    +version:         1.2.3.4
    
    29
    +visibility:      public
    
    30
    +id:              testpkg-1.2.3.4-XXX
    
    31
    +key:             testpkg-1.2.3.4-XXX
    
    32
    +license:         BSD3
    
    33
    +copyright:       (c) The Univsersity of Glasgow 2004
    
    34
    +maintainer:      glasgow-haskell-users@haskell.org
    
    35
    +author:          simonmar@microsoft.com
    
    36
    +stability:       stable
    
    37
    +homepage:        http://www.haskell.org/ghc
    
    38
    +package-url:     http://www.haskell.org/ghc
    
    39
    +description:     A Test Package
    
    40
    +category:        none
    
    41
    +exposed:         True
    
    42
    +exposed-modules: A
    
    43
    +hidden-modules:  B C.D
    
    44
    +import-dirs:     /usr/local/lib/testpkg "c:/Program Files/testpkg"
    
    45
    +library-dirs:    /usr/local/lib/testpkg "c:/Program Files/testpkg"
    
    46
    +hs-libraries:    testpkg-1.2.3.4-XXX
    
    47
    +include-dirs:    /usr/local/include/testpkg "c:/Program Files/testpkg"
    
    48
    +pkgroot: 
    
    49
    +
    
    50
    +import-dirs: /usr/local/lib/testpkg "c:/Program Files/testpkg"

  • 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"#)
    

  • utils/ghc-pkg/Main.hs
    ... ... @@ -47,12 +47,19 @@ import Distribution.Types.UnqualComponentName
    47 47
     import Distribution.Types.LibraryName
    
    48 48
     import Distribution.Types.MungedPackageName
    
    49 49
     import Distribution.Types.MungedPackageId
    
    50
    -import Distribution.Simple.Utils (toUTF8BS, writeUTF8File, readUTF8File)
    
    50
    +import Distribution.Simple.Utils (ignoreBOM, toUTF8BS, toUTF8LBS, fromUTF8LBS)
    
    51 51
     import qualified Data.Version as Version
    
    52
    -import System.FilePath as FilePath
    
    52
    +import System.OsPath as OsPath
    
    53
    +import qualified System.FilePath as FilePath
    
    53 54
     import qualified System.FilePath.Posix as FilePath.Posix
    
    54
    -import System.Directory ( getXdgDirectory, createDirectoryIfMissing, getAppUserDataDirectory,
    
    55
    -                          getModificationTime, XdgDirectory ( XdgData ) )
    
    55
    +import System.Directory.OsPath
    
    56
    +  ( getXdgDirectory, createDirectoryIfMissing, getAppUserDataDirectory,
    
    57
    +    getModificationTime, XdgDirectory ( XdgData ),
    
    58
    +    doesDirectoryExist, getDirectoryContents,
    
    59
    +    doesFileExist, removeFile,
    
    60
    +    getCurrentDirectory )
    
    61
    +import System.Directory.Internal (os)
    
    62
    +import qualified System.File.OsPath as FileIO
    
    56 63
     import Text.Printf
    
    57 64
     
    
    58 65
     import Prelude hiding (Foldable(..))
    
    ... ... @@ -65,15 +72,13 @@ import Data.Bifunctor
    65 72
     
    
    66 73
     import Data.Char ( toLower )
    
    67 74
     import Control.Monad
    
    68
    -import System.Directory ( doesDirectoryExist, getDirectoryContents,
    
    69
    -                          doesFileExist, removeFile,
    
    70
    -                          getCurrentDirectory )
    
    71 75
     import System.Exit ( exitWith, ExitCode(..) )
    
    72 76
     import System.Environment ( getArgs, getProgName, getEnv )
    
    73 77
     import System.IO
    
    74 78
     import System.IO.Error
    
    75
    -import GHC.IO           ( catchException )
    
    79
    +import GHC.IO           ( catchException, unsafePerformIO )
    
    76 80
     import GHC.IO.Exception (IOErrorType(InappropriateType))
    
    81
    +import GHC.Stack.Types (HasCallStack)
    
    77 82
     import Data.List ( group, sort, sortBy, nub, partition, find
    
    78 83
                      , intercalate, intersperse, unfoldr
    
    79 84
                      , isInfixOf, isSuffixOf, isPrefixOf, stripPrefix )
    
    ... ... @@ -429,8 +434,9 @@ runit verbosity cli nonopts = do
    429 434
             print filename
    
    430 435
             glob filename >>= print
    
    431 436
     #endif
    
    432
    -    ["init", filename] ->
    
    433
    -        initPackageDB filename verbosity cli
    
    437
    +    ["init", filename] -> do
    
    438
    +        filenameOs <- encodeFS filename
    
    439
    +        initPackageDB filenameOs verbosity cli
    
    434 440
         ["register", filename] ->
    
    435 441
             registerPackage filename verbosity cli
    
    436 442
                             multi_instance
    
    ... ... @@ -538,7 +544,7 @@ readPackageArg AsDefault str = Id <$> readGlobPkgId str
    538 544
     
    
    539 545
     data PackageDB (mode :: GhcPkg.DbMode)
    
    540 546
       = PackageDB {
    
    541
    -      location, locationAbsolute :: !FilePath,
    
    547
    +      location, locationAbsolute :: !OsPath,
    
    542 548
           -- We need both possibly-relative and definitely-absolute package
    
    543 549
           -- db locations. This is because the relative location is used as
    
    544 550
           -- an identifier for the db, so it is important we do not modify it.
    
    ... ... @@ -570,14 +576,14 @@ allPackagesInStack = concatMap packages
    570 576
     -- specified package DB can depend on, since dependencies can only extend
    
    571 577
     -- down the stack, not up (e.g. global packages cannot depend on user
    
    572 578
     -- packages).
    
    573
    -stackUpTo :: FilePath -> PackageDBStack -> PackageDBStack
    
    579
    +stackUpTo :: OsPath -> PackageDBStack -> PackageDBStack
    
    574 580
     stackUpTo to_modify = dropWhile ((/= to_modify) . location)
    
    575 581
     
    
    576
    -readFromSettingsFile :: FilePath
    
    577
    -                      -> (FilePath -> RawSettings -> Either String b)
    
    582
    +readFromSettingsFile :: OsPath
    
    583
    +                      -> (OsPath -> RawSettings -> Either String b)
    
    578 584
                           -> IO (Either String b)
    
    579 585
     readFromSettingsFile settingsFile f = do
    
    580
    -  settingsStr <- readFile settingsFile
    
    586
    +  settingsStr <- readUtf8File settingsFile
    
    581 587
       pure $ do
    
    582 588
         mySettings <- case maybeReadFuzzy settingsStr of
    
    583 589
           Just s -> pure $ Map.fromList s
    
    ... ... @@ -586,11 +592,11 @@ readFromSettingsFile settingsFile f = do
    586 592
           Nothing -> Left $ "Can't parse settings file " ++ show settingsFile
    
    587 593
         f settingsFile mySettings
    
    588 594
     
    
    589
    -readFromTargetFile :: FilePath
    
    595
    +readFromTargetFile :: OsPath
    
    590 596
                        -> (Target -> b)
    
    591 597
                        -> IO (Either String b)
    
    592 598
     readFromTargetFile targetFile f = do
    
    593
    -  targetStr <- readFile targetFile
    
    599
    +  targetStr <- readUtf8File targetFile
    
    594 600
       pure $ do
    
    595 601
         target <- case maybeReadFuzzy targetStr of
    
    596 602
           Just t -> Right t
    
    ... ... @@ -626,33 +632,35 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    626 632
          case [ f | FlagGlobalConfig f <- my_flags ] of
    
    627 633
             -- See Note [Base Dir] for more information on the base dir / top dir.
    
    628 634
             [] -> do mb_dir <- getBaseDir
    
    629
    -                 case mb_dir of
    
    635
    +                 mb_dir_os <- traverse encodeFS mb_dir
    
    636
    +                 case mb_dir_os of
    
    630 637
                        Nothing  -> die err_msg
    
    631 638
                        Just dir -> do
    
    632 639
                          -- Look for where it is given in the settings file, if marked there.
    
    633 640
                          -- See Note [Settings file] about this file, and why we need GHC to share it with us.
    
    634
    -                     let settingsFile = dir </> "settings"
    
    641
    +                     let settingsFile = dir </> os "settings"
    
    635 642
                          exists_settings_file <- doesFileExist settingsFile
    
    636 643
                          erel_db <-
    
    637 644
                           if exists_settings_file
    
    638
    -                          then readFromSettingsFile settingsFile getGlobalPackageDb
    
    639
    -                          else pure (Left ("Settings file doesn't exist: " ++ settingsFile))
    
    645
    +                          then do
    
    646
    +                            readFromSettingsFile settingsFile (\ settings  -> getGlobalPackageDb (unsafeDecodeUtf settings))
    
    647
    +                          else pure (Left ("Settings file doesn't exist: " ++ showOsPath settingsFile))
    
    640 648
     
    
    641 649
                          case erel_db of
    
    642
    -                      Right rel_db -> return (dir, dir </> rel_db)
    
    650
    +                      Right rel_db -> return (dir, dir </> unsafeEncodeUtf rel_db)
    
    643 651
                           -- If the version of GHC doesn't have this field or the settings file
    
    644 652
                           -- doesn't exist for some reason, look in the libdir.
    
    645 653
                           Left err -> do
    
    646 654
                             r <- lookForPackageDBIn dir
    
    647 655
                             case r of
    
    648
    -                          Nothing -> die (unlines [err, ("Fallback: Can't find package database in " ++ dir)])
    
    656
    +                          Nothing -> die (unlines [err, ("Fallback: Can't find package database in " ++ showOsPath dir)])
    
    649 657
                               Just path -> return (dir, path)
    
    650 658
             fs -> do
    
    651 659
               -- The value of the $topdir variable used in some package descriptions
    
    652 660
               -- Note that the way we calculate this is slightly different to how it
    
    653 661
               -- is done in ghc itself. We rely on the convention that the global
    
    654 662
               -- package db lives in ghc's libdir.
    
    655
    -          let pkg_db = last fs
    
    663
    +          let pkg_db = unsafeEncodeUtf $ last fs
    
    656 664
               top_dir <- absolutePath (takeDirectory pkg_db)
    
    657 665
               return (top_dir, pkg_db)
    
    658 666
     
    
    ... ... @@ -662,10 +670,10 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    662 670
       -- getXdgDirectory can fail (e.g. if $HOME isn't set)
    
    663 671
     
    
    664 672
       mb_user_conf <-
    
    665
    -    case [ f | FlagUserConfig f <- my_flags ] of
    
    673
    +    case [ unsafeEncodeUtf f | FlagUserConfig f <- my_flags ] of
    
    666 674
           _ | no_user_db -> return Nothing
    
    667 675
           [] -> do
    
    668
    -        let targetFile = top_dir </> "targets" </> "default.target"
    
    676
    +        let targetFile = top_dir </> os "targets" </> os "default.target"
    
    669 677
             exists_settings_file <- doesFileExist targetFile
    
    670 678
             targetArchOS <- case exists_settings_file of
    
    671 679
               False -> do
    
    ... ... @@ -694,15 +702,15 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    694 702
             -- otherwise we use $XDG_DATA_HOME/$UNIQUE_SUBDIR
    
    695 703
             --
    
    696 704
             -- UNIQUE_SUBDIR is typically a combination of the target platform and GHC version
    
    697
    -        m_appdir <- getFirstSuccess $ map (fmap (</> subdir))
    
    698
    -          [ getAppUserDataDirectory "ghc"  -- this is ~/.ghc/
    
    699
    -          , getXdgDirectory XdgData "ghc"  -- this is $XDG_DATA_HOME/
    
    705
    +        m_appdir <- getFirstSuccess $ map (fmap (</> unsafeEncodeUtf subdir))
    
    706
    +          [ getAppUserDataDirectory $ os "ghc"  -- this is ~/.ghc/
    
    707
    +          , getXdgDirectory XdgData $ os "ghc"  -- this is $XDG_DATA_HOME/
    
    700 708
               ]
    
    701 709
             case m_appdir of
    
    702 710
               Nothing -> return Nothing
    
    703 711
               Just dir -> do
    
    704 712
                 lookForPackageDBIn dir >>= \case
    
    705
    -              Nothing -> return (Just (dir </> "package.conf.d", False))
    
    713
    +              Nothing -> return (Just (dir </> os "package.conf.d", False))
    
    706 714
                   Just f  -> return (Just (f, True))
    
    707 715
           fs -> return (Just (last fs, True))
    
    708 716
     
    
    ... ... @@ -716,11 +724,11 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    716 724
     
    
    717 725
       e_pkg_path <- tryIO (System.Environment.getEnv "GHC_PACKAGE_PATH")
    
    718 726
       let env_stack =
    
    719
    -        case e_pkg_path of
    
    727
    +        case fmap unsafeEncodeUtf e_pkg_path of
    
    720 728
                     Left  _ -> sys_databases
    
    721 729
                     Right path
    
    722
    -                  | not (null path) && isSearchPathSeparator (last path)
    
    723
    -                  -> splitSearchPath (init path) ++ sys_databases
    
    730
    +                  | hasTrailingPathSeparator path
    
    731
    +                  -> splitSearchPath (dropTrailingPathSeparator path) <> sys_databases
    
    724 732
                       | otherwise
    
    725 733
                       -> splitSearchPath path
    
    726 734
     
    
    ... ... @@ -733,7 +741,7 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    733 741
                           | Just (user_conf, _user_exists) <- mb_user_conf
    
    734 742
                           = Just user_conf
    
    735 743
                    is_db_flag FlagGlobal     = Just virt_global_conf
    
    736
    -               is_db_flag (FlagConfig f) = Just f
    
    744
    +               is_db_flag (FlagConfig f) = Just $ unsafeEncodeUtf f
    
    737 745
                    is_db_flag _              = Nothing
    
    738 746
     
    
    739 747
       let flag_db_names | null db_flags = env_stack
    
    ... ... @@ -748,7 +756,7 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    748 756
       -- stack, unless any of them are present in the stack
    
    749 757
       -- already.
    
    750 758
       let final_stack = filter (`notElem` env_stack)
    
    751
    -                     [ f | FlagConfig f <- reverse my_flags ]
    
    759
    +                     [ unsafeEncodeUtf f | FlagConfig f <- reverse my_flags ]
    
    752 760
                          ++ env_stack
    
    753 761
     
    
    754 762
           top_db = if null db_flags
    
    ... ... @@ -764,7 +772,7 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    764 772
       when (verbosity > Normal) $ do
    
    765 773
         infoLn ("db stack: " ++ show (map location db_stack))
    
    766 774
         F.forM_ db_to_operate_on $ \db ->
    
    767
    -      infoLn ("modifying: " ++ (location db))
    
    775
    +      infoLn ("modifying: " ++ showOsPath (location db))
    
    768 776
         infoLn ("flag db stack: " ++ show (map location flag_db_stack))
    
    769 777
     
    
    770 778
       return (db_stack, db_to_operate_on, flag_db_stack)
    
    ... ... @@ -843,17 +851,19 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    843 851
     
    
    844 852
             return (db_stack, GhcPkg.DbOpenReadWrite to_modify)
    
    845 853
           where
    
    846
    -        couldntOpenDbForModification :: FilePath -> IOError -> IO a
    
    854
    +        couldntOpenDbForModification :: OsPath -> IOError -> IO a
    
    847 855
             couldntOpenDbForModification db_path e = die $ "Couldn't open database "
    
    848
    -          ++ db_path ++ " for modification: " ++ show e
    
    856
    +          ++ showOsPath db_path ++ " for modification: " ++ show e
    
    849 857
     
    
    850 858
             -- Parse package db in read-only mode.
    
    851
    -        readDatabase :: FilePath -> IO (PackageDB 'GhcPkg.DbReadOnly)
    
    859
    +        readDatabase :: OsPath -> IO (PackageDB 'GhcPkg.DbReadOnly)
    
    852 860
             readDatabase db_path = do
    
    853 861
               db <- readParseDatabase verbosity mb_user_conf
    
    854 862
                                       GhcPkg.DbOpenReadOnly use_cache db_path
    
    855 863
               if expand_vars
    
    856
    -            then return $ mungePackageDBPaths top_dir db
    
    864
    +            then do
    
    865
    +              top_dir_filepath <- decodeFS top_dir
    
    866
    +              return $ mungePackageDBPaths top_dir_filepath db
    
    857 867
                 else return db
    
    858 868
     
    
    859 869
         stateSequence :: Monad m => s -> [s -> m (a, s)] -> m ([a], s)
    
    ... ... @@ -863,20 +873,20 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    863 873
           (as, s'') <- stateSequence s' ms
    
    864 874
           return (a : as, s'')
    
    865 875
     
    
    866
    -lookForPackageDBIn :: FilePath -> IO (Maybe FilePath)
    
    876
    +lookForPackageDBIn :: OsPath -> IO (Maybe OsPath)
    
    867 877
     lookForPackageDBIn dir = do
    
    868
    -  let path_dir = dir </> "package.conf.d"
    
    878
    +  let path_dir = dir </> os "package.conf.d"
    
    869 879
       exists_dir <- doesDirectoryExist path_dir
    
    870 880
       if exists_dir then return (Just path_dir) else do
    
    871
    -    let path_file = dir </> "package.conf"
    
    881
    +    let path_file = dir </> os "package.conf"
    
    872 882
         exists_file <- doesFileExist path_file
    
    873 883
         if exists_file then return (Just path_file) else return Nothing
    
    874 884
     
    
    875 885
     readParseDatabase :: forall mode t. Verbosity
    
    876
    -                  -> Maybe (FilePath,Bool)
    
    886
    +                  -> Maybe (OsPath,Bool)
    
    877 887
                       -> GhcPkg.DbOpenMode mode t
    
    878 888
                       -> Bool -- use cache
    
    879
    -                  -> FilePath
    
    889
    +                  -> OsPath
    
    880 890
                       -> IO (PackageDB mode)
    
    881 891
     readParseDatabase verbosity mb_user_conf mode use_cache path
    
    882 892
       -- the user database (only) is allowed to be non-existent
    
    ... ... @@ -898,7 +908,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    898 908
                     Just db -> return db
    
    899 909
                     Nothing ->
    
    900 910
                       die $ "ghc no longer supports single-file style package "
    
    901
    -                     ++ "databases (" ++ path ++ ") use 'ghc-pkg init'"
    
    911
    +                     ++ "databases (" ++ showOsPath path ++ ") use 'ghc-pkg init'"
    
    902 912
                          ++ "to create the database with the correct format."
    
    903 913
     
    
    904 914
                | otherwise -> ioError err
    
    ... ... @@ -914,7 +924,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    914 924
                             -- It's fine if the cache is not there as long as the
    
    915 925
                             -- database is empty.
    
    916 926
                             when (not $ null confs) $ do
    
    917
    -                            warn ("WARNING: cache does not exist: " ++ cache)
    
    927
    +                            warn ("WARNING: cache does not exist: " ++ showOsPath cache)
    
    918 928
                                 warn ("ghc will fail to read this package db. " ++
    
    919 929
                                       recacheAdvice)
    
    920 930
                           else do
    
    ... ... @@ -923,7 +933,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    923 933
                       ignore_cache (const $ return ())
    
    924 934
                     Right tcache -> do
    
    925 935
                       when (verbosity >= Verbose) $ do
    
    926
    -                      warn ("Timestamp " ++ show tcache ++ " for " ++ cache)
    
    936
    +                      warn ("Timestamp " ++ show tcache ++ " for " ++ showOsPath cache)
    
    927 937
                       -- If any of the .conf files is newer than package.cache, we
    
    928 938
                       -- assume that cache is out of date.
    
    929 939
                       cache_outdated <- (`anyM` confs) $ \conf ->
    
    ... ... @@ -931,12 +941,12 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    931 941
                       if not cache_outdated
    
    932 942
                           then do
    
    933 943
                               when (verbosity > Normal) $
    
    934
    -                             infoLn ("using cache: " ++ cache)
    
    944
    +                             infoLn ("using cache: " ++ showOsPath cache)
    
    935 945
                               GhcPkg.readPackageDbForGhcPkg cache mode
    
    936 946
                                 >>= uncurry mkPackageDB
    
    937 947
                           else do
    
    938 948
                               whenReportCacheErrors $ do
    
    939
    -                              warn ("WARNING: cache is out of date: " ++ cache)
    
    949
    +                              warn ("WARNING: cache is out of date: " ++ showOsPath cache)
    
    940 950
                                   warn ("ghc will see an old view of this " ++
    
    941 951
                                         "package db. " ++ recacheAdvice)
    
    942 952
                               ignore_cache $ \file -> do
    
    ... ... @@ -947,11 +957,11 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    947 957
                                         GT -> " (older than cache)"
    
    948 958
                                         EQ -> " (same as cache)"
    
    949 959
                                   warn ("Timestamp " ++ show tFile
    
    950
    -                                ++ " for " ++ file ++ rel)
    
    960
    +                                ++ " for " ++ showOsPath file ++ rel)
    
    951 961
                 where
    
    952
    -                 confs = map (path </>) $ filter (".conf" `isSuffixOf`) fs
    
    962
    +                 confs = map (path </>) $ filter (os ".conf" `OsPath.isExtensionOf`) fs
    
    953 963
     
    
    954
    -                 ignore_cache :: (FilePath -> IO ()) -> IO (PackageDB mode)
    
    964
    +                 ignore_cache :: (OsPath -> IO ()) -> IO (PackageDB mode)
    
    955 965
                      ignore_cache checkTime = do
    
    956 966
                          -- If we're opening for modification, we need to acquire a
    
    957 967
                          -- lock even if we don't open the cache now, because we are
    
    ... ... @@ -987,17 +997,18 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    987 997
               packages = pkgs
    
    988 998
             }
    
    989 999
     
    
    990
    -parseSingletonPackageConf :: Verbosity -> FilePath -> IO InstalledPackageInfo
    
    1000
    +parseSingletonPackageConf :: Verbosity -> OsPath -> IO InstalledPackageInfo
    
    991 1001
     parseSingletonPackageConf verbosity file = do
    
    992
    -  when (verbosity > Normal) $ infoLn ("reading package config: " ++ file)
    
    993
    -  BS.readFile file >>= fmap fst . parsePackageInfo
    
    1002
    +  when (verbosity > Normal) $ infoLn ("reading package config: " ++ showOsPath file)
    
    1003
    +  FileIO.readFile file >>= fmap fst . parsePackageInfo . BS.toStrict
    
    1004
    +
    
    994 1005
     
    
    995
    -cachefilename :: FilePath
    
    996
    -cachefilename = "package.cache"
    
    1006
    +cachefilename :: OsPath
    
    1007
    +cachefilename = os "package.cache"
    
    997 1008
     
    
    998 1009
     mungePackageDBPaths :: FilePath -> PackageDB mode -> PackageDB mode
    
    999 1010
     mungePackageDBPaths top_dir db@PackageDB { packages = pkgs } =
    
    1000
    -    db { packages = map (mungePackagePaths top_dir pkgroot) pkgs }
    
    1011
    +    db { packages = map (mungePackagePaths top_dir (unsafeDecodeUtf pkgroot)) pkgs }
    
    1001 1012
       where
    
    1002 1013
         pkgroot = takeDirectory $ dropTrailingPathSeparator (locationAbsolute db)
    
    1003 1014
         -- It so happens that for both styles of package db ("package.conf"
    
    ... ... @@ -1044,12 +1055,13 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    1044 1055
           | Just p' <- stripVarPrefix "$httptopdir"   p = toUrlPath top_dir p'
    
    1045 1056
           | otherwise                                   = p
    
    1046 1057
     
    
    1058
    +    toUrlPath :: FilePath -> FilePath -> FilePath
    
    1047 1059
         toUrlPath r p = "file:///"
    
    1048 1060
                      -- URLs always use posix style '/' separators:
    
    1049 1061
                      ++ FilePath.Posix.joinPath
    
    1050 1062
                             (r : -- We need to drop a leading "/" or "\\"
    
    1051 1063
                                  -- if there is one:
    
    1052
    -                             dropWhile (all isPathSeparator)
    
    1064
    +                             dropWhile (all FilePath.isPathSeparator)
    
    1053 1065
                                            (FilePath.splitDirectories p))
    
    1054 1066
     
    
    1055 1067
         -- We could drop the separator here, and then use </> above. However,
    
    ... ... @@ -1057,7 +1069,7 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    1057 1069
         -- rather than letting FilePath change it to use \ as the separator
    
    1058 1070
         stripVarPrefix var path = case stripPrefix var path of
    
    1059 1071
                                   Just [] -> Just []
    
    1060
    -                              Just cs@(c : _) | isPathSeparator c -> Just cs
    
    1072
    +                              Just cs@(c : _) | FilePath.isPathSeparator c -> Just cs
    
    1061 1073
                                   _ -> Nothing
    
    1062 1074
     
    
    1063 1075
     -- -----------------------------------------------------------------------------
    
    ... ... @@ -1074,18 +1086,18 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    1074 1086
     
    
    1075 1087
     -- ghc itself also cooperates in this workaround
    
    1076 1088
     
    
    1077
    -tryReadParseOldFileStyleDatabase :: Verbosity -> Maybe (FilePath, Bool)
    
    1078
    -                                 -> GhcPkg.DbOpenMode mode t -> Bool -> FilePath
    
    1089
    +tryReadParseOldFileStyleDatabase :: Verbosity -> Maybe (OsPath, Bool)
    
    1090
    +                                 -> GhcPkg.DbOpenMode mode t -> Bool -> OsPath
    
    1079 1091
                                      -> IO (Maybe (PackageDB mode))
    
    1080 1092
     tryReadParseOldFileStyleDatabase verbosity mb_user_conf
    
    1081 1093
                                      mode use_cache path = do
    
    1082 1094
       -- assumes we've already established that path exists and is not a dir
    
    1083
    -  content <- readFile path `catchIO` \_ -> return ""
    
    1095
    +  content <- readUtf8File path `catchIO` \_ -> return ""
    
    1084 1096
       if take 2 content == "[]"
    
    1085 1097
         then do
    
    1086 1098
           path_abs <- absolutePath path
    
    1087 1099
           let path_dir = adjustOldDatabasePath path
    
    1088
    -      warn $ "Warning: ignoring old file-style db and trying " ++ path_dir
    
    1100
    +      warn $ "Warning: ignoring old file-style db and trying " ++ showOsPath path_dir
    
    1089 1101
           direxists <- doesDirectoryExist path_dir
    
    1090 1102
           if direxists
    
    1091 1103
             then do
    
    ... ... @@ -1112,7 +1124,7 @@ tryReadParseOldFileStyleDatabase verbosity mb_user_conf
    1112 1124
     adjustOldFileStylePackageDB :: PackageDB mode -> IO (PackageDB mode)
    
    1113 1125
     adjustOldFileStylePackageDB db = do
    
    1114 1126
       -- assumes we have not yet established if it's an old style or not
    
    1115
    -  mcontent <- liftM Just (readFile (location db)) `catchIO` \_ -> return Nothing
    
    1127
    +  mcontent <- liftM Just (readUtf8File (location db)) `catchIO` \_ -> return Nothing
    
    1116 1128
       case fmap (take 2) mcontent of
    
    1117 1129
         -- it is an old style and empty db, so look for a dir kind in location.d/
    
    1118 1130
         Just "[]" -> return db {
    
    ... ... @@ -1121,20 +1133,20 @@ adjustOldFileStylePackageDB db = do
    1121 1133
           }
    
    1122 1134
         -- it is old style but not empty, we have to bail
    
    1123 1135
         Just  _   -> die $ "ghc no longer supports single-file style package "
    
    1124
    -                    ++ "databases (" ++ location db ++ ") use 'ghc-pkg init'"
    
    1136
    +                    ++ "databases (" ++ showOsPath (location db) ++ ") use 'ghc-pkg init'"
    
    1125 1137
                         ++ "to create the database with the correct format."
    
    1126 1138
         -- probably not old style, carry on as normal
    
    1127 1139
         Nothing   -> return db
    
    1128 1140
     
    
    1129
    -adjustOldDatabasePath :: FilePath -> FilePath
    
    1130
    -adjustOldDatabasePath = (<.> "d")
    
    1141
    +adjustOldDatabasePath :: OsPath -> OsPath
    
    1142
    +adjustOldDatabasePath = (<.> os "d")
    
    1131 1143
     
    
    1132 1144
     -- -----------------------------------------------------------------------------
    
    1133 1145
     -- Creating a new package DB
    
    1134 1146
     
    
    1135
    -initPackageDB :: FilePath -> Verbosity -> [Flag] -> IO ()
    
    1147
    +initPackageDB :: OsPath -> Verbosity -> [Flag] -> IO ()
    
    1136 1148
     initPackageDB filename verbosity _flags = do
    
    1137
    -  let eexist = die ("cannot create: " ++ filename ++ " already exists")
    
    1149
    +  let eexist = die ("cannot create: " ++ showOsPath filename ++ " already exists")
    
    1138 1150
       b1 <- doesFileExist filename
    
    1139 1151
       when b1 eexist
    
    1140 1152
       b2 <- doesDirectoryExist filename
    
    ... ... @@ -1183,7 +1195,8 @@ registerPackage input verbosity my_flags multi_instance
    1183 1195
           f   -> do
    
    1184 1196
             when (verbosity >= Normal) $
    
    1185 1197
                 info ("Reading package info from " ++ show f ++ " ... ")
    
    1186
    -        readUTF8File f
    
    1198
    +        fs <- encodeFS f
    
    1199
    +        readUtf8File fs
    
    1187 1200
     
    
    1188 1201
       expanded <- if expand_env_vars then expandEnvVars s force
    
    1189 1202
                                      else return s
    
    ... ... @@ -1199,7 +1212,11 @@ registerPackage input verbosity my_flags multi_instance
    1199 1212
       -- validate the expanded pkg, but register the unexpanded
    
    1200 1213
       pkgroot <- absolutePath (takeDirectory to_modify)
    
    1201 1214
       let top_dir = takeDirectory (location (last db_stack))
    
    1202
    -      pkg_expanded = mungePackagePaths top_dir pkgroot pkg
    
    1215
    +
    
    1216
    +  top_dir_filepath <- decodeFS top_dir
    
    1217
    +  pkgroot_filepath <- decodeFS pkgroot
    
    1218
    +  let
    
    1219
    +      pkg_expanded = mungePackagePaths top_dir_filepath pkgroot_filepath pkg
    
    1203 1220
     
    
    1204 1221
       let truncated_stack = stackUpTo to_modify db_stack
    
    1205 1222
       -- truncate the stack for validation, because we don't allow
    
    ... ... @@ -1274,13 +1291,13 @@ changeDBDir verbosity cmds db db_stack = do
    1274 1291
       updateDBCache verbosity db db_stack
    
    1275 1292
      where
    
    1276 1293
       do_cmd (RemovePackage p) = do
    
    1277
    -    let file = location db </> display (installedUnitId p) <.> "conf"
    
    1278
    -    when (verbosity > Normal) $ infoLn ("removing " ++ file)
    
    1294
    +    let file = location db </> unsafeEncodeUtf (display (installedUnitId p)) <.> os "conf"
    
    1295
    +    when (verbosity > Normal) $ infoLn ("removing " ++ showOsPath file)
    
    1279 1296
         removeFileSafe file
    
    1280 1297
       do_cmd (AddPackage p) = do
    
    1281
    -    let file = location db </> display (installedUnitId p) <.> "conf"
    
    1282
    -    when (verbosity > Normal) $ infoLn ("writing " ++ file)
    
    1283
    -    writeUTF8File file (showInstalledPackageInfo p)
    
    1298
    +    let file = location db </> unsafeEncodeUtf (display (installedUnitId p)) <.> os "conf"
    
    1299
    +    when (verbosity > Normal) $ infoLn ("writing " ++ showOsPath file)
    
    1300
    +    writeUtf8File file (showInstalledPackageInfo p)
    
    1284 1301
       do_cmd (ModifyPackage p) =
    
    1285 1302
         do_cmd (AddPackage p)
    
    1286 1303
     
    
    ... ... @@ -1338,13 +1355,13 @@ updateDBCache verbosity db db_stack = do
    1338 1355
                 warn $ "    " ++ pkg
    
    1339 1356
     
    
    1340 1357
       when (verbosity > Normal) $
    
    1341
    -      infoLn ("writing cache " ++ filename)
    
    1358
    +      infoLn ("writing cache " ++ showOsPath filename)
    
    1342 1359
     
    
    1343 1360
       let d = fmap (fromPackageCacheFormat . fst) pkgsGhcCacheFormat
    
    1344 1361
       GhcPkg.writePackageDb filename d pkgsCabalFormat
    
    1345 1362
         `catchIO` \e ->
    
    1346 1363
           if isPermissionError e
    
    1347
    -      then die $ filename ++ ": you don't have permission to modify this file"
    
    1364
    +      then die $ showOsPath filename ++ ": you don't have permission to modify this file"
    
    1348 1365
           else ioError e
    
    1349 1366
     
    
    1350 1367
       case packageDbLock db of
    
    ... ... @@ -1583,7 +1600,7 @@ listPackages verbosity my_flags mPackageName mModuleName = do
    1583 1600
           broken = map installedUnitId (brokenPackages pkg_map)
    
    1584 1601
     
    
    1585 1602
           show_normal PackageDB{ location = db_name, packages = pkg_confs } =
    
    1586
    -          do hPutStrLn stdout db_name
    
    1603
    +          do hPutStrLn stdout (showOsPath db_name)
    
    1587 1604
                  if null pkg_confs
    
    1588 1605
                      then hPutStrLn stdout "    (no packages)"
    
    1589 1606
                      else hPutStrLn stdout $ unlines (map ("    " ++) (map pp_pkg pkg_confs))
    
    ... ... @@ -1610,7 +1627,7 @@ listPackages verbosity my_flags mPackageName mModuleName = do
    1610 1627
     #else
    
    1611 1628
         let
    
    1612 1629
           show_colour PackageDB{ location = db_name, packages = pkg_confs } =
    
    1613
    -          do hPutStrLn stdout db_name
    
    1630
    +          do hPutStrLn stdout (showOsPath db_name)
    
    1614 1631
                  if null pkg_confs
    
    1615 1632
                      then hPutStrLn stdout "    (no packages)"
    
    1616 1633
                      else hPutStrLn stdout $ unlines (map ("    " ++) (map pp_pkg pkg_confs))
    
    ... ... @@ -1698,7 +1715,7 @@ dumpUnits verbosity my_flags expand_pkgroot = do
    1698 1715
       doDump expand_pkgroot [ (pkg, locationAbsolute db)
    
    1699 1716
                             | db <- flag_db_stack, pkg <- packages db ]
    
    1700 1717
     
    
    1701
    -doDump :: Bool -> [(InstalledPackageInfo, FilePath)] -> IO ()
    
    1718
    +doDump :: Bool -> [(InstalledPackageInfo, OsPath)] -> IO ()
    
    1702 1719
     doDump expand_pkgroot pkgs = do
    
    1703 1720
       -- fix the encoding to UTF-8, since this is an interchange format
    
    1704 1721
       hSetEncoding stdout utf8
    
    ... ... @@ -1731,7 +1748,7 @@ findPackagesByDB db_stack pkgarg
    1731 1748
     
    
    1732 1749
     cannotFindPackage :: PackageArg -> Maybe (PackageDB mode) -> IO a
    
    1733 1750
     cannotFindPackage pkgarg mdb = die $ "cannot find package " ++ pkg_msg pkgarg
    
    1734
    -  ++ maybe "" (\db -> " in " ++ location db) mdb
    
    1751
    +  ++ maybe "" (\db -> " in " ++ showOsPath (location db)) mdb
    
    1735 1752
       where
    
    1736 1753
         pkg_msg (Id pkgid)           = displayGlobPkgId pkgid
    
    1737 1754
         pkg_msg (IUId ipid)          = display ipid
    
    ... ... @@ -1944,7 +1961,7 @@ checkPackageConfig pkg verbosity db_stack
    1944 1961
       checkExposedModules db_stack pkg
    
    1945 1962
       checkOtherModules pkg
    
    1946 1963
       let has_code = Set.null (openModuleSubstFreeHoles (Map.fromList (instantiatedWith pkg)))
    
    1947
    -  when has_code $ mapM_ (checkHSLib verbosity (libraryDirs pkg ++ libraryDynDirs pkg)) (hsLibraries pkg)
    
    1964
    +  when has_code $ mapM_ (checkHSLib verbosity (fmap unsafeEncodeUtf $ libraryDirs pkg ++ libraryDynDirs pkg)) (hsLibraries pkg)
    
    1948 1965
       -- ToDo: check these somehow?
    
    1949 1966
       --    extra_libraries :: [String],
    
    1950 1967
       --    c_includes      :: [String],
    
    ... ... @@ -2011,20 +2028,20 @@ checkPath url_ok is_dir warn_only thisfield d
    2011 2028
                || "https://" `isPrefixOf` d) = return ()
    
    2012 2029
     
    
    2013 2030
      | url_ok
    
    2014
    - , Just d' <- stripPrefix "file://" d
    
    2015
    - = checkPath False is_dir warn_only thisfield d'
    
    2031
    + , Just f <- stripPrefix "file://" d
    
    2032
    + = checkPath False is_dir warn_only thisfield f
    
    2016 2033
     
    
    2017 2034
        -- Note: we don't check for $topdir/${pkgroot} here. We rely on these
    
    2018 2035
        -- variables having been expanded already, see mungePackagePaths.
    
    2019 2036
     
    
    2020
    - | isRelative d = verror ForceFiles $
    
    2037
    + | isRelative d' = verror ForceFiles $
    
    2021 2038
                          thisfield ++ ": " ++ d ++ " is a relative path which "
    
    2022 2039
                       ++ "makes no sense (as there is nothing for it to be "
    
    2023 2040
                       ++ "relative to). You can make paths relative to the "
    
    2024 2041
                       ++ "package database itself by using ${pkgroot}."
    
    2025 2042
             -- relative paths don't make any sense; #4134
    
    2026 2043
      | otherwise = do
    
    2027
    -   there <- liftIO $ if is_dir then doesDirectoryExist d else doesFileExist d
    
    2044
    +   there <- liftIO $ if is_dir then doesDirectoryExist d' else doesFileExist d'
    
    2028 2045
        when (not there) $
    
    2029 2046
            let msg = thisfield ++ ": " ++ d ++ " doesn't exist or isn't a "
    
    2030 2047
                                             ++ if is_dir then "directory" else "file"
    
    ... ... @@ -2032,6 +2049,8 @@ checkPath url_ok is_dir warn_only thisfield d
    2032 2049
            if warn_only
    
    2033 2050
               then vwarn msg
    
    2034 2051
               else verror ForceFiles msg
    
    2052
    +  where
    
    2053
    +   d' = unsafeEncodeUtf d
    
    2035 2054
     
    
    2036 2055
     checkDep :: PackageDBStack -> UnitId -> Validate ()
    
    2037 2056
     checkDep db_stack pkgid
    
    ... ... @@ -2050,24 +2069,25 @@ checkDuplicateDepends deps
    2050 2069
       where
    
    2051 2070
            dups = [ p | (p:_:_) <- group (sort deps) ]
    
    2052 2071
     
    
    2053
    -checkHSLib :: Verbosity -> [String] -> String -> Validate ()
    
    2072
    +checkHSLib :: Verbosity -> [OsPath] -> String -> Validate ()
    
    2054 2073
     checkHSLib _verbosity dirs lib = do
    
    2055
    -  let filenames = ["lib" ++ lib ++ ".a",
    
    2056
    -                   "lib" ++ lib ++ "_p.a",
    
    2057
    -                   "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so",
    
    2058
    -                   "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so",
    
    2059
    -                   "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib",
    
    2060
    -                   "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib",
    
    2061
    -                   lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll",
    
    2062
    -                   lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll",
    
    2063
    -                   lib ++ ".bytecodelib"
    
    2064
    -                  ]
    
    2074
    +  let filenames = fmap OsPath.unsafeEncodeUtf
    
    2075
    +        [ "lib" ++ lib ++ ".a"
    
    2076
    +        , "lib" ++ lib ++ "_p.a"
    
    2077
    +        , "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so"
    
    2078
    +        , "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so"
    
    2079
    +        , "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib"
    
    2080
    +        , "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib"
    
    2081
    +        , lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll"
    
    2082
    +        , lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll"
    
    2083
    +        , lib ++ ".bytecodelib"
    
    2084
    +        ]
    
    2065 2085
       b <- liftIO $ doesFileExistOnPath filenames dirs
    
    2066 2086
       when (not b) $
    
    2067 2087
         verror ForceFiles ("cannot find any of " ++ show filenames ++
    
    2068 2088
                            " on library path")
    
    2069 2089
     
    
    2070
    -doesFileExistOnPath :: [FilePath] -> [FilePath] -> IO Bool
    
    2090
    +doesFileExistOnPath :: [OsPath] -> [OsPath] -> IO Bool
    
    2071 2091
     doesFileExistOnPath filenames paths = anyM doesFileExist fullFilenames
    
    2072 2092
       where fullFilenames = [ path </> filename
    
    2073 2093
                             | filename <- filenames
    
    ... ... @@ -2096,9 +2116,9 @@ checkModuleFile :: InstalledPackageInfo -> ModuleName -> Validate ()
    2096 2116
     checkModuleFile pkg modl =
    
    2097 2117
           -- there's no interface file for GHC.Prim
    
    2098 2118
           unless (modl == ModuleName.fromString "GHC.Prim") $ do
    
    2099
    -      let files = [ ModuleName.toFilePath modl <.> extension
    
    2100
    -                  | extension <- ["hi", "p_hi", "dyn_hi", "p_dyn_hi"] ]
    
    2101
    -      b <- liftIO $ doesFileExistOnPath files (importDirs pkg)
    
    2119
    +      let files = [ unsafeEncodeUtf (ModuleName.toFilePath modl) <.> extension
    
    2120
    +                  | extension <- fmap os ["hi", "p_hi", "dyn_hi", "p_dyn_hi"] ]
    
    2121
    +      b <- liftIO $ doesFileExistOnPath files (fmap unsafeEncodeUtf $ importDirs pkg)
    
    2102 2122
           when (not b) $
    
    2103 2123
              verror ForceFiles ("cannot find any of " ++ show files)
    
    2104 2124
     
    
    ... ... @@ -2273,19 +2293,45 @@ installSignalHandlers = do
    2273 2293
       return ()
    
    2274 2294
     #endif
    
    2275 2295
     
    
    2296
    +-- ------------------------------------------------
    
    2297
    +-- OsPath Utils
    
    2298
    +
    
    2299
    +-- | Show an 'OsPath', throwing an exception if we fail to decode it.
    
    2300
    +showOsPath :: HasCallStack => OsPath -> FilePath
    
    2301
    +showOsPath = unsafePerformIO . decodeFS
    
    2302
    +
    
    2303
    +-- | Turn a path relative to the current directory into a (normalised)
    
    2304
    +-- absolute path.
    
    2305
    +absolutePath :: OsPath -> IO OsPath
    
    2306
    +absolutePath path = return . normalise . (</> path) =<< getCurrentDirectory
    
    2307
    +
    
    2308
    +-- ------------------------------------------------
    
    2309
    +
    
    2276 2310
     catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
    
    2277 2311
     catchIO = catchException
    
    2278 2312
     
    
    2279 2313
     tryIO :: IO a -> IO (Either Exception.IOException a)
    
    2280 2314
     tryIO = Exception.try
    
    2281 2315
     
    
    2282
    --- removeFileSave doesn't throw an exceptions, if the file is already deleted
    
    2283
    -removeFileSafe :: FilePath -> IO ()
    
    2316
    +-----------------------------------------
    
    2317
    +-- Adapted from ghc/compiler/utils/Panic
    
    2318
    +
    
    2319
    +-- | 'removeFileSave' doesn't throw an exceptions, if the file is already deleted
    
    2320
    +removeFileSafe :: OsPath -> IO ()
    
    2284 2321
     removeFileSafe fn =
    
    2285 2322
       removeFile fn `catchIO` \ e ->
    
    2286 2323
         when (not $ isDoesNotExistError e) $ ioError e
    
    2287 2324
     
    
    2288
    --- | Turn a path relative to the current directory into a (normalised)
    
    2289
    --- absolute path.
    
    2290
    -absolutePath :: FilePath -> IO FilePath
    
    2291
    -absolutePath path = return . normalise . (</> path) =<< getCurrentDirectory
    2325
    +-- | Read a file using UTF-8 encoding
    
    2326
    +--
    
    2327
    +-- Taken from https://github.com/haskell/cabal/blob/cea1d8ff1a80df3c3b3148d1556bd3edf656da93/Cabal-syntax/src/Distribution/Utils/Generic.hs#L326
    
    2328
    +-- and adapted to 'OsPath'.
    
    2329
    +writeUtf8File :: OsPath -> String -> IO ()
    
    2330
    +writeUtf8File file contents = writeFileAtomic file (toUTF8LBS contents)
    
    2331
    +
    
    2332
    +-- | Read a file and interpret its content to be UTF-8 encoded.
    
    2333
    +--
    
    2334
    +-- Taken from https://github.com/haskell/cabal/blob/cea1d8ff1a80df3c3b3148d1556bd3edf656da93/Cabal-syntax/src/Distribution/Utils/Generic.hs#L309
    
    2335
    +-- and adapted to 'OsPath'.
    
    2336
    +readUtf8File :: OsPath -> IO String
    
    2337
    +readUtf8File file = (ignoreBOM . fromUTF8LBS) <$> FileIO.readFile file

  • utils/ghc-pkg/ghc-pkg.cabal.in
    ... ... @@ -25,6 +25,7 @@ Executable ghc-pkg
    25 25
                        process    >= 1   && < 1.7,
    
    26 26
                        containers,
    
    27 27
                        filepath,
    
    28
    +                   file-io,
    
    28 29
                        Cabal,
    
    29 30
                        Cabal-syntax,
    
    30 31
                        binary,