Skip to content

Commit dc088b2

Browse files
committed
refactor check_for_substitution
No behavior change, just flatter and simpler code
1 parent 40ab9d2 commit dc088b2

File tree

2 files changed

+72
-67
lines changed

2 files changed

+72
-67
lines changed

src/libsyntax/parse/lexer/mod.rs

-22
Original file line numberDiff line numberDiff line change
@@ -84,28 +84,6 @@ impl<'a> StringReader<'a> {
8484
Ok(ret_val)
8585
}
8686

87-
/// Immutably extract string if found at current position with given delimiters
88-
fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<String> {
89-
let mut pos = self.pos;
90-
let mut idx = self.src_index(pos);
91-
let mut ch = char_at(&self.src, idx);
92-
if ch != from_ch {
93-
return None;
94-
}
95-
pos = pos + Pos::from_usize(ch.len_utf8());
96-
let start_pos = pos;
97-
idx = self.src_index(pos);
98-
while idx < self.end_src_index {
99-
ch = char_at(&self.src, idx);
100-
if ch == to_ch {
101-
return Some(self.src[self.src_index(start_pos)..self.src_index(pos)].to_string());
102-
}
103-
pos = pos + Pos::from_usize(ch.len_utf8());
104-
idx = self.src_index(pos);
105-
}
106-
return None;
107-
}
108-
10987
fn try_real_token(&mut self) -> Result<Token, ()> {
11088
let mut t = self.try_next_token()?;
11189
loop {

src/libsyntax/parse/lexer/unicode_chars.rs

+72-45
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Characters and their corresponding confusables were collected from
22
// http://www.unicode.org/Public/security/10.0.0/confusables.txt
33

4-
use syntax_pos::{Span, Pos, NO_EXPANSION};
5-
use errors::{Applicability, DiagnosticBuilder};
64
use super::StringReader;
5+
use errors::{Applicability, DiagnosticBuilder};
6+
use syntax_pos::{Pos, Span, NO_EXPANSION};
77

8+
#[rustfmt::skip] // for line breaks
89
const UNICODE_ARRAY: &[(char, &str, char)] = &[
910
('
', "Line Separator", ' '),
1011
('
', "Paragraph Separator", ' '),
@@ -293,8 +294,8 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[
293294
('〉', "Right-Pointing Angle Bracket", '>'),
294295
('〉', "Right Angle Bracket", '>'),
295296
('》', "Right Double Angle Bracket", '>'),
296-
('>', "Fullwidth Greater-Than Sign", '>'), ];
297-
297+
('>', "Fullwidth Greater-Than Sign", '>'),
298+
];
298299

299300
const ASCII_ARRAY: &[(char, &str)] = &[
300301
(' ', "Space"),
@@ -321,46 +322,72 @@ const ASCII_ARRAY: &[(char, &str)] = &[
321322
('+', "Plus Sign"),
322323
('<', "Less-Than Sign"),
323324
('=', "Equals Sign"),
324-
('>', "Greater-Than Sign"), ];
325-
326-
crate fn check_for_substitution<'a>(reader: &StringReader<'a>,
327-
ch: char,
328-
err: &mut DiagnosticBuilder<'a>) -> bool {
329-
UNICODE_ARRAY
330-
.iter()
331-
.find(|&&(c, _, _)| c == ch)
332-
.map(|&(_, u_name, ascii_char)| {
333-
let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION);
334-
match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
335-
Some(&(ascii_char, ascii_name)) => {
336-
// special help suggestion for "directed" double quotes
337-
if let Some(s) = reader.peek_delimited('“', '”') {
338-
let msg = format!("Unicode characters '“' (Left Double Quotation Mark) and \
339-
'”' (Right Double Quotation Mark) look like '{}' ({}), but are not",
340-
ascii_char, ascii_name);
341-
err.span_suggestion(
342-
Span::new(reader.pos, reader.next_pos + Pos::from_usize(s.len()) +
343-
Pos::from_usize('”'.len_utf8()), NO_EXPANSION),
344-
&msg,
345-
format!("\"{}\"", s),
346-
Applicability::MaybeIncorrect);
347-
} else {
348-
let msg =
349-
format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not",
350-
ch, u_name, ascii_char, ascii_name);
351-
err.span_suggestion(
352-
span,
353-
&msg,
354-
ascii_char.to_string(),
355-
Applicability::MaybeIncorrect);
356-
}
357-
true
358-
},
359-
None => {
360-
let msg = format!("substitution character not found for '{}'", ch);
361-
reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
362-
false
363-
}
325+
('>', "Greater-Than Sign"),
326+
];
327+
328+
crate fn check_for_substitution<'a>(
329+
reader: &StringReader<'a>,
330+
ch: char,
331+
err: &mut DiagnosticBuilder<'a>,
332+
) -> bool {
333+
let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) {
334+
Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char),
335+
None => return false,
336+
};
337+
338+
let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION);
339+
340+
let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
341+
Some((_ascii_char, ascii_name)) => ascii_name,
342+
None => {
343+
let msg = format!("substitution character not found for '{}'", ch);
344+
reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
345+
return false
346+
},
347+
};
348+
349+
// special help suggestion for "directed" double quotes
350+
if let Some(s) = reader.peek_delimited('“', '”') {
351+
let msg = format!(
352+
"Unicode characters '“' (Left Double Quotation Mark) and \
353+
'”' (Right Double Quotation Mark) look like '{}' ({}), but are not",
354+
ascii_char, ascii_name
355+
);
356+
err.span_suggestion(
357+
Span::new(
358+
reader.pos,
359+
reader.next_pos + Pos::from_usize(s.len()) + Pos::from_usize('”'.len_utf8()),
360+
NO_EXPANSION,
361+
),
362+
&msg,
363+
format!("\"{}\"", s),
364+
Applicability::MaybeIncorrect,
365+
);
366+
} else {
367+
let msg = format!(
368+
"Unicode character '{}' ({}) looks like '{}' ({}), but it is not",
369+
ch, u_name, ascii_char, ascii_name
370+
);
371+
err.span_suggestion(
372+
span,
373+
&msg,
374+
ascii_char.to_string(),
375+
Applicability::MaybeIncorrect,
376+
);
377+
}
378+
true
379+
}
380+
381+
impl StringReader<'_> {
382+
/// Immutably extract string if found at current position with given delimiters
383+
fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<&str> {
384+
let tail = &self.src[self.src_index(self.pos)..];
385+
let mut chars = tail.chars();
386+
let first_char = chars.next()?;
387+
if first_char != from_ch {
388+
return None;
364389
}
365-
}).unwrap_or(false)
390+
let last_char_idx = chars.as_str().find(to_ch)?;
391+
Some(&chars.as_str()[..last_char_idx])
392+
}
366393
}

0 commit comments

Comments
 (0)