Skip to content

Commit

Permalink
Rollup merge of #104497 - lyming2007:issue-104379-fix, r=fee1-dead
Browse files Browse the repository at this point in the history
detect () to avoid redundant <> suggestion for type

fix #104379
  • Loading branch information
matthiaskrgr authored Nov 19, 2022
2 parents 06707c0 + 867582e commit e86f184
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1918,12 +1918,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Str
| ty::Projection(_)
| ty::Param(_) => format!("{deref_ty}"),
// we need to test something like <&[_]>::len
// we need to test something like <&[_]>::len or <(&[u32])>::len
// and Vec::function();
// <&[_]>::len doesn't need an extra "<>" between
// <&[_]>::len or <&[u32]>::len doesn't need an extra "<>" between
// but for Adt type like Vec::function()
// we would suggest <[_]>::function();
_ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"),
_ if self.tcx.sess.source_map().span_wrapped_by_angle_or_parentheses(ty.span) => format!("{deref_ty}"),
_ => format!("<{deref_ty}>"),
};
err.span_suggestion_verbose(
Expand Down
25 changes: 21 additions & 4 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,22 +753,29 @@ impl SourceMap {
}
}

/// Given a 'Span', tries to tell if the next character is '>'
/// and the previous charactoer is '<' after skipping white space
/// return true if wrapped by '<>'
pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
/// Given a 'Span', tries to tell if it's wrapped by "<>" or "()"
/// the algorithm searches if the next character is '>' or ')' after skipping white space
/// then searches the previous charactoer to match '<' or '(' after skipping white space
/// return true if wrapped by '<>' or '()'
pub fn span_wrapped_by_angle_or_parentheses(&self, span: Span) -> bool {
self.span_to_source(span, |src, start_index, end_index| {
if src.get(start_index..end_index).is_none() {
return Ok(false);
}
// test the right side to match '>' after skipping white space
let end_src = &src[end_index..];
let mut i = 0;
let mut found_right_parentheses = false;
let mut found_right_angle = false;
while let Some(cc) = end_src.chars().nth(i) {
if cc == ' ' {
i = i + 1;
} else if cc == '>' {
// found > in the right;
found_right_angle = true;
break;
} else if cc == ')' {
found_right_parentheses = true;
break;
} else {
// failed to find '>' return false immediately
Expand All @@ -786,6 +793,16 @@ impl SourceMap {
i = i - 1;
} else if cc == '<' {
// found < in the left
if !found_right_angle {
// skip something like "(< )>"
return Ok(false);
}
break;
} else if cc == '(' {
if !found_right_parentheses {
// skip something like "<(>)"
return Ok(false);
}
break;
} else {
// failed to find '<' return false immediately
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/type/issue-103271.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ fn main() {
let x: &u32 = item;
assert_eq!(x, &1);
}
let iter_fun2 = <(&[u32])>::iter;
//~^ no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599]
//~| function or associated item not found in `&[u32]`
//~| HELP the function `iter` is implemented on `[u32]`
for item2 in iter_fun2(&[1,1]) {
let x: &u32 = item2;
assert_eq!(x, &1);
}
}
13 changes: 12 additions & 1 deletion src/test/ui/type/issue-103271.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ help: the function `iter` is implemented on `[u32]`
LL | let iter_fun = <[u32]>::iter;
| ~~~~~

error: aborting due to previous error
error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope
--> $DIR/issue-103271.rs:10:33
|
LL | let iter_fun2 = <(&[u32])>::iter;
| ^^^^ function or associated item not found in `&[u32]`
|
help: the function `iter` is implemented on `[u32]`
|
LL | let iter_fun2 = <([u32])>::iter;
| ~~~~~

error: aborting due to 2 previous errors

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

0 comments on commit e86f184

Please sign in to comment.