mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
fix issue-144595
This commit is contained in:
@@ -4639,3 +4639,28 @@ pub(crate) struct ReservedMultihashLint {
|
||||
)]
|
||||
pub suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
"if you meant to write a path, use a double colon:",
|
||||
code = "::",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct UseDoubleColonSuggestion {
|
||||
#[primary_span]
|
||||
pub colon: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
"if you meant to create a regular struct, use curly braces:",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct UseRegularStructSuggestion {
|
||||
#[suggestion_part(code = "{{")]
|
||||
pub open: Span,
|
||||
#[suggestion_part(code = "}}")]
|
||||
pub close: Span,
|
||||
#[suggestion_part(code = "")]
|
||||
pub semicolon: Option<Span>,
|
||||
}
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
AllowConstBlockItems, AttrWrapper, ExpKeywordPair, ExpTokenPair, FollowedByType, ForceCollect,
|
||||
Parser, PathStyle, Recovered, Trailing, UsePreAttrPos,
|
||||
};
|
||||
use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField};
|
||||
use crate::errors::{
|
||||
self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField,
|
||||
UseDoubleColonSuggestion, UseRegularStructSuggestion,
|
||||
};
|
||||
use crate::exp;
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
@@ -2084,10 +2087,11 @@ fn parse_unsafe_field(&mut self) -> Safety {
|
||||
Safety::Default
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the case where we find `struct Foo<T>(T) where T: Copy;`
|
||||
/// Unit like structs are handled in parse_item_struct function
|
||||
pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
|
||||
// This is the case where we find `struct Foo<T>(T) where T: Copy;`
|
||||
// Unit like structs are handled in parse_item_struct function
|
||||
let openparen_span = self.token.span;
|
||||
let mut encountered_colon = false;
|
||||
self.parse_paren_comma_seq(|p| {
|
||||
let attrs = p.parse_outer_attributes()?;
|
||||
p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
|
||||
@@ -2109,6 +2113,8 @@ pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef
|
||||
}
|
||||
};
|
||||
let mut_restriction = p.parse_mut_restriction()?;
|
||||
encountered_colon |=
|
||||
p.token.is_ident() && p.look_ahead(1, |tok| tok == &token::Colon);
|
||||
// Unsafe fields are not supported in tuple structs, as doing so would result in a
|
||||
// parsing ambiguity for `struct X(unsafe fn())`.
|
||||
let ty = match p.parse_ty() {
|
||||
@@ -2156,6 +2162,19 @@ pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef
|
||||
})
|
||||
})
|
||||
.map(|(r, _)| r)
|
||||
.map_err(|mut error| {
|
||||
if encountered_colon {
|
||||
error.subdiagnostic(UseDoubleColonSuggestion { colon: self.token.span });
|
||||
self.eat_to_tokens(&[exp!(CloseParen)]);
|
||||
self.bump();
|
||||
error.subdiagnostic(UseRegularStructSuggestion {
|
||||
open: openparen_span,
|
||||
close: self.prev_token.span,
|
||||
semicolon: if self.token == token::Semi { Some(self.token.span) } else { None },
|
||||
});
|
||||
}
|
||||
error
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses an element of a struct declaration.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Provide diagnostics when the user writes field names in tuple struct.(issue#144595)
|
||||
|
||||
struct Foo(a:u8,b:u8);
|
||||
//~^ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
//~| HELP if you meant to write a path, use a double colon:
|
||||
//~| HELP if you meant to create a regular struct, use curly braces:
|
||||
@@ -0,0 +1,18 @@
|
||||
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
|
||||
--> $DIR/field-name-in-tuple-struct.rs:3:13
|
||||
|
|
||||
LL | struct Foo(a:u8,b:u8);
|
||||
| ^ expected one of 7 possible tokens
|
||||
|
|
||||
help: if you meant to write a path, use a double colon:
|
||||
|
|
||||
LL | struct Foo(a::u8,b:u8);
|
||||
| +
|
||||
help: if you meant to create a regular struct, use curly braces:
|
||||
|
|
||||
LL - struct Foo(a:u8,b:u8);
|
||||
LL + struct Foo{a:u8,b:u8}
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Reference in New Issue
Block a user