Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

12 changed files:

Changes:

  • changelog.d/ghc-api-interactive-ids
    1
    +section: ghc-lib
    
    2
    +synopsis: The GHCi evaluation API now returns ``Id``\s and ``TyThing``\s rather than ``Name``\s
    
    3
    +issues: #28052
    
    4
    +mrs: !16883
    
    5
    +
    
    6
    +description: {
    
    7
    +The results of interactive evaluation are now returned directly, rather than as
    
    8
    +``Name``\s that had to be looked up again in the interactive context:
    
    9
    +
    
    10
    +- ``ExecComplete``'s ``execResult`` and ``ExecBreak``'s ``breakNames`` now hold ``[Id]``.
    
    11
    +- ``runDecls``, ``runDeclsWithLocation`` and ``runParsedDecls`` now return ``[TyThing]`` rather than ``[Name]``.
    
    12
    +- ``rttiEnvironment`` now returns a Subst with the inferred types.
    
    13
    +
    
    14
    +The returned ``Id``\s carry the types refined by runtime type inference.
    
    15
    +}

  • compiler/GHC/Runtime/Context.hs
    ... ... @@ -6,6 +6,8 @@ module GHC.Runtime.Context
    6 6
        , extendInteractiveContextWithIds
    
    7 7
        , setInteractivePrintName
    
    8 8
        , substInteractiveContext
    
    9
    +   , substInteractiveTyThing
    
    10
    +   , substInteractiveId
    
    9 11
        , replaceImportEnv
    
    10 12
        , icReaderEnv
    
    11 13
        , icExtendGblRdrEnv
    
    ... ... @@ -496,15 +498,18 @@ icExtendGblRdrEnv drop_only_qualified env tythings
    496 498
     substInteractiveContext :: InteractiveContext -> Subst -> InteractiveContext
    
    497 499
     substInteractiveContext ictxt@InteractiveContext{ ic_tythings = tts } subst
    
    498 500
       | isEmptyTCvSubst subst = ictxt
    
    499
    -  | otherwise             = ictxt { ic_tythings = map subst_ty tts }
    
    500
    -  where
    
    501
    -    subst_ty (AnId id)
    
    502
    -      = AnId $ updateIdTypeAndMult (substTyAddInScope subst) id
    
    503
    -      -- Variables in the interactive context *can* mention free type variables
    
    504
    -      -- because of the runtime debugger. Otherwise you'd expect all
    
    505
    -      -- variables bound in the interactive context to be closed.
    
    506
    -    subst_ty tt
    
    507
    -      = tt
    
    501
    +  | otherwise             = ictxt { ic_tythings = map (substInteractiveTyThing subst) tts }
    
    502
    +
    
    503
    +substInteractiveTyThing :: Subst -> TyThing -> TyThing
    
    504
    +substInteractiveTyThing subst (AnId id) = AnId $ substInteractiveId subst id
    
    505
    +substInteractiveTyThing _ tt            = tt
    
    506
    +
    
    507
    +substInteractiveId :: Subst -> Id -> Id
    
    508
    +substInteractiveId subst id =
    
    509
    +  -- Variables in the interactive context *can* mention free type variables
    
    510
    +  -- because of the runtime debugger. Otherwise you'd expect all
    
    511
    +  -- variables bound in the interactive context to be closed.
    
    512
    +  updateIdTypeAndMult (substTyAddInScope subst) id
    
    508 513
     
    
    509 514
     instance Outputable InteractiveImport where
    
    510 515
       ppr (IIModule m) = char '*' <> ppr m
    

  • compiler/GHC/Runtime/Debugger.hs
    ... ... @@ -121,8 +121,7 @@ pprintClosureCommand bindThings force str = do
    121 121
          --  Then, we extract a substitution,
    
    122 122
          --  mapping the old tyvars to the reconstructed types.
    
    123 123
            let reconstructed_type = termType term
    
    124
    -       hsc_env <- getSession
    
    125
    -       case (improveRTTIType hsc_env id_ty' reconstructed_type) of
    
    124
    +       case improveRTTIType id_ty' reconstructed_type of
    
    126 125
              Nothing     -> return (subst, term')
    
    127 126
              Just subst' -> do { logger <- getLogger
    
    128 127
                                ; liftIO $
    

  • compiler/GHC/Runtime/Eval.hs
    ... ... @@ -131,7 +131,7 @@ import GHC.ByteCode.Breakpoints
    131 131
     import Control.Monad
    
    132 132
     import Data.Dynamic
    
    133 133
     import Data.IntMap (IntMap)
    
    134
    -import Data.List (find,intercalate)
    
    134
    +import Data.List (intercalate)
    
    135 135
     import Data.List.NonEmpty (NonEmpty)
    
    136 136
     import Unsafe.Coerce ( unsafeCoerce )
    
    137 137
     import qualified GHC.Unit.Home.Graph as HUG
    
    ... ... @@ -241,12 +241,12 @@ execStmt' stmt stmt_text ExecOptions{..} = do
    241 241
             handleRunStatus execSingleStep stmt_text bindings ids
    
    242 242
                             status (emptyHistory size)
    
    243 243
     
    
    244
    -runDecls :: GhcMonad m => String -> m [Name]
    
    244
    +runDecls :: GhcMonad m => String -> m [TyThing]
    
    245 245
     runDecls = runDeclsWithLocation "<interactive>" 1
    
    246 246
     
    
    247 247
     -- | Run some declarations and return any user-visible names that were brought
    
    248 248
     -- into scope.
    
    249
    -runDeclsWithLocation :: GhcMonad m => String -> Int -> String -> m [Name]
    
    249
    +runDeclsWithLocation :: GhcMonad m => String -> Int -> String -> m [TyThing]
    
    250 250
     runDeclsWithLocation source line_num input = do
    
    251 251
         hsc_env <- getSession
    
    252 252
         decls <- liftIO (hscParseDeclsWithLocation hsc_env source line_num input)
    
    ... ... @@ -255,18 +255,18 @@ runDeclsWithLocation source line_num input = do
    255 255
     -- | Like `runDeclsWithLocation`, but takes parsed declarations as argument.
    
    256 256
     -- Useful when doing preprocessing on the AST before execution, e.g. in GHCi
    
    257 257
     -- (see GHCi.UI.runStmt).
    
    258
    -runParsedDecls :: GhcMonad m => [LHsDecl GhcPs] -> m [Name]
    
    258
    +runParsedDecls :: GhcMonad m => [LHsDecl GhcPs] -> m [TyThing]
    
    259 259
     runParsedDecls decls = do
    
    260
    -    hsc_env <- getSession
    
    261
    -    (tyThings, ic) <- liftIO (hscParsedDecls hsc_env decls)
    
    262
    -
    
    260
    +    hsc_env        <- getSession
    
    261
    +    (tyThings, ic) <- liftIO $ hscParsedDecls hsc_env decls
    
    263 262
         setSession $ hsc_env { hsc_IC = ic }
    
    264 263
         hsc_env <- getSession
    
    265
    -    hsc_env' <- liftIO $ rttiEnvironment hsc_env
    
    264
    +    (hsc_env', subst) <- liftIO $ rttiEnvironment hsc_env
    
    266 265
         setSession hsc_env'
    
    267
    -    return $ filter (not . isDerivedOccName . nameOccName)
    
    266
    +    return $ map (substInteractiveTyThing subst)
    
    267
    +           $ filter (not . isDerivedOccName . nameOccName . getName)
    
    268 268
                  -- For this filter, see Note [What to show to users]
    
    269
    -           $ map getName tyThings
    
    269
    +           $ tyThings
    
    270 270
     
    
    271 271
     {- Note [What to show to users]
    
    272 272
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -310,9 +310,10 @@ handleRunStatus step expr bindings final_ids status history0 = do
    310 310
             final_ic = extendInteractiveContextWithIds (hsc_IC hsc_env) final_ids
    
    311 311
             final_names = map getName final_ids
    
    312 312
           liftIO $ Loader.extendLoadedEnv interp modifyHomePackageBytecodeState (zip final_names hvals)
    
    313
    -      hsc_env' <- liftIO $ rttiEnvironment hsc_env{hsc_IC=final_ic}
    
    313
    +      (hsc_env', subst) <- liftIO $ rttiEnvironment hsc_env{hsc_IC=final_ic}
    
    314
    +      let improved_final_ids = map (substInteractiveId subst) final_ids
    
    314 315
           setSession hsc_env'
    
    315
    -      return (ExecComplete (Right final_names) allocs)
    
    316
    +      return (ExecComplete (Right improved_final_ids) allocs)
    
    316 317
     
    
    317 318
         -- Completed with an exception
    
    318 319
         EvalComplete alloc (EvalException e) ->
    
    ... ... @@ -323,7 +324,7 @@ handleRunStatus step expr bindings final_ids status history0 = do
    323 324
           resume_ctxt_fhv <- liftIO $ mkFinalizedHValue interp resume_ctxt
    
    324 325
           apStack_fhv     <- liftIO $ mkFinalizedHValue interp apStack_ref
    
    325 326
           let span = mkGeneralSrcSpan (fsLit "<unknown>")
    
    326
    -      (hsc_env1, names) <- liftIO $
    
    327
    +      (hsc_env1, break_ids) <- liftIO $
    
    327 328
             bindLocalsAtBreakpoint hsc_env apStack_fhv span Nothing
    
    328 329
           let
    
    329 330
             resume = Resume
    
    ... ... @@ -342,7 +343,7 @@ handleRunStatus step expr bindings final_ids status history0 = do
    342 343
             hsc_env2 = pushResume hsc_env1 resume
    
    343 344
     
    
    344 345
           setSession hsc_env2
    
    345
    -      return (ExecBreak names Nothing)
    
    346
    +      return (ExecBreak break_ids Nothing)
    
    346 347
     
    
    347 348
         -- EvalBreak (Just ...) case: the interpreter stopped at a breakpoint
    
    348 349
         --
    
    ... ... @@ -370,7 +371,7 @@ handleRunStatus step expr bindings final_ids status history0 = do
    370 371
             -- This function only returns control to ghci with 'ExecBreak' when it is really meant to break.
    
    371 372
             -- Specifically, for :steplocal or :stepmodule, don't return control
    
    372 373
             -- and simply resume execution from here until we hit a breakpoint we do want to stop at.
    
    373
    -        (hsc_env1, names) <- liftIO $
    
    374
    +        (hsc_env1, break_ids) <- liftIO $
    
    374 375
               bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi)
    
    375 376
             let
    
    376 377
               resume = Resume
    
    ... ... @@ -388,7 +389,7 @@ handleRunStatus step expr bindings final_ids status history0 = do
    388 389
                 }
    
    389 390
               hsc_env2 = pushResume hsc_env1 resume
    
    390 391
             setSession hsc_env2
    
    391
    -        return (ExecBreak names (Just ibi))
    
    392
    +        return (ExecBreak break_ids (Just ibi))
    
    392 393
           else do
    
    393 394
             -- resume with the same step type
    
    394 395
             let eval_opts = initEvalOpts dflags (enableGhcStepMode step)
    
    ... ... @@ -491,13 +492,13 @@ getBreakArray interp InternalBreakpointId{ibi_info_mod} imbs = do
    491 492
               ( ld_st'
    
    492 493
               , ba
    
    493 494
               )
    
    494
    -back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
    
    495
    +back :: GhcMonad m => Int -> m ([Id], Int, SrcSpan)
    
    495 496
     back n = moveHist (+n)
    
    496 497
     
    
    497
    -forward :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
    
    498
    +forward :: GhcMonad m => Int -> m ([Id], Int, SrcSpan)
    
    498 499
     forward n = moveHist (subtract n)
    
    499 500
     
    
    500
    -moveHist :: GhcMonad m => (Int -> Int) -> m ([Name], Int, SrcSpan)
    
    501
    +moveHist :: GhcMonad m => (Int -> Int) -> m ([Id], Int, SrcSpan)
    
    501 502
     moveHist fn = do
    
    502 503
       hsc_env <- getSession
    
    503 504
       case ic_resume (hsc_IC hsc_env) of
    
    ... ... @@ -521,7 +522,7 @@ moveHist fn = do
    521 522
                             let hug = hsc_HUG hsc_env
    
    522 523
                             brks <- readIModBreaks hug ibi
    
    523 524
                             getBreakLoc (readIModModBreaks hug) ibi brks
    
    524
    -            (hsc_env1, names) <-
    
    525
    +            (hsc_env1, final_ids) <-
    
    525 526
                   liftIO $ bindLocalsAtBreakpoint hsc_env apStack span mb_info
    
    526 527
                 let ic = hsc_IC hsc_env1
    
    527 528
                     r' = r { resumeHistoryIx = new_ix }
    
    ... ... @@ -529,7 +530,7 @@ moveHist fn = do
    529 530
     
    
    530 531
                 setSession hsc_env1{ hsc_IC = ic' }
    
    531 532
     
    
    532
    -            return (names, new_ix, span)
    
    533
    +            return (final_ids, new_ix, span)
    
    533 534
     
    
    534 535
             -- careful: we want apStack to be the AP_STACK itself, not a thunk
    
    535 536
             -- around it, hence the cases are carefully constructed below to
    
    ... ... @@ -555,7 +556,7 @@ bindLocalsAtBreakpoint
    555 556
             -> ForeignHValue
    
    556 557
             -> SrcSpan
    
    557 558
             -> Maybe InternalBreakpointId
    
    558
    -        -> IO (HscEnv, [Name])
    
    559
    +        -> IO (HscEnv, [Id])
    
    559 560
     
    
    560 561
     -- Nothing case: we stopped when an exception was raised, not at a
    
    561 562
     -- breakpoint.  We have no location information or local variables to
    
    ... ... @@ -575,7 +576,7 @@ bindLocalsAtBreakpoint hsc_env apStack span Nothing = do
    575 576
            interp = hscInterp hsc_env
    
    576 577
        --
    
    577 578
        Loader.extendLoadedEnv interp modifyHomePackageBytecodeState [(exn_name, apStack)]
    
    578
    -   return (hsc_env{ hsc_IC = ictxt1 }, [exn_name])
    
    579
    +   return (hsc_env{ hsc_IC = ictxt1 }, [exn_id])
    
    579 580
     
    
    580 581
     -- Just case: we stopped at a breakpoint, we have information about the location
    
    581 582
     -- of the breakpoint and the free variables of the expression.
    
    ... ... @@ -635,8 +636,9 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
    635 636
        let fhvs = catMaybes mb_hValues
    
    636 637
        Loader.extendLoadedEnv interp modifyHomePackageBytecodeState (zip names fhvs)
    
    637 638
        when result_ok $ Loader.extendLoadedEnv interp modifyHomePackageBytecodeState [(result_name, apStack_fhv)]
    
    638
    -   hsc_env1 <- rttiEnvironment hsc_env{ hsc_IC = ictxt1 }
    
    639
    -   return (hsc_env1, if result_ok then result_name:names else names)
    
    639
    +   (hsc_env1, subst) <- rttiEnvironment hsc_env{ hsc_IC = ictxt1 }
    
    640
    +   let improved_final_ids = map (substInteractiveId subst) final_ids
    
    641
    +   return (hsc_env1, improved_final_ids)
    
    640 642
       where
    
    641 643
             -- We need a fresh Unique for each Id we bind, because the linker
    
    642 644
             -- state is single-threaded and otherwise we'd spam old bindings
    
    ... ... @@ -676,34 +678,33 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
    676 678
            joinOccs = zipWithEqual joinOcc
    
    677 679
            joinOcc mbV oc = (\(a,b) c -> (a,b,c)) <$> mbV <*> pure oc
    
    678 680
     
    
    679
    -rttiEnvironment :: HscEnv -> IO HscEnv
    
    681
    +rttiEnvironment :: HscEnv -> IO (HscEnv, Subst)
    
    680 682
     rttiEnvironment hsc_env@HscEnv{hsc_IC=ic} = do
    
    681 683
        let tmp_ids = [id | AnId id <- ic_tythings ic]
    
    682 684
            incompletelyTypedIds =
    
    683 685
                [id | id <- tmp_ids
    
    684 686
                    , not $ noSkolems id
    
    685 687
                    , (occNameFS.nameOccName.idName) id /= result_fs]
    
    686
    -   foldM improveTypes hsc_env (map idName incompletelyTypedIds)
    
    688
    +   foldM improveTypes (hsc_env, emptySubst) incompletelyTypedIds
    
    687 689
         where
    
    688 690
          noSkolems = noFreeVarsOfType . idType
    
    689
    -     improveTypes hsc_env@HscEnv{hsc_IC=ic} name = do
    
    690
    -      let tmp_ids = [id | AnId id <- ic_tythings ic]
    
    691
    -          id = expectJust $ find (\i -> idName i == name) tmp_ids
    
    691
    +     improveTypes (hsc_env@HscEnv{hsc_IC=ic}, last_subst) id0 = do
    
    692
    +      let id = substInteractiveId last_subst id0
    
    692 693
           if noSkolems id
    
    693
    -         then return hsc_env
    
    694
    +         then return (hsc_env, last_subst)
    
    694 695
              else do
    
    695 696
                mb_new_ty <- reconstructType hsc_env 10 id
    
    696 697
                let old_ty = idType id
    
    697 698
                case mb_new_ty of
    
    698
    -             Nothing -> return hsc_env
    
    699
    +             Nothing -> return (hsc_env, last_subst)
    
    699 700
                  Just new_ty -> do
    
    700
    -              case improveRTTIType hsc_env old_ty new_ty of
    
    701
    +              case improveRTTIType old_ty new_ty of
    
    701 702
                    Nothing -> warnPprTrace True (":print failed to calculate the "
    
    702 703
                                                  ++ "improvement for a type")
    
    703 704
                                   (vcat [ text "id" <+> ppr id
    
    704 705
                                         , text "old_ty" <+> debugPprType old_ty
    
    705 706
                                         , text "new_ty" <+> debugPprType new_ty ]) $
    
    706
    -                          return hsc_env
    
    707
    +                          return (hsc_env, last_subst)
    
    707 708
                    Just subst -> do
    
    708 709
                      let logger = hsc_logger hsc_env
    
    709 710
                      putDumpFileMaybe logger Opt_D_dump_rtti "RTTI"
    
    ... ... @@ -712,7 +713,7 @@ rttiEnvironment hsc_env@HscEnv{hsc_IC=ic} = do
    712 713
                               ppr subst])
    
    713 714
     
    
    714 715
                      let ic' = substInteractiveContext ic subst
    
    715
    -                 return hsc_env{hsc_IC=ic'}
    
    716
    +                 return (hsc_env{hsc_IC=ic'}, subst `composeTCvSubst` last_subst)
    
    716 717
     
    
    717 718
     pushResume :: HscEnv -> Resume -> HscEnv
    
    718 719
     pushResume hsc_env resume = hsc_env { hsc_IC = ictxt1 }
    

  • compiler/GHC/Runtime/Eval/Types.hs
    ... ... @@ -19,7 +19,6 @@ import GHCi.RemoteTypes
    19 19
     import GHCi.Message (EvalExpr, ResumeContext)
    
    20 20
     import GHC.ByteCode.Types (InternalBreakpointId(..))
    
    21 21
     import GHC.Types.Id
    
    22
    -import GHC.Types.Name
    
    23 22
     import GHC.Types.TyThing
    
    24 23
     import GHC.Types.Name.Reader
    
    25 24
     import GHC.Types.SrcLoc
    
    ... ... @@ -150,7 +149,7 @@ data ExecResult
    150 149
       -- | Execution is complete with either an exception or the list of
    
    151 150
       -- user-visible names that were brought into scope.
    
    152 151
       = ExecComplete
    
    153
    -       { execResult :: Either SomeException [Name]
    
    152
    +       { execResult :: Either SomeException [Id]
    
    154 153
            , execAllocation :: Word64
    
    155 154
            }
    
    156 155
     
    
    ... ... @@ -161,7 +160,7 @@ data ExecResult
    161 160
         -- subsequently deciding whether to really stop here.
    
    162 161
         -- `ExecBreak` always means GHCi breaks.
    
    163 162
         | ExecBreak
    
    164
    -       { breakNames   :: [Name]
    
    163
    +       { breakNames   :: [Id]
    
    165 164
            , breakPointId :: Maybe InternalBreakpointId
    
    166 165
            }
    
    167 166
     
    

  • compiler/GHC/Runtime/Heap/Inspect.hs
    ... ... @@ -1163,8 +1163,8 @@ findPtrTyss i tys = foldM step (i, []) tys
    1163 1163
     -- improveType <base_type> <rtti_type>
    
    1164 1164
     -- The types can contain skolem type variables, which need to be treated as normal vars.
    
    1165 1165
     -- In particular, we want them to unify with things.
    
    1166
    -improveRTTIType :: HscEnv -> RttiType -> RttiType -> Maybe Subst
    
    1167
    -improveRTTIType _ base_ty new_ty = U.tcUnifyDebugger base_ty new_ty
    
    1166
    +improveRTTIType :: RttiType -> RttiType -> Maybe Subst
    
    1167
    +improveRTTIType base_ty new_ty = U.tcUnifyDebugger base_ty new_ty
    
    1168 1168
     
    
    1169 1169
     getDataConArgTys :: DataCon -> Type -> TR [Type]
    
    1170 1170
     -- Given the result type ty of a constructor application (D a b c :: ty)
    

  • ghc/GHCi/UI.hs
    ... ... @@ -1495,7 +1495,7 @@ runOneCommand eh gCmd = do
    1495 1495
     
    
    1496 1496
         -- runStmt wrapper for temporarily overridden line-number
    
    1497 1497
         runStmtWithLineNum :: Int -> String -> SingleStep
    
    1498
    -                       -> GHCi (Maybe GHC.ExecResult)
    
    1498
    +                       -> GHCi (Maybe RunResult)
    
    1499 1499
         runStmtWithLineNum lnum stmt step = do
    
    1500 1500
             st0 <- getGHCiState
    
    1501 1501
             setGHCiState st0 { line_number = lnum }
    
    ... ... @@ -1560,7 +1560,7 @@ enqueueCommands cmds = do
    1560 1560
     
    
    1561 1561
     -- | Entry point to execute some haskell code from user.
    
    1562 1562
     -- The return value True indicates success, as in `runOneCommand`.
    
    1563
    -runStmt :: GhciMonad m => String -> SingleStep -> m (Maybe GHC.ExecResult)
    
    1563
    +runStmt :: GhciMonad m => String -> SingleStep -> m (Maybe RunResult)
    
    1564 1564
     runStmt input step = do
    
    1565 1565
       dflags <- GHC.getInteractiveDynFlags
    
    1566 1566
       let pflags = initParserOpts dflags
    
    ... ... @@ -1582,7 +1582,7 @@ runStmt input step = do
    1582 1582
              case mb_stmt of
    
    1583 1583
                Nothing ->
    
    1584 1584
                  -- empty statement / comment
    
    1585
    -             return (Just exec_complete)
    
    1585
    +             return (Just (RunDeclsResult []))
    
    1586 1586
                Just stmt ->
    
    1587 1587
                  run_stmt stmt
    
    1588 1588
     
    
    ... ... @@ -1605,8 +1605,6 @@ runStmt input step = do
    1605 1605
                  run_imports imports
    
    1606 1606
                  run_decls decls
    
    1607 1607
       where
    
    1608
    -    exec_complete = GHC.ExecComplete (Right []) 0
    
    1609
    -
    
    1610 1608
         run_imports imports = mapM_ (addImportToContext . unLoc) imports
    
    1611 1609
     
    
    1612 1610
         set_pragmas pflags sec supported =
    
    ... ... @@ -1615,12 +1613,12 @@ runStmt input step = do
    1615 1613
               opts = unLoc <$> loc_opts
    
    1616 1614
           in setOptions opts
    
    1617 1615
     
    
    1618
    -    run_stmt :: GhciMonad m => GhciLStmt GhcPs -> m (Maybe GHC.ExecResult)
    
    1616
    +    run_stmt :: GhciMonad m => GhciLStmt GhcPs -> m (Maybe RunResult)
    
    1619 1617
         run_stmt stmt = do
    
    1620 1618
                m_result <- GhciMonad.runStmt stmt input step
    
    1621 1619
                case m_result of
    
    1622 1620
                    Nothing     -> return Nothing
    
    1623
    -               Just result -> Just <$> afterRunStmt step result
    
    1621
    +               Just result -> Just <$> afterRunStmt step (RunStmtResult result)
    
    1624 1622
     
    
    1625 1623
         -- `x = y` (a declaration) should be treated as `let x = y` (a statement).
    
    1626 1624
         -- The reason is because GHCi wasn't designed to support `x = y`, but then
    
    ... ... @@ -1636,7 +1634,7 @@ runStmt input step = do
    1636 1634
         --
    
    1637 1635
         -- Instead of dealing with all these problems individually here we fix this
    
    1638 1636
         -- mess by just treating `x = y` as `let x = y`.
    
    1639
    -    run_decls :: GhciMonad m => [LHsDecl GhcPs] -> m (Maybe GHC.ExecResult)
    
    1637
    +    run_decls :: GhciMonad m => [LHsDecl GhcPs] -> m (Maybe RunResult)
    
    1640 1638
         -- Only turn `FunBind` and `VarBind` into statements, other bindings
    
    1641 1639
         -- (e.g. `PatBind`) need to stay as decls.
    
    1642 1640
         run_decls [L l (ValD _ bind@FunBind{})] = run_stmt (mk_stmt (locA l) bind)
    
    ... ... @@ -1651,8 +1649,8 @@ runStmt input step = do
    1651 1649
           -- a file, otherwise the read buffer can't be flushed).
    
    1652 1650
           _ <- liftIO $ tryIO $ hFlushAll stdin
    
    1653 1651
           m_result <- GhciMonad.runDecls' decls
    
    1654
    -      forM m_result $ \result ->
    
    1655
    -        afterRunStmt step (GHC.ExecComplete (Right result) 0)
    
    1652
    +      forM m_result $ \result -> do
    
    1653
    +        afterRunStmt step (RunDeclsResult result)
    
    1656 1654
     
    
    1657 1655
         mk_stmt :: SrcSpan -> HsBind GhcPs -> GhciLStmt GhcPs
    
    1658 1656
         mk_stmt loc bind =
    
    ... ... @@ -1668,32 +1666,39 @@ runStmt input step = do
    1668 1666
           where
    
    1669 1667
             modStr = moduleNameString $ moduleName $ icInteractiveModule $ ic
    
    1670 1668
     
    
    1669
    +data RunResult
    
    1670
    +  = RunStmtResult GHC.ExecResult
    
    1671
    +  | RunDeclsResult [TyThing]
    
    1672
    +
    
    1671 1673
     -- | Clean up the GHCi environment after a statement has run
    
    1672 1674
     afterRunStmt :: GhciMonad m => SingleStep {-^ Type of step we took just before -}
    
    1673
    -             -> GHC.ExecResult -> m GHC.ExecResult
    
    1675
    +             -> RunResult -> m RunResult
    
    1674 1676
     afterRunStmt step run_result = do
    
    1675 1677
       resumes <- GHC.getResumeContext
    
    1676 1678
       case run_result of
    
    1677
    -     GHC.ExecComplete{..} ->
    
    1678
    -       case execResult of
    
    1679
    -          Left ex -> liftIO $ Exception.throwIO ex
    
    1680
    -          Right names -> do
    
    1681
    -            show_types <- isOptionSet ShowType
    
    1682
    -            when show_types $ printTypeOfNames names
    
    1683
    -     GHC.ExecBreak names mb_info
    
    1684
    -         | first_resume : _ <- resumes
    
    1685
    -         -> do mb_id_loc <- toBreakIdAndLocation mb_info
    
    1686
    -               let bCmd = maybe "" ( \(_,l) -> onBreakCmd l ) mb_id_loc
    
    1687
    -               if (null bCmd)
    
    1688
    -                 then printStoppedAtBreakInfo first_resume names
    
    1689
    -                 else enqueueCommands [bCmd]
    
    1690
    -               -- run the command set with ":set stop <cmd>"
    
    1691
    -               st <- getGHCiState
    
    1692
    -               enqueueCommands [stop st]
    
    1693
    -               return ()
    
    1694
    -
    
    1695
    -         | otherwise -> resume step Nothing >>=
    
    1696
    -                        afterRunStmt step >> return ()
    
    1679
    +    RunDeclsResult things -> do
    
    1680
    +      show_types <- isOptionSet ShowType
    
    1681
    +      when show_types $ printTypeOfThings things
    
    1682
    +    RunStmtResult GHC.ExecComplete{..} ->
    
    1683
    +      case execResult of
    
    1684
    +        Left ex -> liftIO $ Exception.throwIO ex
    
    1685
    +        Right ids -> do
    
    1686
    +          show_types <- isOptionSet ShowType
    
    1687
    +          when show_types $ printTypeOfIds ids
    
    1688
    +    RunStmtResult (GHC.ExecBreak ids mb_info)
    
    1689
    +        | first_resume : _ <- resumes
    
    1690
    +        -> do mb_id_loc <- toBreakIdAndLocation mb_info
    
    1691
    +              let bCmd = maybe "" ( \(_,l) -> onBreakCmd l ) mb_id_loc
    
    1692
    +              if (null bCmd)
    
    1693
    +                then printStoppedAtBreakInfo first_resume ids
    
    1694
    +                else enqueueCommands [bCmd]
    
    1695
    +              -- run the command set with ":set stop <cmd>"
    
    1696
    +              st <- getGHCiState
    
    1697
    +              enqueueCommands [stop st]
    
    1698
    +              return ()
    
    1699
    +
    
    1700
    +        | otherwise -> resume step Nothing >>=
    
    1701
    +                       afterRunStmt step . RunStmtResult >> return ()
    
    1697 1702
     
    
    1698 1703
       flushInterpBuffers
    
    1699 1704
       withSignalHandlers $ do
    
    ... ... @@ -1702,16 +1707,19 @@ afterRunStmt step run_result = do
    1702 1707
     
    
    1703 1708
       return run_result
    
    1704 1709
     
    
    1705
    -runSuccess :: Maybe GHC.ExecResult -> Bool
    
    1710
    +runSuccess :: Maybe RunResult -> Bool
    
    1706 1711
     runSuccess run_result
    
    1707
    -  | Just (GHC.ExecComplete { execResult = Right _ }) <- run_result = True
    
    1712
    +  | Just (RunDeclsResult _) <- run_result = True
    
    1713
    +  | Just (RunStmtResult GHC.ExecComplete { execResult = Right _ })
    
    1714
    +                            <- run_result = True
    
    1708 1715
       | otherwise = False
    
    1709 1716
     
    
    1710
    -runAllocs :: Maybe GHC.ExecResult -> Maybe Integer
    
    1717
    +runAllocs :: Maybe RunResult -> Maybe Integer
    
    1711 1718
     runAllocs m = do
    
    1712 1719
       res <- m
    
    1713 1720
       case res of
    
    1714
    -    GHC.ExecComplete{..} -> Just (fromIntegral execAllocation)
    
    1721
    +    RunDeclsResult _ -> Just 0
    
    1722
    +    RunStmtResult GHC.ExecComplete{..} -> Just (fromIntegral execAllocation)
    
    1715 1723
         _ -> Nothing
    
    1716 1724
     
    
    1717 1725
     toBreakIdAndLocation :: GhciMonad m
    
    ... ... @@ -1725,30 +1733,23 @@ toBreakIdAndLocation (Just inf) = do
    1725 1733
       return $ listToMaybe [ id_loc | id_loc@(_,loc) <- IntMap.assocs (breaks st),
    
    1726 1734
                                       breakId loc == bi ]
    
    1727 1735
     
    
    1728
    -printStoppedAtBreakInfo :: GHC.GhcMonad m => Resume -> [Name] -> m ()
    
    1729
    -printStoppedAtBreakInfo res names = do
    
    1736
    +printStoppedAtBreakInfo :: GHC.GhcMonad m => Resume -> [GHC.Id] -> m ()
    
    1737
    +printStoppedAtBreakInfo res ids = do
    
    1730 1738
       printForUser =<< pprStopped res
    
    1731
    -  --  printTypeOfNames session names
    
    1732
    -  let namesSorted = sortBy compareNames names
    
    1733
    -  tythings <- catMaybes `liftM` mapM GHC.lookupName namesSorted
    
    1734
    -  docs <- mapM pprTypeAndContents [i | AnId i <- tythings]
    
    1739
    +  let idsSorted = sortBy (compareNames `on` getName) ids
    
    1740
    +  docs <- mapM pprTypeAndContents idsSorted
    
    1735 1741
       printForUserPartWay $ vcat docs
    
    1736 1742
     
    
    1737
    -printTypeOfNames :: GHC.GhcMonad m => [Name] -> m ()
    
    1738
    -printTypeOfNames names
    
    1739
    - = mapM_ (printTypeOfName ) $ sortBy compareNames names
    
    1743
    +printTypeOfIds :: GHC.GhcMonad m => [GHC.Id] -> m ()
    
    1744
    +printTypeOfIds = printTypeOfThings . map AnId
    
    1745
    +
    
    1746
    +printTypeOfThings :: GHC.GhcMonad m => [GHC.TyThing] -> m ()
    
    1747
    +printTypeOfThings things
    
    1748
    + = mapM_ printTyThing $ sortBy (compareNames `on` getName) things
    
    1740 1749
     
    
    1741 1750
     compareNames :: Name -> Name -> Ordering
    
    1742 1751
     compareNames = on compare getOccString S.<> on SrcLoc.leftmost_smallest getSrcSpan
    
    1743 1752
     
    
    1744
    -printTypeOfName :: GHC.GhcMonad m => Name -> m ()
    
    1745
    -printTypeOfName n
    
    1746
    -   = do maybe_tything <- GHC.lookupName n
    
    1747
    -        case maybe_tything of
    
    1748
    -            Nothing    -> return ()
    
    1749
    -            Just thing -> printTyThing thing
    
    1750
    -
    
    1751
    -
    
    1752 1753
     data MaybeCommand = GotCommand Command | BadCommand | NoLastCommand
    
    1753 1754
     
    
    1754 1755
     -- | Entry point for execution a ':<command>' input from user
    
    ... ... @@ -4400,7 +4401,7 @@ doContinue step = doContinue' step Nothing
    4400 4401
     doContinue' :: GhciMonad m => SingleStep -> Maybe Int -> m ()
    
    4401 4402
     doContinue' step mbCnt= do
    
    4402 4403
       runResult <- resume step mbCnt
    
    4403
    -  _ <- afterRunStmt step runResult
    
    4404
    +  _ <- afterRunStmt step (RunStmtResult runResult)
    
    4404 4405
       return ()
    
    4405 4406
     
    
    4406 4407
     abandonCmd :: GhciMonad m => String -> m ()
    
    ... ... @@ -4551,9 +4552,9 @@ backCmd arg
    4551 4552
       | otherwise       = liftIO $ putStrLn "Syntax:  :back [num]"
    
    4552 4553
       where
    
    4553 4554
       back num = withSandboxOnly ":back" $ do
    
    4554
    -      (names, _, pan) <- GHC.back num
    
    4555
    +      (ids, _, pan) <- GHC.back num
    
    4555 4556
           printForUser $ text "Logged breakpoint at" <+> ppr pan
    
    4556
    -      printTypeOfNames names
    
    4557
    +      printTypeOfIds ids
    
    4557 4558
            -- run the command set with ":set stop <cmd>"
    
    4558 4559
           st <- getGHCiState
    
    4559 4560
           enqueueCommands [stop st]
    
    ... ... @@ -4565,11 +4566,11 @@ forwardCmd arg
    4565 4566
       | otherwise       = liftIO $ putStrLn "Syntax:  :forward [num]"
    
    4566 4567
       where
    
    4567 4568
       forward num = withSandboxOnly ":forward" $ do
    
    4568
    -      (names, ix, pan) <- GHC.forward num
    
    4569
    +      (ids, ix, pan) <- GHC.forward num
    
    4569 4570
           printForUser $ (if (ix == 0)
    
    4570 4571
                             then text "Stopped at"
    
    4571 4572
                             else text "Logged breakpoint at") <+> ppr pan
    
    4572
    -      printTypeOfNames names
    
    4573
    +      printTypeOfIds ids
    
    4573 4574
            -- run the command set with ":set stop <cmd>"
    
    4574 4575
           st <- getGHCiState
    
    4575 4576
           enqueueCommands [stop st]
    

  • ghc/GHCi/UI/Monad.hs
    ... ... @@ -381,7 +381,7 @@ runStmt stmt stmt_text step = do
    381 381
                                                        (EvalThis fhv) }
    
    382 382
         Just <$> GHC.execStmt' stmt stmt_text opts
    
    383 383
     
    
    384
    -runDecls :: GhciMonad m => String -> m (Maybe [GHC.Name])
    
    384
    +runDecls :: GhciMonad m => String -> m (Maybe [GHC.TyThing])
    
    385 385
     runDecls decls = do
    
    386 386
       st <- getGHCiState
    
    387 387
       reifyGHCi $ \x ->
    
    ... ... @@ -393,7 +393,7 @@ runDecls decls = do
    393 393
               r <- GHC.runDeclsWithLocation (progname st) (line_number st) decls
    
    394 394
               return (Just r)
    
    395 395
     
    
    396
    -runDecls' :: GhciMonad m => [LHsDecl GhcPs] -> m (Maybe [GHC.Name])
    
    396
    +runDecls' :: GhciMonad m => [LHsDecl GhcPs] -> m (Maybe [GHC.TyThing])
    
    397 397
     runDecls' decls = do
    
    398 398
       st <- getGHCiState
    
    399 399
       reifyGHCi $ \x ->
    

  • testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.hs
    1
    +module RttiSharedTyVar where
    
    2
    +
    
    3
    +f :: a -> a -> ()
    
    4
    +f x y = x `seq` y `seq` ()

  • testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.script
    1
    +:l RttiSharedTyVar
    
    2
    +let a = Just undefined :: Maybe Int
    
    3
    +let b = Just 5 :: Maybe Int
    
    4
    +a `seq` b `seq` ()
    
    5
    +:break f
    
    6
    +-- should say x y have type Maybe Int, not Maybe a
    
    7
    +f a b
    
    8
    +:t x
    
    9
    +:t y

  • testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.stdout
    1
    +()
    
    2
    +Breakpoint 0 activated at RttiSharedTyVar.hs:4:9-26
    
    3
    +Stopped in RttiSharedTyVar.f, RttiSharedTyVar.hs:4:9-26
    
    4
    +_result :: () = _
    
    5
    +x :: Maybe Int = Just _
    
    6
    +y :: Maybe Int = Just 5
    
    7
    +x :: Maybe Int
    
    8
    +y :: Maybe Int

  • testsuite/tests/ghci.debugger/scripts/all.T
    ... ... @@ -155,3 +155,5 @@ test('T26042f2', [extra_hc_opts('-O -fno-unoptimized-core-for-interpreter'), ext
    155 155
     test('T26042g', extra_files(['T26042g.hs']), ghci_script, ['T26042g.script'])
    
    156 156
     
    
    157 157
     test('T27633c', extra_files(['T27633c_obj.hs']), ghci_script, ['T27633c.script'])
    
    158
    +
    
    159
    +test('RttiSharedTyVar', extra_files(['RttiSharedTyVar.hs']), ghci_script, ['RttiSharedTyVar.script'])