From a09204ad18ddc8e2b5548b96c3294e2558a21801 Mon Sep 17 00:00:00 2001 From: Kokoro2336 <2529677678@qq.com> Date: Thu, 21 May 2026 19:33:50 +0800 Subject: [PATCH 1/8] fix: missing suggestion for string match. chore: update .fixed. fix: suggestion. Revert irrelevant changes. --- compiler/rustc_hir_typeck/src/pat.rs | 17 +++++++- .../pattern/deref-patterns/needs-gate.stderr | 5 +++ .../string-match-as-str-suggestion.fixed | 18 ++++++++ .../pattern/string-match-as-str-suggestion.rs | 18 ++++++++ .../string-match-as-str-suggestion.stderr | 43 +++++++++++++++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/ui/pattern/string-match-as-str-suggestion.fixed create mode 100644 tests/ui/pattern/string-match-as-str-suggestion.rs create mode 100644 tests/ui/pattern/string-match-as-str-suggestion.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index e06fab410c887..b5ae3d06b3b33 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1007,7 +1007,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // then that's equivalent to there existing a LUB. let cause = self.pattern_cause(ti, span); - if let Err(err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { + if let Err(mut err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { + // If scrutinee is String and pattern is &str, suggest .as_str() + let expected = self.resolve_vars_with_obligations(expected); + if let ty::Adt(adt, _) = expected.kind() + && self.tcx.is_lang_item(adt.did(), LangItem::String) + && pat_ty.is_ref() + && pat_ty.peel_refs().is_str() + && let Some(origin_expr) = ti.origin_expr + { + err.span_suggestion_verbose( + origin_expr.span.shrink_to_hi(), + "consider converting the `String` to a `&str` using `.as_str()`", + ".as_str()", + Applicability::MachineApplicable, + ); + } err.emit(); } diff --git a/tests/ui/pattern/deref-patterns/needs-gate.stderr b/tests/ui/pattern/deref-patterns/needs-gate.stderr index edc70048ecf2f..b07c136740036 100644 --- a/tests/ui/pattern/deref-patterns/needs-gate.stderr +++ b/tests/ui/pattern/deref-patterns/needs-gate.stderr @@ -76,6 +76,11 @@ LL | match "str".to_owned() { | ---------------- this expression has type `String` LL | "str" => {} | ^^^^^ expected `String`, found `&str` + | +help: consider converting the `String` to a `&str` using `.as_str()` + | +LL | match "str".to_owned().as_str() { + | +++++++++ error[E0308]: mismatched types --> $DIR/needs-gate.rs:52:12 diff --git a/tests/ui/pattern/string-match-as-str-suggestion.fixed b/tests/ui/pattern/string-match-as-str-suggestion.fixed new file mode 100644 index 0000000000000..620c35fb270cc --- /dev/null +++ b/tests/ui/pattern/string-match-as-str-suggestion.fixed @@ -0,0 +1,18 @@ +//@ run-rustfix + +fn main() { + let s = "yes".to_owned(); + + let _ = match s.as_str() { + "yes" => Some(true), + //~^ ERROR mismatched types + "no" => Some(false), + //~^ ERROR mismatched types + _ => None, + }; + + let s2 = String::from("hello"); + if let "hello" = s2.as_str() { + //~^ ERROR mismatched types + } +} diff --git a/tests/ui/pattern/string-match-as-str-suggestion.rs b/tests/ui/pattern/string-match-as-str-suggestion.rs new file mode 100644 index 0000000000000..5f319e417e4ef --- /dev/null +++ b/tests/ui/pattern/string-match-as-str-suggestion.rs @@ -0,0 +1,18 @@ +//@ run-rustfix + +fn main() { + let s = "yes".to_owned(); + + let _ = match s { + "yes" => Some(true), + //~^ ERROR mismatched types + "no" => Some(false), + //~^ ERROR mismatched types + _ => None, + }; + + let s2 = String::from("hello"); + if let "hello" = s2 { + //~^ ERROR mismatched types + } +} diff --git a/tests/ui/pattern/string-match-as-str-suggestion.stderr b/tests/ui/pattern/string-match-as-str-suggestion.stderr new file mode 100644 index 0000000000000..6c15877703821 --- /dev/null +++ b/tests/ui/pattern/string-match-as-str-suggestion.stderr @@ -0,0 +1,43 @@ +error[E0308]: mismatched types + --> $DIR/string-match-as-str-suggestion.rs:7:9 + | +LL | let _ = match s { + | - this expression has type `String` +LL | "yes" => Some(true), + | ^^^^^ expected `String`, found `&str` + | +help: consider converting the `String` to a `&str` using `.as_str()` + | +LL | let _ = match s.as_str() { + | +++++++++ + +error[E0308]: mismatched types + --> $DIR/string-match-as-str-suggestion.rs:9:9 + | +LL | let _ = match s { + | - this expression has type `String` +... +LL | "no" => Some(false), + | ^^^^ expected `String`, found `&str` + | +help: consider converting the `String` to a `&str` using `.as_str()` + | +LL | let _ = match s.as_str() { + | +++++++++ + +error[E0308]: mismatched types + --> $DIR/string-match-as-str-suggestion.rs:15:12 + | +LL | if let "hello" = s2 { + | ^^^^^^^ -- this expression has type `String` + | | + | expected `String`, found `&str` + | +help: consider converting the `String` to a `&str` using `.as_str()` + | +LL | if let "hello" = s2.as_str() { + | +++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From 84951293574c573c3e79a0ea503418509e9f16c6 Mon Sep 17 00:00:00 2001 From: Mads Ravn Date: Mon, 25 May 2026 21:23:46 +0200 Subject: [PATCH 2/8] Adding sign flag formatting error message --- compiler/rustc_parse_format/src/lib.rs | 19 +++++++++++++++ compiler/rustc_parse_format/src/tests.rs | 11 ++++++++- tests/ui/fmt/format-string-wrong-order.rs | 4 ++++ tests/ui/fmt/format-string-wrong-order.stderr | 24 ++++++++++++++++++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 20f4646490a6b..8f079420f7623 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -491,6 +491,7 @@ impl<'input> Parser<'input> { ('<' | '^' | '>', _) => self.suggest_format_align(c), (',', _) => self.suggest_unsupported_python_numeric_grouping(), ('=', '}') => self.suggest_rust_debug_printing_macro(), + ('+', _) => self.suggest_format_missing_colon_for_sign(), _ => self.suggest_positional_arg_instead_of_captured_arg(arg), } } @@ -939,6 +940,24 @@ impl<'input> Parser<'input> { } } + fn suggest_format_missing_colon_for_sign(&mut self) { + if let Some((range, _)) = self.consume_pos('+') { + let span = range.clone(); + self.errors.insert( + 0, + ParseError { + description: "the `+` sign flag must appear after `:` in a format string" + .to_owned(), + note: Some("`+` comes after `:`, try `{:+}` instead of `{+}`".to_owned()), + label: "expected `:` before `+` sign flag".to_owned(), + span: range, + secondary_label: None, + suggestion: Suggestion::AddMissingColon(span), + }, + ); + } + } + fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: &Argument<'_>) { // If the argument is not an identifier, it is not a field access. if !arg.is_identifier() { diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index a6c7e1890abd1..5f6d62f8b49b2 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -553,7 +553,6 @@ fn asm_concat() { assert_eq!(parser.by_ref().collect::>>(), &[Lit(asm)]); assert_eq!(parser.line_spans, &[]); } - #[test] fn diagnostic_format_flags() { let lit = "{thing:blah}"; @@ -595,3 +594,13 @@ fn diagnostic_format_mod() { assert_eq!(parser.line_spans, &[]); assert!(parser.errors.is_empty()); } +#[test] +fn format_plus_sign_missing_colon_error() { + // `{+}` should produce an error suggesting `:` before `+` + let mut p = Parser::new("{+}", None, None, false, ParseMode::Format); + let _ = p.by_ref().collect::>>(); + assert!(!p.errors.is_empty()); + assert!(p.errors[0].description.contains("`+` sign flag must appear after `:`")); + assert!(p.errors[0].label.contains("expected `:` before `+` sign flag")); + assert_eq!(p.errors[0].span, 2..3); +} diff --git a/tests/ui/fmt/format-string-wrong-order.rs b/tests/ui/fmt/format-string-wrong-order.rs index 4d4e04ecd042d..bda19fe9bebce 100644 --- a/tests/ui/fmt/format-string-wrong-order.rs +++ b/tests/ui/fmt/format-string-wrong-order.rs @@ -20,4 +20,8 @@ fn main() { //~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}` println!("{0:#X>18}", 12345); //~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}` + format!("{+:}"); + //~^ ERROR invalid format string: the `+` sign flag must appear after `:` in a format string + format!("{bar+:}"); + //~^ ERROR invalid format string: the `+` sign flag must appear after `:` in a format string } diff --git a/tests/ui/fmt/format-string-wrong-order.stderr b/tests/ui/fmt/format-string-wrong-order.stderr index 441ae6d2e505f..da1b6399ccfd7 100644 --- a/tests/ui/fmt/format-string-wrong-order.stderr +++ b/tests/ui/fmt/format-string-wrong-order.stderr @@ -74,5 +74,27 @@ error: invalid format string: expected alignment specifier after `:` in format s LL | println!("{0:#X>18}", 12345); | ^ expected `>` to occur after `:` in format string -error: aborting due to 10 previous errors +error: invalid format string: the `+` sign flag must appear after `:` in a format string + --> $DIR/format-string-wrong-order.rs:23:15 + | +LL | format!("{+:}"); + | ^ + | | + | expected `:` before `+` sign flag in format string + | help: add a colon before the format specifier: `:?` + | + = note: `+` comes after `:`, try `{:+}` instead of `{+}` + +error: invalid format string: the `+` sign flag must appear after `:` in a format string + --> $DIR/format-string-wrong-order.rs:25:18 + | +LL | format!("{bar+:}"); + | ^ + | | + | expected `:` before `+` sign flag in format string + | help: add a colon before the format specifier: `:?` + | + = note: `+` comes after `:`, try `{:+}` instead of `{+}` + +error: aborting due to 12 previous errors From 900e061dce255c2a41d6e07e9bd1ab3078f68aaf Mon Sep 17 00:00:00 2001 From: Mads Ravn Date: Mon, 25 May 2026 21:34:36 +0200 Subject: [PATCH 3/8] Removing Suggestion from ParseError and fixed tests accordingly --- compiler/rustc_parse_format/src/lib.rs | 3 +-- compiler/rustc_parse_format/src/tests.rs | 1 + tests/ui/fmt/format-string-wrong-order.stderr | 10 ++-------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 8f079420f7623..c807b9ee7b296 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -942,7 +942,6 @@ impl<'input> Parser<'input> { fn suggest_format_missing_colon_for_sign(&mut self) { if let Some((range, _)) = self.consume_pos('+') { - let span = range.clone(); self.errors.insert( 0, ParseError { @@ -952,7 +951,7 @@ impl<'input> Parser<'input> { label: "expected `:` before `+` sign flag".to_owned(), span: range, secondary_label: None, - suggestion: Suggestion::AddMissingColon(span), + suggestion: Suggestion::None, }, ); } diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index 5f6d62f8b49b2..c5e94ad7acd46 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -553,6 +553,7 @@ fn asm_concat() { assert_eq!(parser.by_ref().collect::>>(), &[Lit(asm)]); assert_eq!(parser.line_spans, &[]); } + #[test] fn diagnostic_format_flags() { let lit = "{thing:blah}"; diff --git a/tests/ui/fmt/format-string-wrong-order.stderr b/tests/ui/fmt/format-string-wrong-order.stderr index da1b6399ccfd7..eaaac2b9d8566 100644 --- a/tests/ui/fmt/format-string-wrong-order.stderr +++ b/tests/ui/fmt/format-string-wrong-order.stderr @@ -78,10 +78,7 @@ error: invalid format string: the `+` sign flag must appear after `:` in a forma --> $DIR/format-string-wrong-order.rs:23:15 | LL | format!("{+:}"); - | ^ - | | - | expected `:` before `+` sign flag in format string - | help: add a colon before the format specifier: `:?` + | ^ expected `:` before `+` sign flag in format string | = note: `+` comes after `:`, try `{:+}` instead of `{+}` @@ -89,10 +86,7 @@ error: invalid format string: the `+` sign flag must appear after `:` in a forma --> $DIR/format-string-wrong-order.rs:25:18 | LL | format!("{bar+:}"); - | ^ - | | - | expected `:` before `+` sign flag in format string - | help: add a colon before the format specifier: `:?` + | ^ expected `:` before `+` sign flag in format string | = note: `+` comes after `:`, try `{:+}` instead of `{+}` From bc12569f94d8f27baa93f501bae0ca96f2484a39 Mon Sep 17 00:00:00 2001 From: Redddy Date: Sat, 23 May 2026 13:53:43 +0000 Subject: [PATCH 4/8] rustdoc: avoid ICE when rendering body-less type consts --- src/librustdoc/clean/utils.rs | 6 ++++-- .../type-const-associated-const-no-body.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/rustdoc-ui/type-const-associated-const-no-body.rs diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index ff4f5c115ffa9..253d4dcf9f2a5 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -351,8 +351,10 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { pub(crate) fn print_const(tcx: TyCtxt<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { - if let Some(def) = def.as_local() { - rendered_const(tcx, tcx.hir_body_owned_by(def), def) + if let Some(def) = def.as_local() + && let Some(body_id) = tcx.hir_maybe_body_owned_by(def) + { + rendered_const(tcx, body_id, def) } else { inline::print_inlined_const(tcx, def) } diff --git a/tests/rustdoc-ui/type-const-associated-const-no-body.rs b/tests/rustdoc-ui/type-const-associated-const-no-body.rs new file mode 100644 index 0000000000000..66a60c7fc7246 --- /dev/null +++ b/tests/rustdoc-ui/type-const-associated-const-no-body.rs @@ -0,0 +1,16 @@ +//! Regression test for +//! Ensure that rustdoc does not ICE when a body-less type const is used +//! as an associated const. +//@ check-pass + +#![feature(min_generic_const_args)] + +pub trait Tr { + type const SIZE: usize; +} + +fn mk_array() -> [(); ::SIZE] { + [(); T::SIZE] +} + +fn main() {} From 9e96efac62648c46bb141d274462874e6fa1e42f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 26 May 2026 00:45:46 +0200 Subject: [PATCH 5/8] Remove unneeded `#[skip_arg]` attributes --- compiler/rustc_attr_parsing/src/session_diagnostics.rs | 8 -------- compiler/rustc_trait_selection/src/errors.rs | 9 --------- 2 files changed, 17 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 5b715005f1076..ea5c9077dcde6 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -274,11 +274,7 @@ pub(crate) enum IncorrectReprFormatGenericCause { Int { #[primary_span] span: Span, - - #[skip_arg] name: Symbol, - - #[skip_arg] value: u128, }, @@ -290,11 +286,7 @@ pub(crate) enum IncorrectReprFormatGenericCause { Symbol { #[primary_span] span: Span, - - #[skip_arg] name: Symbol, - - #[skip_arg] value: Symbol, }, } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 3610ffbb30c3b..5a926dc46c707 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -869,7 +869,6 @@ pub(crate) enum ExplicitLifetimeRequired<'a> { style = "verbose" )] new_ty_span: Span, - #[skip_arg] new_ty: Ty<'a>, }, #[diag("explicit lifetime required in parameter type", code = E0621)] @@ -885,7 +884,6 @@ pub(crate) enum ExplicitLifetimeRequired<'a> { style = "verbose" )] new_ty_span: Span, - #[skip_arg] new_ty: Ty<'a>, }, } @@ -1519,7 +1517,6 @@ pub(crate) enum FunctionPointerSuggestion<'a> { RemoveRef { #[primary_span] span: Span, - #[skip_arg] fn_name: String, }, #[suggestion( @@ -1531,9 +1528,7 @@ pub(crate) enum FunctionPointerSuggestion<'a> { CastRef { #[primary_span] span: Span, - #[skip_arg] fn_name: String, - #[skip_arg] sig: Binder<'a, FnSig<'a>>, }, #[suggestion( @@ -1545,7 +1540,6 @@ pub(crate) enum FunctionPointerSuggestion<'a> { Cast { #[primary_span] span: Span, - #[skip_arg] sig: Binder<'a, FnSig<'a>>, }, #[suggestion( @@ -1557,7 +1551,6 @@ pub(crate) enum FunctionPointerSuggestion<'a> { CastBoth { #[primary_span] span: Span, - #[skip_arg] found_sig: Binder<'a, FnSig<'a>>, expected_sig: Binder<'a, FnSig<'a>>, }, @@ -1570,9 +1563,7 @@ pub(crate) enum FunctionPointerSuggestion<'a> { CastBothRef { #[primary_span] span: Span, - #[skip_arg] fn_name: String, - #[skip_arg] found_sig: Binder<'a, FnSig<'a>>, expected_sig: Binder<'a, FnSig<'a>>, }, From 92194469a07a150a96e1e9ee8672424bcbf7bc7c Mon Sep 17 00:00:00 2001 From: b1yd <2156864690@qq.com> Date: Tue, 26 May 2026 11:20:51 +0000 Subject: [PATCH 6/8] fix issue-144595 --- compiler/rustc_parse/src/errors.rs | 25 +++++++++++++++++ compiler/rustc_parse/src/parser/item.rs | 27 ++++++++++++++++--- tests/ui/parser/field-name-in-tuple-struct.rs | 6 +++++ .../parser/field-name-in-tuple-struct.stderr | 18 +++++++++++++ 4 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 tests/ui/parser/field-name-in-tuple-struct.rs create mode 100644 tests/ui/parser/field-name-in-tuple-struct.stderr diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index a0b6321a6c437..2d9e0a857bf5e 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -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, +} diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index bed03800d3f4c..3f6429c6a60f0 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -23,7 +23,10 @@ use super::{ 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 @@ impl<'a> Parser<'a> { Safety::Default } } - + /// This is the case where we find `struct Foo(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> { - // This is the case where we find `struct Foo(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 @@ impl<'a> Parser<'a> { } }; 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 @@ impl<'a> Parser<'a> { }) }) .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. diff --git a/tests/ui/parser/field-name-in-tuple-struct.rs b/tests/ui/parser/field-name-in-tuple-struct.rs new file mode 100644 index 0000000000000..f2ccdd8cfdf29 --- /dev/null +++ b/tests/ui/parser/field-name-in-tuple-struct.rs @@ -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: diff --git a/tests/ui/parser/field-name-in-tuple-struct.stderr b/tests/ui/parser/field-name-in-tuple-struct.stderr new file mode 100644 index 0000000000000..0b0964f29033d --- /dev/null +++ b/tests/ui/parser/field-name-in-tuple-struct.stderr @@ -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 + From f7c35686aa375650c5c694d96c44a7e884e3d207 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 26 May 2026 16:39:09 +0200 Subject: [PATCH 7/8] add field_projections fixme --- compiler/rustc_next_trait_solver/src/solve/trait_goals.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f3ace5a70c69c..e09864295020f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -898,6 +898,8 @@ where predicate: TraitRef::new(ecx.cx(), sized_trait, [ty]).upcast(ecx.cx()), }, ); + // FIXME(field_projections): This function does some questionable incomplete stuff by + // returning `Err(NoSolution)` on ambiguity. ecx.try_evaluate_added_goals()? == Certainty::Yes } && match base.kind() { From a2b21900b40c2d3d3009b8d9e7ecd143416a6b18 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 26 May 2026 17:16:20 +0200 Subject: [PATCH 8/8] Move check_cfg out of diagnostic attr module --- compiler/rustc_attr_parsing/src/attributes/cfg.rs | 3 +-- compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs | 1 - .../src/{attributes/diagnostic => }/check_cfg.rs | 0 compiler/rustc_attr_parsing/src/lib.rs | 1 + triagebot.toml | 2 +- 5 files changed, 3 insertions(+), 4 deletions(-) rename compiler/rustc_attr_parsing/src/{attributes/diagnostic => }/check_cfg.rs (100%) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 4c5616084cb0b..edbb4b2c2ead9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -20,7 +20,6 @@ use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; use thin_vec::ThinVec; use crate::attributes::AttributeSafety; -use crate::attributes::diagnostic::check_cfg; use crate::context::{AcceptContext, ShouldEmit}; use crate::parser::{ AllowExprMetavar, ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser, @@ -29,7 +28,7 @@ use crate::session_diagnostics::{ AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg, ParsedDescription, }; -use crate::{AttributeParser, parse_version, session_diagnostics}; +use crate::{AttributeParser, check_cfg, parse_version, session_diagnostics}; pub const CFG_TEMPLATE: AttributeTemplate = template!( List: &["predicate"], diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs index 9b4ffc7ea27f6..12c16605196d2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs @@ -23,7 +23,6 @@ use crate::errors::{ }; use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItemParser}; -pub(crate) mod check_cfg; pub(crate) mod do_not_recommend; pub(crate) mod on_const; pub(crate) mod on_move; diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs b/compiler/rustc_attr_parsing/src/check_cfg.rs similarity index 100% rename from compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs rename to compiler/rustc_attr_parsing/src/check_cfg.rs diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 24e10e19ca976..3fa11d05d062f 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -106,6 +106,7 @@ mod interface; /// like lists or name-value pairs. pub mod parser; +mod check_cfg; mod early_parsed; mod errors; mod safety; diff --git a/triagebot.toml b/triagebot.toml index 63bdd45bdcca2..ff87f182e0e4a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1050,7 +1050,7 @@ cc = ["@Nadrieril"] message = "Some changes occurred in cfg and check-cfg configuration" cc = ["@Urgau"] -[mentions."compiler/rustc_attr_parsing/src/attributes/diagnostic/check_cfg.rs"] +[mentions."compiler/rustc_attr_parsing/src/check_cfg.rs"] message = "Some changes occurred in check-cfg diagnostics" cc = ["@Urgau"]