From d824edfc2c063cff6e6536a1fcb56be6d89fa0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 12 Aug 2019 23:31:13 -0700 Subject: [PATCH 1/3] Do not ICE when synthesizing spans falling inside unicode chars --- src/libsyntax/source_map.rs | 6 ++++++ src/test/ui/suggestions/issue-61226.rs | 5 +++++ src/test/ui/suggestions/issue-61226.stderr | 17 +++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/test/ui/suggestions/issue-61226.rs create mode 100644 src/test/ui/suggestions/issue-61226.stderr diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 4e29c77c89e42..3c58cfbbb2bea 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -554,8 +554,14 @@ impl SourceMap { } if let Some(ref src) = local_begin.sf.src { + if !src.is_char_boundary(start_index) || !src.is_char_boundary(end_index) { + return Err(SpanSnippetError::IllFormedSpan(sp)); + } return Ok(extract_source(src, start_index, end_index)); } else if let Some(src) = local_begin.sf.external_src.borrow().get_source() { + if !src.is_char_boundary(start_index) || !src.is_char_boundary(end_index) { + return Err(SpanSnippetError::IllFormedSpan(sp)); + } return Ok(extract_source(src, start_index, end_index)); } else { return Err(SpanSnippetError::SourceNotAvailable { diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs new file mode 100644 index 0000000000000..1eed55e5f9ffd --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.rs @@ -0,0 +1,5 @@ +struct X {} +fn f() { + vec![X]; //… + //~^ ERROR expected value, found struct `X` +} diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr new file mode 100644 index 0000000000000..ac27fb1f75822 --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -0,0 +1,17 @@ +error[E0423]: expected value, found struct `X` + --> $DIR/issue-61226.rs:3:10 + | +LL | vec![X]; //… + | ^ + | | + | did you mean `X { /* fields */ }`? + | help: a function with a similar name exists: `f` + +error[E0601]: `main` function not found in crate `issue_61226` + | + = note: consider adding a `main` function to `$DIR/issue-61226.rs` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0601. +For more information about an error, try `rustc --explain E0423`. From 105b3a0b02baa0dd974731648ae9438ba420811b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Aug 2019 09:01:56 -0700 Subject: [PATCH 2/3] review comment: remove unecessary error in test --- src/test/ui/suggestions/issue-61226.rs | 2 +- src/test/ui/suggestions/issue-61226.stderr | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs index 1eed55e5f9ffd..e83b0b4d6308d 100644 --- a/src/test/ui/suggestions/issue-61226.rs +++ b/src/test/ui/suggestions/issue-61226.rs @@ -1,5 +1,5 @@ struct X {} -fn f() { +fn main() { vec![X]; //… //~^ ERROR expected value, found struct `X` } diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr index ac27fb1f75822..6d7d98ac6a16b 100644 --- a/src/test/ui/suggestions/issue-61226.stderr +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -2,16 +2,8 @@ error[E0423]: expected value, found struct `X` --> $DIR/issue-61226.rs:3:10 | LL | vec![X]; //… - | ^ - | | - | did you mean `X { /* fields */ }`? - | help: a function with a similar name exists: `f` + | ^ did you mean `X { /* fields */ }`? -error[E0601]: `main` function not found in crate `issue_61226` - | - = note: consider adding a `main` function to `$DIR/issue-61226.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0423, E0601. -For more information about an error, try `rustc --explain E0423`. +For more information about this error, try `rustc --explain E0423`. From 84e202e6b36250dfc319aa5a869ad1df29b4b55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Aug 2019 11:35:49 -0700 Subject: [PATCH 3/3] review comments --- src/libsyntax/source_map.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 3c58cfbbb2bea..74cab00d3c1eb 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -519,7 +519,7 @@ impl SourceMap { /// extract function takes three arguments: a string slice containing the source, an index in /// the slice for the beginning of the span and an index in the slice for the end of the span. fn span_to_source(&self, sp: Span, extract_source: F) -> Result - where F: Fn(&str, usize, usize) -> String + where F: Fn(&str, usize, usize) -> Result { if sp.lo() > sp.hi() { return Err(SpanSnippetError::IllFormedSpan(sp)); @@ -554,15 +554,9 @@ impl SourceMap { } if let Some(ref src) = local_begin.sf.src { - if !src.is_char_boundary(start_index) || !src.is_char_boundary(end_index) { - return Err(SpanSnippetError::IllFormedSpan(sp)); - } - return Ok(extract_source(src, start_index, end_index)); + return extract_source(src, start_index, end_index); } else if let Some(src) = local_begin.sf.external_src.borrow().get_source() { - if !src.is_char_boundary(start_index) || !src.is_char_boundary(end_index) { - return Err(SpanSnippetError::IllFormedSpan(sp)); - } - return Ok(extract_source(src, start_index, end_index)); + return extract_source(src, start_index, end_index); } else { return Err(SpanSnippetError::SourceNotAvailable { filename: local_begin.sf.name.clone() @@ -573,8 +567,9 @@ impl SourceMap { /// Returns the source snippet as `String` corresponding to the given `Span` pub fn span_to_snippet(&self, sp: Span) -> Result { - self.span_to_source(sp, |src, start_index, end_index| src[start_index..end_index] - .to_string()) + self.span_to_source(sp, |src, start_index, end_index| src.get(start_index..end_index) + .map(|s| s.to_string()) + .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp))) } pub fn span_to_margin(&self, sp: Span) -> Option { @@ -588,7 +583,9 @@ impl SourceMap { /// Returns the source snippet as `String` before the given `Span` pub fn span_to_prev_source(&self, sp: Span) -> Result { - self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string()) + self.span_to_source(sp, |src, start_index, _| src.get(..start_index) + .map(|s| s.to_string()) + .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp))) } /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span