Skip to content
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

Fix duplicated attributes on nonterminal expressions #126678

Merged
merged 11 commits into from
Jun 19, 2024
4 changes: 3 additions & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,9 @@ impl UnOp {
}
}

/// A statement
/// A statement. No `attrs` or `tokens` fields because each `StmtKind` variant
/// contains an AST node with those fields. (Except for `StmtKind::Empty`,
/// which never has attrs or tokens)
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Stmt {
pub id: NodeId,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `{$token_
parse_dot_dot_dot_range_to_pattern_not_allowed = range-to patterns with `...` are not allowed
.suggestion = use `..=` instead

parse_dot_dot_range_attribute = attributes are not allowed on range expressions starting with `..`

parse_dotdotdot = unexpected token: `...`
.suggest_exclusive_range = use `..` for an exclusive range
.suggest_inclusive_range = or `..=` for an inclusive range
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2989,3 +2989,10 @@ pub(crate) struct ExprRArrowCall {
#[suggestion(style = "short", applicability = "machine-applicable", code = ".")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_dot_dot_range_attribute)]
pub(crate) struct DotDotRangeAttribute {
#[primary_span]
pub span: Span,
}
6 changes: 5 additions & 1 deletion compiler/rustc_parse/src/parser/attr_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::ops::Range;
/// for the attribute target. This allows us to perform cfg-expansion on
/// a token stream before we invoke a derive proc-macro.
///
/// This wrapper prevents direct access to the underlying `ast::AttrVec>`.
/// This wrapper prevents direct access to the underlying `ast::AttrVec`.
/// Parsing code can only get access to the underlying attributes
/// by passing an `AttrWrapper` to `collect_tokens_trailing_tokens`.
/// This makes it difficult to accidentally construct an AST node
Expand Down Expand Up @@ -177,6 +177,10 @@ impl<'a> Parser<'a> {
/// into a `LazyAttrTokenStream`, and returned along with the result
/// of the callback.
///
/// The `attrs` passed in are in `AttrWrapper` form, which is opaque. The
/// `AttrVec` within is passed to `f`. See the comment on `AttrWrapper` for
/// details.
///
/// Note: If your callback consumes an opening delimiter
/// (including the case where you call `collect_tokens`
/// when the current token is an opening delimiter),
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,8 @@ impl<'a> Parser<'a> {
/// wrapped in braces.
pub(super) fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P<Expr>> {
let start = self.token.span;
let expr = self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
let attrs = self.parse_outer_attributes()?;
let expr = self.parse_expr_res(Restrictions::CONST_EXPR, attrs).map_err(|mut err| {
err.span_label(
start.shrink_to_lo(),
"while parsing a const generic argument starting here",
Expand Down Expand Up @@ -2624,7 +2625,10 @@ impl<'a> Parser<'a> {
if is_op_or_dot {
self.bump();
}
match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
match (|| {
let attrs = self.parse_outer_attributes()?;
self.parse_expr_res(Restrictions::CONST_EXPR, attrs)
})() {
Ok(expr) => {
// Find a mistake like `MyTrait<Assoc == S::Assoc>`.
if token::EqEq == snapshot.token.kind {
Expand Down Expand Up @@ -2678,7 +2682,10 @@ impl<'a> Parser<'a> {
&mut self,
mut snapshot: SnapshotParser<'a>,
) -> Option<P<ast::Expr>> {
match snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) {
match (|| {
let attrs = self.parse_outer_attributes()?;
snapshot.parse_expr_res(Restrictions::CONST_EXPR, attrs)
})() {
// Since we don't know the exact reason why we failed to parse the type or the
// expression, employ a simple heuristic to weed out some pathological cases.
Ok(expr) if let token::Comma | token::Gt = snapshot.token.kind => {
Expand Down
Loading
Loading