-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: interactive mode shouldn't send output until it receives a query #912
Comments
Hi @cpitclaudel . In my nik_912 branch, I implemented something to address this issue. Basically, when launching When the next message arrives (usually a push) we type-check the dependences of the current buffer etc. If there are any errors in the dependences, then we print those errors back and then exit with error code 1. However, this doesn't seem to have much impact from what is observed from the side of fstar-mode.el. Could fstar-mode.el be revised to at least report the error message that F* prints back before exiting? Not exiting on the fstar side is quite hard ... since without a proper dependence graph, it's not at all clear how to proceed. Thanks! |
Yay, thanks!
Hmm. How are you printing the errors and exiting? Can you show me what a transcript looks like (it should be easy with
Doesn't it do that (in the
What happens if instead of exiting you just revert to the state right before the push? |
I have in a.fst:
and in b.fst
I'm launching fstar-mode.el on a.fst using nik_912. Here's the output from the debug window:
Here's what's in the Messages buffer.
This seems ok enough ... I'm not sure what the desired behavior here should be. I, for one, find it confusing when the most prominent error message just says "F* subprocess exited". It would be cool if there were some way to instead (or in addition) show the error message related to the failure in the b.fst in the ribbon at the bottom. What do you think? About this:
In this setting, it would mean trying to proceed without any type checking / desugaring environment at all. Or, at best, with some more work, an environment populated with only some of the dependences. Neither of which seem like a particularly useful state to be in. Perhaps I'm misunderstanding ... |
I can try to work something out. These two messages come from different parts of the code, so it's hard to teach them about each other.
Or perhaps I am. Here's the flow I'm suggesting:
Does this make sense? |
It makes sense to me. That would save a lot of time trying to see where are the errors in dependencies by looking at the |
I have a draft implementation for the proposal above. There are some issues:
|
I have refreshed the code mentioned above, and made progress with the implementation. I now have…
Here's how my code works (in cpitclaudel_912). When we launch F*, we create a small, partial REPL state and we do only minimal initialization. Then, when we receive our first push, we process dependencies and report errors if any instead of those of the pushed chunk (which we go on to process if dependency checking was successful). Now I need help. The first solution sounds much simpler; I'd favor taking that route, since we expect dependency re-loading to be fast once we introduce on-the-fly compilation of modules. But I can easily adjust to either solution. @aseemr, could you help me? I'm excited to be this close to a resolution for this long-standing bug :) |
As a side note / starting point, here's a draft / what I guess tc_deps could look like if we forget about update_deps: let rec push_then_do_or_revert_all env stack fn =
let revert env stack =
Util.print1 "Reverting %s entries" (string_of_int (List.length stack));
let rec aux env stack =
match stack with
| [] -> env
| env' :: stack' -> pop env' "typecheck_modul"; aux env' stack' in
aux env stack in
let stack = env :: stack in
let env' = push env "tc prims, deps, or interface" in
match with_captured_errors env' fn with
| None -> Inr (revert env' stack)
| Some res -> Inl (stack, res)
let tc_deps (env: env_t) (stack: deps_stack_t) (remaining: list<string>) =
let rec aux (env: env_t) (stack: deps_stack_t)
(ts: m_timestamps) (remaining: list<string>) =
match remaining with
| [] -> Inl (stack, env, ts)
| _ ->
let stack = env :: stack in
let push_kind = if Options.lax () then LaxCheck else FullCheck in
Options.restore_cmd_line_options false |> ignore;
match push_then_do_or_revert_all env stack
(fun () -> Some <| tc_one_file remaining (set_check_kind env push_kind)) with
| Inr env -> Inr env
| Inl (stack, ((intf, impl), env, remaining)) ->
let intf_t = intf |> Util.map_option get_file_last_modification_time in
let impl_t = get_file_last_modification_time impl in
aux env stack ((intf, impl, intf_t, impl_t) :: ts) remaining in
aux env stack [] remaining |
I have a full draft in cpitclaudel_912_wip |
First collect tasks, then run them.
First collect tasks, then run them.
First collect tasks, then run them.
First collect tasks, then run them.
With the generalization of load_deps, there's no need for a type of partial REPL states anymore: it's enough to first not load anything, and then let the dependency updater do its thing on the first push. Neat! Fixes #912.
First collect tasks, then run them.
With the generalization of load_deps, there's no need for a type of partial REPL states anymore: it's enough to first not load anything, and then let the dependency updater do its thing on the first push. Neat! Fixes #912.
First collect tasks, then run them.
With the generalization of load_deps, there's no need for a type of partial REPL states anymore: it's enough to first not load anything, and then let the dependency updater do its thing on the first push. Neat! Fixes #912.
First collect tasks, then run them.
With the generalization of load_deps, there's no need for a type of partial REPL states anymore: it's enough to first not load anything, and then let the dependency updater do its thing on the first push. Neat! Fixes #912.
This is essentially the F* side of FStarLang/fstar-mode.el#21 . When booting, F* does a bunch of things that can produce errors. These errors are reported immediately, without an end-of-message marker or a way to know where they came from, and fstar-mode consequently doesn't report them.
The fix is pretty simple: delay most initialization until an
#init
call or something similar has been received.This way we could get rid of the https://github.com/FStarLang/FStar/wiki/Early-stumbling-blocks,-FAQ#fstar-mode-gives-error-message-f-subprocess-exited-what-shall-i-do and README entries about it :)
The text was updated successfully, but these errors were encountered: