From fe0663c33d24c903812ec0fe58b94d68aa275b98 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 18 May 2025 15:53:03 +0800 Subject: [PATCH 1/4] Add test sugg-field-in-format-string-issue-141136 Signed-off-by: xizheyin --- ...ugg-field-in-format-string-issue-141136.rs | 14 ++++++ ...field-in-format-string-issue-141136.stderr | 46 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs create mode 100644 tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr diff --git a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs new file mode 100644 index 0000000000000..e0c2f49604617 --- /dev/null +++ b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs @@ -0,0 +1,14 @@ +struct Foo { + x: i32 +} + +impl Foo { + fn foo(&self) { + let _ = format!("{x}"); //~ ERROR cannot find value `x` in this scope [E0425] + let _ = format!("{x }"); //~ ERROR cannot find value `x` in this scope [E0425] + let _ = format!("{ x}"); //~ ERROR invalid format string: expected `}`, found `x` + let _ = format!("{}", x); //~ ERROR cannot find value `x` in this scope [E0425] + } +} + +fn main(){} diff --git a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr new file mode 100644 index 0000000000000..4bdefa70a0004 --- /dev/null +++ b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr @@ -0,0 +1,46 @@ +error: invalid format string: expected `}`, found `x` + --> $DIR/sugg-field-in-format-string-issue-141136.rs:9:28 + | +LL | let _ = format!("{ x}"); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error[E0425]: cannot find value `x` in this scope + --> $DIR/sugg-field-in-format-string-issue-141136.rs:7:27 + | +LL | let _ = format!("{x}"); + | ^ + | +help: you might have meant to use the available field + | +LL | let _ = format!("{self.x}"); + | +++++ + +error[E0425]: cannot find value `x` in this scope + --> $DIR/sugg-field-in-format-string-issue-141136.rs:8:27 + | +LL | let _ = format!("{x }"); + | ^^ + | +help: you might have meant to use the available field + | +LL | let _ = format!("{self.x }"); + | +++++ + +error[E0425]: cannot find value `x` in this scope + --> $DIR/sugg-field-in-format-string-issue-141136.rs:10:31 + | +LL | let _ = format!("{}", x); + | ^ + | +help: you might have meant to use the available field + | +LL | let _ = format!("{}", self.x); + | +++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. From 9de7fff0d8ab72fb57dea6255fc10fe35219db72 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 18 May 2025 16:14:48 +0800 Subject: [PATCH 2/4] Suggest use `"{}", self.x` instead of `{self.x}` when resolve `x` as field of `self` Signed-off-by: xizheyin --- .../rustc_resolve/src/late/diagnostics.rs | 30 +++++++++++++++---- ...field-in-format-string-issue-141136.stderr | 10 ++----- ...e-with-name-similar-to-struct-field.stderr | 12 ++------ 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b538be34f31f1..30c2125d0b66a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -751,12 +751,30 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { match candidate { AssocSuggestion::Field(field_span) => { if self_is_available { - err.span_suggestion_verbose( - span.shrink_to_lo(), - "you might have meant to use the available field", - format!("{pre}self."), - Applicability::MachineApplicable, - ); + let source_map = self.r.tcx.sess.source_map(); + // check if the field is used in a format string, such as `"{x}"` + let field_is_format_named_arg = + source_map.span_to_source(span, |s, start, _| { + if let Some(expanded_expr) = s.get(start - 1..start) + && expanded_expr.starts_with("{") + { + Ok(true) + } else { + Ok(false) + } + }); + if let Ok(true) = field_is_format_named_arg { + err.help( + format!("you might have meant to use the available field in a format string: `\"{{}}\", self.{}`", segment.ident.name), + ); + } else { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "you might have meant to use the available field", + format!("{pre}self."), + Applicability::MachineApplicable, + ); + } } else { err.span_label(field_span, "a field by that name exists in `Self`"); } diff --git a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr index 4bdefa70a0004..795de38d0279c 100644 --- a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr +++ b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr @@ -14,10 +14,7 @@ error[E0425]: cannot find value `x` in this scope LL | let _ = format!("{x}"); | ^ | -help: you might have meant to use the available field - | -LL | let _ = format!("{self.x}"); - | +++++ + = help: you might have meant to use the available field in a format string: `"{}", self.x` error[E0425]: cannot find value `x` in this scope --> $DIR/sugg-field-in-format-string-issue-141136.rs:8:27 @@ -25,10 +22,7 @@ error[E0425]: cannot find value `x` in this scope LL | let _ = format!("{x }"); | ^^ | -help: you might have meant to use the available field - | -LL | let _ = format!("{self.x }"); - | +++++ + = help: you might have meant to use the available field in a format string: `"{}", self.x` error[E0425]: cannot find value `x` in this scope --> $DIR/sugg-field-in-format-string-issue-141136.rs:10:31 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 5832cb69a3dd8..1ecbfee17bc70 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -20,17 +20,9 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 | LL | println!("{config}"); - | ^^^^^^ - | -help: you might have meant to use the available field - | -LL | println!("{self.config}"); - | +++++ -help: a local variable with a similar name exists - | -LL - println!("{config}"); -LL + println!("{cofig}"); + | ^^^^^^ help: a local variable with a similar name exists: `cofig` | + = help: you might have meant to use the available field in a format string: `"{}", self.config` error[E0425]: cannot find value `bah` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:33:9 From 4ec991989af4662104fdbafc43b12232887fa0b4 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 20 May 2025 14:10:17 +0800 Subject: [PATCH 3/4] Add println! test for sugg-field-in-format-string-issue-141136 Signed-off-by: xizheyin --- .../sugg-field-in-format-string-issue-141136.rs | 1 + .../sugg-field-in-format-string-issue-141136.stderr | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs index e0c2f49604617..d2aa61186bcd0 100644 --- a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs +++ b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.rs @@ -8,6 +8,7 @@ impl Foo { let _ = format!("{x }"); //~ ERROR cannot find value `x` in this scope [E0425] let _ = format!("{ x}"); //~ ERROR invalid format string: expected `}`, found `x` let _ = format!("{}", x); //~ ERROR cannot find value `x` in this scope [E0425] + println!("{x}"); //~ ERROR cannot find value `x` in this scope [E0425] } } diff --git a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr index 795de38d0279c..0a84848081d5c 100644 --- a/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr +++ b/tests/ui/resolve/suggestions/sugg-field-in-format-string-issue-141136.stderr @@ -35,6 +35,14 @@ help: you might have meant to use the available field LL | let _ = format!("{}", self.x); | +++++ -error: aborting due to 4 previous errors +error[E0425]: cannot find value `x` in this scope + --> $DIR/sugg-field-in-format-string-issue-141136.rs:11:20 + | +LL | println!("{x}"); + | ^ + | + = help: you might have meant to use the available field in a format string: `"{}", self.x` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0425`. From 84f67a5e51bf1695a0c368a9f44a15f15cdf6b9e Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 21 May 2025 16:19:51 +0800 Subject: [PATCH 4/4] Downgrade the confident of suggestion `available field in format string` and optimize expression Signed-off-by: xizheyin --- compiler/rustc_resolve/src/late/diagnostics.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 30c2125d0b66a..80d7a4dd47ac8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -753,15 +753,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if self_is_available { let source_map = self.r.tcx.sess.source_map(); // check if the field is used in a format string, such as `"{x}"` - let field_is_format_named_arg = - source_map.span_to_source(span, |s, start, _| { - if let Some(expanded_expr) = s.get(start - 1..start) - && expanded_expr.starts_with("{") - { - Ok(true) - } else { - Ok(false) - } + let field_is_format_named_arg = source_map + .span_to_source(span, |s, start, _| { + Ok(s.get(start - 1..start) == Some("{")) }); if let Ok(true) = field_is_format_named_arg { err.help( @@ -772,7 +766,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { span.shrink_to_lo(), "you might have meant to use the available field", format!("{pre}self."), - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } } else {