Opened 3 years ago

Closed 2 years ago

Last modified 9 months ago

#12091 closed bug (fixed)

'Variable not in scope" when using GHCi with `-fobject-code`

Reported by: thomie Owned by:
Priority: high Milestone: 8.4.1
Component: GHCi Version: 8.0.1
Keywords: Cc: roshats
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #7253, #14108 Differential Rev(s): Phab:D3849
Wiki Page:


Since b98ff3ccb14e36145404f075349c8689762a2913 was landed (#7253), you don't need let to define stuff in GHCi:

$ ghci
Prelude> x = 3
Prelude> x

But when using -fobject-code, this results in an error:

$ ghci -fobject-code
Prelude> x = 3
Prelude> x

<interactive>:2:1: error: Variable not in scope: x

Very strange.

CC @roshats, who implemented this feature, but the bug is probably in some part of the code he didn't touch.

Change History (9)

comment:1 Changed 3 years ago by osa1

I know the problem but I don't know how to fix it. let x = ... is compiled as a statement, x = ... is compiled as a declaration. Desugarer dumps unused declarations if the target is not HscInterpreted or HscNothing (see DynFlags.targetRetainsAllBindings), but nothing like that is done for statements. Since -fobject-code sets target something other than HscInterpreted and HscNothing, x gets dumped.

comment:2 Changed 3 years ago by osa1

This is related with @roshats's patch as that's where we choose to compile x = ... as a statement instead of declaration (by "desugaring" it into let x = ...).

Maybe we can do that now, unless someone has a better idea.

comment:3 Changed 3 years ago by Ben Gamari <ben@…>

In 22259c17/ghc:

testsuite: Failing testcase for #12091

Just as it says on the can

Test Plan: validate

Reviewers: austin

Subscribers: thomie

Differential Revision:

GHC Trac Issues: #12091

comment:4 Changed 2 years ago by RyanGlScott

Differential Rev(s): Phab:D3849
Status: newpatch

comment:5 Changed 2 years ago by Ben Gamari <ben@…>

In ddb870b/ghc:

Don't drop GHCi-defined functions with -fobject-code enabled

The desugarer was using `targetRetainsAllBindings` as a litmus test for
determining if a function was defined in interactive mode (and thus
should be exported). However, there is a corner case where one can be in
interactive mode and have `targetRetainsAllBindings` return `False`: if
`-fobject-code` is enabled (since the target will no longer be
`HscInteractive`). In such a scenario, we should fall back on a
different test for determining if we are in a GHCi session. I chose to
use `isInteractiveModule`, which appears to do the trick.

Test Plan: make test TEST=T12091

Reviewers: austin, bgamari

Subscribers: rwbarton, thomie

GHC Trac Issues: #12091

Differential Revision:

comment:6 Changed 2 years ago by bgamari

Milestone: 8.4.1
Resolution: fixed
Status: patchclosed

comment:7 Changed 9 months ago by osa1

I reverted ddb870bf7055ccc8ff8b86c161f31aad81d01add in, which fixes the difference between x = ... and let x = ... in GHCi.

comment:8 Changed 9 months ago by osa1

The MR in comment:7 is merged as a34ee6154.

comment:9 Changed 9 months ago by Ömer Sinan Ağacan <omeragacan@…>

In a34ee615/ghc:

Refactor GHCi UI to fix #11606, #12091, #15721, #16096

Instead of parsing and executing a statement or declaration directly we
now parse them first and then execute in a separate step. This gives us
the flexibility to inspect the parsed declaration before execution.
Using this we now inspect parsed declarations, and if it's a single
declaration of form `x = y` we execute it as `let x = y` instead, fixing
a ton of problems caused by poor declaration support in GHCi.

To avoid any users of the modules I left `execStmt` and `runDecls`
unchanged and added `execStmt'` and `runDecls'` which work on parsed
Note: See TracTickets for help on using tickets.