Skip to content

Commit d562f48

Browse files
committed
suggest &str.chars() on attempt to &str.iter()
check if `String` or `&String` or `&str` Update compiler/rustc_typeck/src/check/method/suggest.rs Co-authored-by: Esteban Kuber <estebank@users.noreply.github.com> remove some trailing whitespace
1 parent 9dbbbb1 commit d562f48

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

Diff for: compiler/rustc_typeck/src/check/method/suggest.rs

+20
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478478
let mut label_span_not_found = || {
479479
if unsatisfied_predicates.is_empty() {
480480
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
481+
let is_string_or_ref_str = match actual.kind() {
482+
ty::Ref(_, ty, _) => {
483+
ty.is_str()
484+
|| matches!(
485+
ty.kind(),
486+
ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did)
487+
)
488+
}
489+
ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did),
490+
_ => false,
491+
};
492+
if is_string_or_ref_str && item_name.name == sym::iter {
493+
err.span_suggestion_verbose(
494+
item_name.span,
495+
"because of the in-memory representation of `&str`, to obtain \
496+
an `Iterator` over each of its codepoint use method `chars`",
497+
String::from("chars"),
498+
Applicability::MachineApplicable,
499+
);
500+
}
481501
if let ty::Adt(adt, _) = rcvr_ty.kind() {
482502
let mut inherent_impls_candidate = self
483503
.tcx

Diff for: src/test/ui/suggest-using-chars.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub fn main() {
2+
let _ = "foo".iter(); //~ ERROR no method named `iter` found for reference `&'static str` in the current scope
3+
let _ = "foo".foo(); //~ ERROR no method named `foo` found for reference `&'static str` in the current scope
4+
let _ = String::from("bar").iter(); //~ ERROR no method named `iter` found for struct `String` in the current scope
5+
let _ = (&String::from("bar")).iter(); //~ ERROR no method named `iter` found for reference `&String` in the current scope
6+
let _ = 0.iter(); //~ ERROR no method named `iter` found for type `{integer}` in the current scope
7+
}

Diff for: src/test/ui/suggest-using-chars.stderr

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error[E0599]: no method named `iter` found for reference `&'static str` in the current scope
2+
--> $DIR/suggest-using-chars.rs:2:19
3+
|
4+
LL | let _ = "foo".iter();
5+
| ^^^^ method not found in `&'static str`
6+
|
7+
help: because of the in-memory representation of `&str`, to obtain an `Iterator` over each of its codepoint use method `chars`
8+
|
9+
LL | let _ = "foo".chars();
10+
| ~~~~~
11+
12+
error[E0599]: no method named `foo` found for reference `&'static str` in the current scope
13+
--> $DIR/suggest-using-chars.rs:3:19
14+
|
15+
LL | let _ = "foo".foo();
16+
| ^^^ method not found in `&'static str`
17+
18+
error[E0599]: no method named `iter` found for struct `String` in the current scope
19+
--> $DIR/suggest-using-chars.rs:4:33
20+
|
21+
LL | let _ = String::from("bar").iter();
22+
| ^^^^ method not found in `String`
23+
|
24+
help: because of the in-memory representation of `&str`, to obtain an `Iterator` over each of its codepoint use method `chars`
25+
|
26+
LL | let _ = String::from("bar").chars();
27+
| ~~~~~
28+
29+
error[E0599]: no method named `iter` found for reference `&String` in the current scope
30+
--> $DIR/suggest-using-chars.rs:5:36
31+
|
32+
LL | let _ = (&String::from("bar")).iter();
33+
| ^^^^ method not found in `&String`
34+
|
35+
help: because of the in-memory representation of `&str`, to obtain an `Iterator` over each of its codepoint use method `chars`
36+
|
37+
LL | let _ = (&String::from("bar")).chars();
38+
| ~~~~~
39+
40+
error[E0599]: no method named `iter` found for type `{integer}` in the current scope
41+
--> $DIR/suggest-using-chars.rs:6:15
42+
|
43+
LL | let _ = 0.iter();
44+
| ^^^^ method not found in `{integer}`
45+
46+
error: aborting due to 5 previous errors
47+
48+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)