diff options
| author | Yiming Lei <yiming.lei@futurewei.com> | 2022-11-16 10:13:51 -0800 |
|---|---|---|
| committer | Yiming Lei <yiming.lei@futurewei.com> | 2022-11-17 09:01:27 -0800 |
| commit | 867582eb9710b08e88d45ca8d2a452efd3233fea (patch) | |
| tree | 50cc46dcf11880b303e4f4936f40ffa429829b1f /compiler | |
| parent | 63c748ee23ab7b6706655146f5b7c7f579811803 (diff) | |
| download | rust-867582eb9710b08e88d45ca8d2a452efd3233fea.tar.gz rust-867582eb9710b08e88d45ca8d2a452efd3233fea.zip | |
detect () to avoid redundant <> suggestion for type
fix #104379
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/method/suggest.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_span/src/source_map.rs | 25 |
2 files changed, 24 insertions, 7 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index edfe12963dc..5ab1581b6e0 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1926,12 +1926,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( diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 7ea028b12ef..e8d129d733c 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -753,10 +753,11 @@ 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); @@ -764,11 +765,17 @@ impl SourceMap { // 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 @@ -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 |
