Skip to content

Commit e86f184

Browse files
authored
Rollup merge of #104497 - lyming2007:issue-104379-fix, r=fee1-dead
detect () to avoid redundant <> suggestion for type fix #104379
2 parents 06707c0 + 867582e commit e86f184

File tree

4 files changed

+44
-8
lines changed

4 files changed

+44
-8
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1918,12 +1918,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19181918
| ty::Str
19191919
| ty::Projection(_)
19201920
| ty::Param(_) => format!("{deref_ty}"),
1921-
// we need to test something like <&[_]>::len
1921+
// we need to test something like <&[_]>::len or <(&[u32])>::len
19221922
// and Vec::function();
1923-
// <&[_]>::len doesn't need an extra "<>" between
1923+
// <&[_]>::len or <&[u32]>::len doesn't need an extra "<>" between
19241924
// but for Adt type like Vec::function()
19251925
// we would suggest <[_]>::function();
1926-
_ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"),
1926+
_ if self.tcx.sess.source_map().span_wrapped_by_angle_or_parentheses(ty.span) => format!("{deref_ty}"),
19271927
_ => format!("<{deref_ty}>"),
19281928
};
19291929
err.span_suggestion_verbose(

compiler/rustc_span/src/source_map.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -753,22 +753,29 @@ impl SourceMap {
753753
}
754754
}
755755

756-
/// Given a 'Span', tries to tell if the next character is '>'
757-
/// and the previous charactoer is '<' after skipping white space
758-
/// return true if wrapped by '<>'
759-
pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
756+
/// Given a 'Span', tries to tell if it's wrapped by "<>" or "()"
757+
/// the algorithm searches if the next character is '>' or ')' after skipping white space
758+
/// then searches the previous charactoer to match '<' or '(' after skipping white space
759+
/// return true if wrapped by '<>' or '()'
760+
pub fn span_wrapped_by_angle_or_parentheses(&self, span: Span) -> bool {
760761
self.span_to_source(span, |src, start_index, end_index| {
761762
if src.get(start_index..end_index).is_none() {
762763
return Ok(false);
763764
}
764765
// test the right side to match '>' after skipping white space
765766
let end_src = &src[end_index..];
766767
let mut i = 0;
768+
let mut found_right_parentheses = false;
769+
let mut found_right_angle = false;
767770
while let Some(cc) = end_src.chars().nth(i) {
768771
if cc == ' ' {
769772
i = i + 1;
770773
} else if cc == '>' {
771774
// found > in the right;
775+
found_right_angle = true;
776+
break;
777+
} else if cc == ')' {
778+
found_right_parentheses = true;
772779
break;
773780
} else {
774781
// failed to find '>' return false immediately
@@ -786,6 +793,16 @@ impl SourceMap {
786793
i = i - 1;
787794
} else if cc == '<' {
788795
// found < in the left
796+
if !found_right_angle {
797+
// skip something like "(< )>"
798+
return Ok(false);
799+
}
800+
break;
801+
} else if cc == '(' {
802+
if !found_right_parentheses {
803+
// skip something like "<(>)"
804+
return Ok(false);
805+
}
789806
break;
790807
} else {
791808
// failed to find '<' return false immediately

src/test/ui/type/issue-103271.rs

+8
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@ fn main() {
77
let x: &u32 = item;
88
assert_eq!(x, &1);
99
}
10+
let iter_fun2 = <(&[u32])>::iter;
11+
//~^ no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599]
12+
//~| function or associated item not found in `&[u32]`
13+
//~| HELP the function `iter` is implemented on `[u32]`
14+
for item2 in iter_fun2(&[1,1]) {
15+
let x: &u32 = item2;
16+
assert_eq!(x, &1);
17+
}
1018
}

src/test/ui/type/issue-103271.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ help: the function `iter` is implemented on `[u32]`
99
LL | let iter_fun = <[u32]>::iter;
1010
| ~~~~~
1111

12-
error: aborting due to previous error
12+
error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope
13+
--> $DIR/issue-103271.rs:10:33
14+
|
15+
LL | let iter_fun2 = <(&[u32])>::iter;
16+
| ^^^^ function or associated item not found in `&[u32]`
17+
|
18+
help: the function `iter` is implemented on `[u32]`
19+
|
20+
LL | let iter_fun2 = <([u32])>::iter;
21+
| ~~~~~
22+
23+
error: aborting due to 2 previous errors
1324

1425
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)