Skip to content

Recover on attribute in use tree#155254

Open
scrabsha wants to merge 2 commits into
rust-lang:mainfrom
scrabsha:push-qlmmuuwqnoqv
Open

Recover on attribute in use tree#155254
scrabsha wants to merge 2 commits into
rust-lang:mainfrom
scrabsha:push-qlmmuuwqnoqv

Conversation

@scrabsha

@scrabsha scrabsha commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Renders as:

This requires passing two more arguments to Parser::parse_use_tree and I'm not super happy about it. I did consider adding more context to Parser instead, 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

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 13, 2026
@rust-log-analyzer

This comment has been minimized.

@scrabsha scrabsha force-pushed the push-qlmmuuwqnoqv branch from 291ff75 to 290c04c Compare April 13, 2026 19:54
Comment thread compiler/rustc_parse/src/parser/item.rs Outdated
@scrabsha scrabsha force-pushed the push-qlmmuuwqnoqv branch from 290c04c to 83f6ae9 Compare April 14, 2026 20:11
@scrabsha

Copy link
Copy Markdown
Contributor Author

@fmease would you be ok with me assigning this PR to you? (once I have re-reviewed it again)

@fmease

fmease commented Apr 14, 2026

Copy link
Copy Markdown
Member

Sure! :)

@fmease fmease self-assigned this Apr 14, 2026
@scrabsha scrabsha force-pushed the push-qlmmuuwqnoqv branch from 83f6ae9 to 0e53906 Compare April 15, 2026 21:07
Comment on lines +1421 to +1423
.filter_map(|segment| {
if !segment.ident.is_special() { Some(segment.ident.as_str()) } else { None }
})

@scrabsha scrabsha Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. However if you were to map kw::PathRoot to "" here, you wouldn't need global_path, right?

@scrabsha scrabsha Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in the file are needed because the closure passed to span_extend_while in item.rs mutably borrows comma_reached.

View changes since the review

@scrabsha

Copy link
Copy Markdown
Contributor Author

thank you!

r? fmease

@rustbot

rustbot commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator

Requested reviewer is already assigned to this pull request.

Please choose another assignee.

@scrabsha scrabsha marked this pull request as ready for review April 17, 2026 15:53
@rustbot

rustbot commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator

The parser was modified, potentially altering the grammar of (stable) Rust
which would be a breaking change.

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 17, 2026

@fmease fmease left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preliminary review, sorry for the delay.

View changes since this review

/// The tokens must be either a delimited token stream, or empty token stream,
/// or the "legacy" key-value form.
///
/// ```none

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// ```none
/// ```text

text is conventional for plain text.

Comment on lines 307 to 311
/// PATH `(` TOKEN_STREAM `)`
/// PATH `[` TOKEN_STREAM `]`
/// PATH `{` TOKEN_STREAM `}`
/// PATH
/// PATH `=` UNSUFFIXED_LIT

@fmease fmease May 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();

@fmease fmease May 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(),

@fmease fmease May 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(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.

View changes since the review

@fmease fmease left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more comments but this already looks very good overall, thanks for working on this!

View changes since this review

Comment on lines +1370 to +1371
if p.check_noexpect(&TokenKind::Pound)
&& p.look_ahead(1, |tok| matches!(tok.kind, TokenKind::OpenBracket))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.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()))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.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],

@fmease fmease May 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
element: &'a [ast::PathSegment],
elements: &'a [ast::PathSegment],

or segments or path?

Comment on lines +1421 to +1423
.filter_map(|segment| {
if !segment.ident.is_special() { Some(segment.ident.as_str()) } else { None }
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. However if you were to map kw::PathRoot to "" here, you wouldn't need global_path, right?

@fmease fmease added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 22, 2026
@scrabsha

Copy link
Copy Markdown
Contributor Author

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants