Recover on attribute in use tree#155254
Conversation
This comment has been minimized.
This comment has been minimized.
291ff75 to
290c04c
Compare
290c04c to
83f6ae9
Compare
|
@fmease would you be ok with me assigning this PR to you? (once I have re-reviewed it again) |
|
Sure! :) |
83f6ae9 to
0e53906
Compare
| .filter_map(|segment| { | ||
| if !segment.ident.is_special() { Some(segment.ident.as_str()) } else { None } | ||
| }) |
There was a problem hiding this comment.
This filter_map removes any segment that is a special identifier - not just the leading {{root}}. I cannot think of a case in which it is an issue, but I want to mention it regardless.
There was a problem hiding this comment.
Fair. However if you were to map kw::PathRoot to "" here, you wouldn't need global_path, right?
There was a problem hiding this comment.
The changes in the file are needed because the closure passed to span_extend_while in item.rs mutably borrows comma_reached.
|
thank you! r? fmease |
|
Requested reviewer is already assigned to this pull request. Please choose another assignee. |
|
The parser was modified, potentially altering the grammar of (stable) Rust cc @fmease |
| /// The tokens must be either a delimited token stream, or empty token stream, | ||
| /// or the "legacy" key-value form. | ||
| /// | ||
| /// ```none |
There was a problem hiding this comment.
| /// ```none | |
| /// ```text |
text is conventional for plain text.
| /// PATH `(` TOKEN_STREAM `)` | ||
| /// PATH `[` TOKEN_STREAM `]` | ||
| /// PATH `{` TOKEN_STREAM `}` | ||
| /// PATH | ||
| /// PATH `=` UNSUFFIXED_LIT |
There was a problem hiding this comment.
Since this is now in a fenced code block, this should be dedented by 4 spaces.
The reason that these grammar rules were indented is because somebody tried to write an indented code block but didn't precede it by a blank line, so it didn't get interpreted that way.
| .psess | ||
| .source_map() | ||
| .span_to_source(attr_span, |s, start, end| Ok(s[start..end].to_string())) | ||
| .unwrap(); |
There was a problem hiding this comment.
span_to_source can fail, so please don't unwrap. It can return None if the span points into the expansion of a macro from an upstream crate whose sources aren't available for some reason.
See RUST-128442 and RUST-128445 for how an artificial reproducer might look like.
Instead suppress the suggestion if we hit None in any of those places where you call span_to_source.
| let err = crate::errors::AttrInUseTree { | ||
| attr_span, | ||
| sub: Some(crate::errors::AttrInUseTreeSugg { | ||
| use_lo: use_token_span.shrink_to_lo(), |
There was a problem hiding this comment.
(minor) This doesn't account for attributes on the use-item itself, the start index of the use keyword is not sufficient. I'm pretty sure your code currently suggests something like
#[deny(unused_imports)]
#[allow(unused_imports)]
use crate::fst;
use crate::{
snd,
};for
#[deny(unused_imports)]
use crate::{
#[allow(unused_imports)]
fst,
snd,
};doesn't need to be addressed now, can also be a FIXME.
| if p.check_noexpect(&TokenKind::Pound) | ||
| && p.look_ahead(1, |tok| matches!(tok.kind, TokenKind::OpenBracket)) |
There was a problem hiding this comment.
I would just parse_outer_attributes unconditionally, take for recovery and raise an error if the attr vec is non-empty. That'd be a lot simpler and it would allow us to recover from "leading" doc comments (we're already recovering from doc comments if they're preceded by regular attributes).
| let use_tree = self | ||
| .psess | ||
| .source_map() | ||
| .span_to_source(use_tree_span, |s, start, end| Ok(s[start..end].to_string())) |
There was a problem hiding this comment.
| .span_to_source(use_tree_span, |s, start, end| Ok(s[start..end].to_string())) | |
| .span_to_snippet(use_tree_span) |
| let attr = self | ||
| .psess | ||
| .source_map() | ||
| .span_to_source(attr_span, |s, start, end| Ok(s[start..end].to_string())) |
There was a problem hiding this comment.
| .span_to_source(attr_span, |s, start, end| Ok(s[start..end].to_string())) | |
| .span_to_snippet(attr_span) |
| } | ||
|
|
||
| struct UsePathList<'a> { | ||
| element: &'a [ast::PathSegment], |
There was a problem hiding this comment.
| element: &'a [ast::PathSegment], | |
| elements: &'a [ast::PathSegment], |
or segments or path?
| .filter_map(|segment| { | ||
| if !segment.ident.is_special() { Some(segment.ident.as_str()) } else { None } | ||
| }) |
There was a problem hiding this comment.
Fair. However if you were to map kw::PathRoot to "" here, you wouldn't need global_path, right?
|
hi @fmease, thank you infinitely for your review. you put a lot of care into these and i really really appreciate all your explanations <3 i'll fix everything once the all hands is over and i have some quiet time, but I still wanted to say thanks as soon as possible :) thank you again! |

Renders as:

This requires passing two more arguments to
Parser::parse_use_treeand I'm not super happy about it. I did consider adding more context toParserinstead, but that did not sound like a good idea. Happy to rework my code to make it less ugly :)I am also not very happy that the deletion shows up as a green
~in the suggestion. I tried very hard to make it render properly but failed. I am not sure it's actually possible but would love to be proven wrong hehe