-
Notifications
You must be signed in to change notification settings - Fork 93
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
Support warnings #2086
Support warnings #2086
Conversation
Bencher Report
Click to view all benchmark results
|
@@ -117,7 +117,7 @@ impl Files { | |||
// This implementation would be a little nicer if `Vector` supported mutable access. | |||
// unwrap: we're allowed to panic if file_id is invalid | |||
let mut old = self.get(file_id).unwrap().clone(); | |||
old.source = source.into(); | |||
old = File::new(old.name, source); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes a recently-introduced but where the line_starts
cache wasn't updated. Unlikely to trigger in nickel
itself, but it caused some problems for nls.
I haven't looked at it in details yet, but why won't something like |
Fair enough, I'll explore option 2 a little. I didn't want to tie the implementation to a vec of diagnostics, because I want to allow for the possibility that some diagnostics handlers will want to issue diagnostics immediately while evaluation continues. I do have another secret motivation for wanting to try out a lifetime parameter on |
By issuing you mean that you might want to print a diagnostic immediately, instead of accumulating and only at the end printing them? In that case I think you can still keep the
That's a fair motivation, but probably slightly orthogonal (at least in the |
Bencher Report
Click to view all benchmark results
|
I think we could get by with a single lifetime parameter, but I guess that's something to look into later anyway.
The previous iteration did in fact use a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I was initially a bit skeptical about the overall size of the diff, in the end there are many things I like in this PR, mainly:
- We get rid of a lot of juggling caused by the need to include
program
in CLI errors before; now we can just cheaply clonefiles
and call it a day, which looks much cleaner 👍 (we also got rid of unsatisfyingreport_xxx
methods inProgram
) - Using channels for reporting stuff is actually quite elegant, and corresponds well to the mental model of sending data to a reporter or a terminal.
TODOs that I see for the future:
- Add more warnings (another obvious one would be unused variable, which can be done currently in the free var transform, and in the future in the compiler)
- Various flags to control warnings (I suppose if you run this version of Nickel on a large existing code base that use naked contracts you'll get a full load of warnings). Like
-Werror
and to disable them at least?
if self.customize_mode.is_empty() { | ||
return Ok(program); | ||
} | ||
|
||
let evaled = match program.eval_record_spine() { | ||
Ok(evaled) => evaled, | ||
// We need a `return` control-flow to be able to take `program` out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! Not anymore 🙂
cli/src/error.rs
Outdated
// This impl is allowed to incorrectly say that two warnings are equal. We allow | ||
// this in order to skip comparing the full `Files` databases, which could be | ||
// large. Since this is only used for deduplicating warnings, the impact of a | ||
// false answer is limited. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this; do you have an example?
Edit: Ok, now I get it - you mean that you don't compare the file database. I think the wording is a bit misleading (it's just that equality ignores the file database, which is ok; initially I wondered if this impl would break the laws of Eq
and PartialEq
, which is not ok). Maybe saying that directly, that is "This implementation only compare the content of the warnings and ignores the Files
database for obvious performance reasons. Since this is only [...]" instead of "is allowed to incorrectly say that two warnings are equal", which is less specific IMHO. Also I guess having two equal warnings (meaning with the same positions stored as well, including file ids and byte offsets) that actually points to different files is highly unlikely.
Thanks! I'm glad the refactors made sense, because it was starting to feel like I lost track of the original goal...
Maybe it makes sense to bikeshed some sort of global nickel config? There's a long discussion here about how to integrate layered config into clap, but it appears there's no resolution yet. (I didn't read the whole thing, just scrolled to the end) |
Co-authored-by: Yann Hamdaoui <[email protected]>
Co-authored-by: Yann Hamdaoui <[email protected]>
Yes, I agree we need a structured approach, with relations and priorities between env vars, CLI arguments and a potential config file, and a consistent option naming scheme, instead of just adding ad hoc flags here and there. |
This adds a bunch of infrastructure for warnings (and for reporting multiple errors, potentially), and also a warning for applying a naked function as a contract.
Most of the PR involves the threading of some extra global state through the program and the vm. I could see a few options:
&mut <global state>
can be passed in.I went with the third option. The first option would require a lot of churn (and then potentially more churn if we want to change the type of the global state). The second option would require the global state to either be a concrete type (but I wanted different types in the cli and nls) or a type parameter. So then given that it looked like we'd want an additional generic parameter anyway, I went for the lifetime parameter of the third option.