]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_span/src/source_map.rs
Rollup merge of #104233 - compiler-errors:issue-104209, r=lcnr
[rust.git] / compiler / rustc_span / src / source_map.rs
index f9566eeee9465949b17e4c133a7b7f3d5d31e1ff..7ea028b12efc41f40fe19250c427ddd5608e68bf 100644 (file)
@@ -753,6 +753,50 @@ pub fn span_until_char(&self, sp: Span, c: char) -> Span {
         }
     }
 
+    /// 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 {
+        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;
+            while let Some(cc) = end_src.chars().nth(i) {
+                if cc == ' ' {
+                    i = i + 1;
+                } else if cc == '>' {
+                    // found > in the right;
+                    break;
+                } else {
+                    // failed to find '>' return false immediately
+                    return Ok(false);
+                }
+            }
+            // test the left side to match '<' after skipping white space
+            i = start_index;
+            let start_src = &src[0..start_index];
+            while let Some(cc) = start_src.chars().nth(i) {
+                if cc == ' ' {
+                    if i == 0 {
+                        return Ok(false);
+                    }
+                    i = i - 1;
+                } else if cc == '<' {
+                    // found < in the left
+                    break;
+                } else {
+                    // failed to find '<' return false immediately
+                    return Ok(false);
+                }
+            }
+            return Ok(true);
+        })
+        .map_or(false, |is_accessible| is_accessible)
+    }
+
     /// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char`
     /// `c`.
     pub fn span_through_char(&self, sp: Span, c: char) -> Span {
@@ -855,7 +899,8 @@ pub fn end_point(&self, sp: Span) -> Span {
     /// Returns a new span representing the next character after the end-point of this span.
     /// Special cases:
     /// - if span is a dummy one, returns the same span
-    /// - if next_point reached the end of source, return span with lo = hi
+    /// - if next_point reached the end of source, return a span exceeding the end of source,
+    ///   which means sm.span_to_snippet(next_point) will get `Err`
     /// - respect multi-byte characters
     pub fn next_point(&self, sp: Span) -> Span {
         if sp.is_dummy() {
@@ -864,9 +909,6 @@ pub fn next_point(&self, sp: Span) -> Span {
         let start_of_next_point = sp.hi().0;
 
         let width = self.find_width_of_character_at_span(sp, true);
-        if width == 0 {
-            return Span::new(sp.hi(), sp.hi(), sp.ctxt(), None);
-        }
         // If the width is 1, then the next span should only contain the next char besides current ending.
         // However, in the case of a multibyte character, where the width != 1, the next span should
         // span multiple bytes to include the whole character.
@@ -938,7 +980,7 @@ fn find_width_of_character_at_span(&self, sp: Span, forwards: bool) -> u32 {
         // Ensure indexes are also not malformed.
         if start_index > end_index || end_index > source_len - 1 {
             debug!("find_width_of_character_at_span: source indexes are malformed");
-            return 0;
+            return 1;
         }
 
         let src = local_begin.sf.external_src.borrow();