Skip to content

Commit

Permalink
Auto merge of #46653 - estebank:str-as-ch, r=petrochenkov
Browse files Browse the repository at this point in the history
When attempting to write str with single quote suggest double quotes

Fix #26101.
  • Loading branch information
bors committed Dec 15, 2017
2 parents 84feab3 + c60aab2 commit 04b2344
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/librustc_errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ crate-type = ["dylib"]
serialize = { path = "../libserialize" }
syntax_pos = { path = "../libsyntax_pos" }
rustc_data_structures = { path = "../librustc_data_structures" }
unicode-width = "0.1.4"
6 changes: 5 additions & 1 deletion src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use std::rc::Rc;
use term;
use std::collections::HashMap;
use std::cmp::min;
use unicode_width;

/// Emitter trait for emitting errors.
pub trait Emitter {
Expand Down Expand Up @@ -1182,7 +1183,10 @@ impl EmitterWriter {
if show_underline {
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
let start = parts[0].snippet.len() - parts[0].snippet.trim_left().len();
let sub_len = parts[0].snippet.trim().len();
// account for substitutions containing unicode characters
let sub_len = parts[0].snippet.trim().chars().fold(0, |acc, ch| {
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
});
let underline_start = span_start_pos.col.0 + start;
let underline_end = span_start_pos.col.0 + start + sub_len;
for p in underline_start..underline_end {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extern crate libc;
extern crate rustc_data_structures;
extern crate serialize as rustc_serialize;
extern crate syntax_pos;
extern crate unicode_width;

pub use emitter::ColorConfig;

Expand Down
28 changes: 27 additions & 1 deletion src/libsyntax/parse/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1306,8 +1306,34 @@ impl<'a> StringReader<'a> {
'\'');

if !self.ch_is('\'') {
let pos = self.pos;
loop {
self.bump();
if self.ch_is('\'') {
let start = self.byte_offset(start).to_usize();
let end = self.byte_offset(self.pos).to_usize();
self.bump();
let span = self.mk_sp(start_with_quote, self.pos);
self.sess.span_diagnostic
.struct_span_err(span,
"character literal may only contain one codepoint")
.span_suggestion(span,
"if you meant to write a `str` literal, \
use double quotes",
format!("\"{}\"",
&self.source_text[start..end]))
.emit();
return Ok(token::Literal(token::Str_(Symbol::intern("??")), None))
}
if self.ch_is('\n') || self.is_eof() || self.ch_is('/') {
// Only attempt to infer single line string literals. If we encounter
// a slash, bail out in order to avoid nonsensical suggestion when
// involving comments.
break;
}
}
panic!(self.fatal_span_verbose(
start_with_quote, self.pos,
start_with_quote, pos,
String::from("character literal may only contain one codepoint")));
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/parse-fail/lex-bad-char-literals-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

// This test needs to the last one appearing in this file as it kills the parser
static c: char =
'●●' //~ ERROR: character literal may only contain one codepoint: '●
'●●' //~ ERROR: character literal may only contain one codepoint
;
2 changes: 1 addition & 1 deletion src/test/parse-fail/lex-bad-char-literals-5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
//
// This test needs to the last one appearing in this file as it kills the parser
static c: char =
'\x10\x10' //~ ERROR: character literal may only contain one codepoint: '\x10
'\x10\x10' //~ ERROR: character literal may only contain one codepoint
;
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/str-as-char.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
println!('●●');
//~^ ERROR character literal may only contain one codepoint
}
12 changes: 12 additions & 0 deletions src/test/ui/suggestions/str-as-char.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: character literal may only contain one codepoint
--> $DIR/str-as-char.rs:12:14
|
12 | println!('●●');
| ^^^^
help: if you meant to write a `str` literal, use double quotes
|
12 | println!("●●");
| ^^^^

error: aborting due to previous error

0 comments on commit 04b2344

Please sign in to comment.