-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Revert context changes on error #508
Revert context changes on error #508
Conversation
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.
Looks pretty good, but I believe it needs more documentation. It took me a while to understand this. But maybe I'm just stupid XD
fn visit_field(&mut self, field: &'a Field) { | ||
if field.attrs.iter().any(utils::is_context) { | ||
if let Some(name) = &field.ident { | ||
if let Some(segment) = utils::get_type(field) { | ||
self.functions.push(Self::make_function(name, segment)); | ||
} | ||
} | ||
} | ||
} |
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.
fn visit_field(&mut self, field: &'a Field) { | |
if field.attrs.iter().any(utils::is_context) { | |
if let Some(name) = &field.ident { | |
if let Some(segment) = utils::get_type(field) { | |
self.functions.push(Self::make_function(name, segment)); | |
} | |
} | |
} | |
} | |
fn visit_field(&mut self, field: &'a Field) { | |
if !field.attrs.iter().any(utils::is_context) { | |
return; | |
} | |
if let (Some(name), Some(segment)) = (&field.ident, utils::get_type(field)) { | |
self.functions.push(Self::make_function(name, segment)); | |
} | |
} |
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'm not sure your suggested tuple destructuring makes things any clearer; better to keep unrelated functionality on separate lines.
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.
@Ph0enixKM wdyt? Imo it looks clearer, but It's just a preference so vox populi, vox Dei
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.
The modified version looks clearer because it favors the never-nesting approach. I like the change that @KrosFire made.
Early return is more verbose. If we had even more nested if..let
then this change would highlight the issue even more. The code will keep the indentation level while the original nested code will be a bunch of if's nested inside.
meta/src/utils.rs
Outdated
if let Meta::Path(path) = &attr.meta { | ||
if let Some(segment) = path.segments.last() { | ||
let ident = segment.ident.to_string(); | ||
if ident == "context" { | ||
return true; | ||
} | ||
} | ||
} | ||
false |
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.
if let Meta::Path(path) = &attr.meta { | |
if let Some(segment) = path.segments.last() { | |
let ident = segment.ident.to_string(); | |
if ident == "context" { | |
return true; | |
} | |
} | |
} | |
false | |
if let Meta::Path(path) = &attr.meta { | |
return path | |
.segments | |
.last() | |
.map_or(false, |segment| segment.ident == "context"); | |
} | |
false |
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'm not sure this makes things any clearer.
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 think that what @KrosFire suggested is slightly more readable because it eliminates the need for conversion .to_string()
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've removed the unnecessary .to_string()
, but that .map_or()
construct seems unnecessarily verbose. I tend to write nested chains of if
statements, because it puts each thing being tested on a single line, reducing the conceptual load.
814f88b
to
dbc4de3
Compare
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.
LGTM
2b7665e
to
1ef6f28
Compare
1ef6f28
to
7d05976
Compare
@@ -7,7 +7,7 @@ use std::{io::{BufWriter, Write}, process::{Command, Stdio}}; | |||
#[derive(Debug, Clone, Copy)] | |||
#[allow(non_camel_case_types)] | |||
pub enum BashFormatter { | |||
/// https://github.com/mvdan/sh | |||
/// <https://github.com/mvdan/sh> |
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.
Change was suggested by RustRover. Not sure if it's sensible; perhaps someone who knows more about doc comments than I do could verify?
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.
As per rust book:
bare_urls
detects links that are not linkified, e.g., in Markdown such asGo to https://example.com/
. It suggests wrapping the link with angle brackets:Go to <https://example.com/>
. to linkify it. This is the code behind therustdoc::bare_urls
lint.
To be honest I didn't know that before! It's always nice to learn something new
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'm thinking whether or not is the whole proc macro
approach a bit of an overkill for such a simple use case. Is there something that macro_rules
was inappropriate? The proc macro requires to create a whole new repository. Using macro_rules
requires a lot less effort to read the macro, because it usually can be expressed in a single file.
I'm saying that because the implementation for the functions isn't that complex and it seems that we could use a simpler macro for this.
macro_rules! with_context {
(...) => {
let prev = self.#name.clone();
self.#name = #name;
let result = body(self);
self.#name = prev;
result
}
// ... Maybe some other implementations for `ref` and `fn`
}
And then the usage would be:
with_context!(..., |...| {
})
Anyways... what do you think @hdwalters @KrosFire?
I think the Also, as I understand it, we do not need to create a new Git repository, just a new Also, depending on your IDE (RustRover does this) you can show the results of macro expansion by hovering over the relevant item in the source. This certainly helped me write this! |
Touched one of the subdirectory source files and rebuilt. The dependency was automatically rebuilt:
So the CI server should continue to work; and I don't believe we're pushing the source to https://crates.io/ or anywhere similar, so there shouldn't be any problems there either. |
@hdwalters could you elaborate on that? I still don't understand the point. You can always modify the variable with |
We could migrate other macros to this proc macro to enhance the experience even more. But that's not the most important thing to be worried about right now. |
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.
LGTM
Actually I meant that it's better to configure macro behaviour with annotations, because they're right next to the annotated code, so it's more obvious what's available:
But your point is valid too; the main thing about procedural macros is that they operate directly on and (in this case) add functions to the abstract syntax tree, exactly as if you had typed them yourself. |
Declarative macros with |
Rust macros are so much cooler than C++ ones! |
Fixes bug #489, by using a procedural macro to generate context manager functions, wrapping syntax parser failure. Also pops scope from the scope stack on syntax parser failure.