Skip to content

Commit 2ab5d8a

Browse files
committed
Auto merge of #57651 - JohnTitor:give-char-type, r=estebank
Implement new literal type `Err` Fixes #57384 I removed `return Ok`, otherwise, two errors occur. Any solutions? r? @estebank
2 parents 588f94b + 4005d3a commit 2ab5d8a

25 files changed

+165
-58
lines changed

src/librustc/ich/impls_syntax.rs

+2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
164164
impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
165165
impl_stable_hash_for!(enum ::syntax::ast::LitKind {
166166
Str(value, style),
167+
Err(value),
167168
ByteStr(value),
168169
Byte(value),
169170
Char(value),
@@ -329,6 +330,7 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
329330
match *lit {
330331
token::Lit::Byte(val) |
331332
token::Lit::Char(val) |
333+
token::Lit::Err(val) |
332334
token::Lit::Integer(val) |
333335
token::Lit::Float(val) |
334336
token::Lit::Str_(val) |

src/librustc_mir/hair/constant.rs

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
3737
let id = tcx.allocate_bytes(s.as_bytes());
3838
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
3939
},
40+
LitKind::Err(ref s) => {
41+
let s = s.as_str();
42+
let id = tcx.allocate_bytes(s.as_bytes());
43+
return Ok(ty::Const {
44+
val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx),
45+
ty: tcx.types.err,
46+
});
47+
},
4048
LitKind::ByteStr(ref data) => {
4149
let id = tcx.allocate_bytes(data);
4250
ConstValue::Scalar(Scalar::Ptr(id.into()))

src/librustc_typeck/check/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3121,7 +3121,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31213121
opt_ty.unwrap_or_else(
31223122
|| tcx.mk_float_var(self.next_float_var_id()))
31233123
}
3124-
ast::LitKind::Bool(_) => tcx.types.bool
3124+
ast::LitKind::Bool(_) => tcx.types.bool,
3125+
ast::LitKind::Err(_) => tcx.types.err,
31253126
}
31263127
}
31273128

src/librustdoc/html/highlight.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<'a> Classifier<'a> {
296296
token::Literal(lit, _suf) => {
297297
match lit {
298298
// Text literals.
299-
token::Byte(..) | token::Char(..) |
299+
token::Byte(..) | token::Char(..) | token::Err(..) |
300300
token::ByteStr(..) | token::ByteStrRaw(..) |
301301
token::Str_(..) | token::StrRaw(..) => Class::String,
302302

src/libsyntax/ast.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,8 @@ pub enum LitKind {
12851285
FloatUnsuffixed(Symbol),
12861286
/// A boolean literal.
12871287
Bool(bool),
1288+
/// A recovered character literal that contains mutliple `char`s, most likely a typo.
1289+
Err(Symbol),
12881290
}
12891291

12901292
impl LitKind {
@@ -1321,6 +1323,7 @@ impl LitKind {
13211323
| LitKind::ByteStr(..)
13221324
| LitKind::Byte(..)
13231325
| LitKind::Char(..)
1326+
| LitKind::Err(..)
13241327
| LitKind::Int(_, LitIntType::Unsuffixed)
13251328
| LitKind::FloatUnsuffixed(..)
13261329
| LitKind::Bool(..) => true,

src/libsyntax/attr/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ impl LitKind {
666666
} else {
667667
"false"
668668
})), false),
669+
LitKind::Err(val) => Token::Literal(token::Lit::Err(val), None),
669670
}
670671
}
671672

src/libsyntax/ext/quote.rs

+1
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
646646

647647
token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i),
648648
token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i),
649+
token::Literal(token::Err(_i), _suf) => return cx.expr(sp, ast::ExprKind::Err),
649650
token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i),
650651
token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i),
651652
token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i),

src/libsyntax/parse/lexer/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1408,9 +1408,10 @@ impl<'a> StringReader<'a> {
14081408
// lifetimes shouldn't end with a single quote
14091409
// if we find one, then this is an invalid character literal
14101410
if self.ch_is('\'') {
1411-
self.fatal_span_verbose(start_with_quote, self.next_pos,
1412-
String::from("character literal may only contain one codepoint"))
1413-
.raise();
1411+
self.err_span_(start_with_quote, self.next_pos,
1412+
"character literal may only contain one codepoint");
1413+
self.bump();
1414+
return Ok(token::Literal(token::Err(Symbol::intern("??")), None))
14141415

14151416
}
14161417

@@ -1445,7 +1446,7 @@ impl<'a> StringReader<'a> {
14451446
format!("\"{}\"", &self.src[start..end]),
14461447
Applicability::MachineApplicable
14471448
).emit();
1448-
return Ok(token::Literal(token::Str_(Symbol::intern("??")), None))
1449+
return Ok(token::Literal(token::Err(Symbol::intern("??")), None))
14491450
}
14501451
if self.ch_is('\n') || self.is_eof() || self.ch_is('/') {
14511452
// Only attempt to infer single line string literals. If we encounter

src/libsyntax/parse/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ crate fn lit_token(lit: token::Lit, suf: Option<Symbol>, diag: Option<(Span, &Ha
466466
match lit {
467467
token::Byte(i) => (true, Some(LitKind::Byte(byte_lit(&i.as_str()).0))),
468468
token::Char(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))),
469+
token::Err(i) => (true, Some(LitKind::Err(i))),
469470

470471
// There are some valid suffixes for integer and float literals,
471472
// so all the handling is done internally.

src/libsyntax/parse/token.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl DelimToken {
6060
pub enum Lit {
6161
Byte(ast::Name),
6262
Char(ast::Name),
63+
Err(ast::Name),
6364
Integer(ast::Name),
6465
Float(ast::Name),
6566
Str_(ast::Name),
@@ -73,6 +74,7 @@ impl Lit {
7374
match *self {
7475
Byte(_) => "byte literal",
7576
Char(_) => "char literal",
77+
Err(_) => "invalid literal",
7678
Integer(_) => "integer literal",
7779
Float(_) => "float literal",
7880
Str_(_) | StrRaw(..) => "string literal",
@@ -471,8 +473,7 @@ impl Token {
471473

472474
Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot |
473475
DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
474-
Question | OpenDelim(..) | CloseDelim(..) => return None,
475-
476+
Question | OpenDelim(..) | CloseDelim(..) |
476477
Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) |
477478
Whitespace | Comment | Shebang(..) | Eof => return None,
478479
})

src/libsyntax/print/pprust.rs

+9
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ pub fn token_to_string(tok: &Token) -> String {
224224
let mut out = match lit {
225225
token::Byte(b) => format!("b'{}'", b),
226226
token::Char(c) => format!("'{}'", c),
227+
token::Err(c) => format!("'{}'", c),
227228
token::Float(c) |
228229
token::Integer(c) => c.to_string(),
229230
token::Str_(s) => format!("\"{}\"", s),
@@ -603,6 +604,14 @@ pub trait PrintState<'a> {
603604
}
604605
match lit.node {
605606
ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
607+
ast::LitKind::Err(st) => {
608+
let st = st.as_str().escape_debug();
609+
let mut res = String::with_capacity(st.len() + 2);
610+
res.push('\'');
611+
res.push_str(&st);
612+
res.push('\'');
613+
self.writer().word(res)
614+
}
606615
ast::LitKind::Byte(byte) => {
607616
let mut res = String::from("b'");
608617
res.extend(ascii::escape_default(byte).map(|c| c as char));

src/libsyntax_ext/concat.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub fn expand_syntax_ext(
2323
match e.node {
2424
ast::ExprKind::Lit(ref lit) => match lit.node {
2525
ast::LitKind::Str(ref s, _)
26+
| ast::LitKind::Err(ref s)
2627
| ast::LitKind::Float(ref s, _)
2728
| ast::LitKind::FloatUnsuffixed(ref s) => {
2829
accumulator.push_str(&s.as_str());
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// This test needs to the last one appearing in this file as it kills the parser
22
static c: char =
3-
'nope' //~ ERROR: character literal may only contain one codepoint: 'nope'
3+
'nope' //~ ERROR: character literal may only contain one codepoint
44
;
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
error: character literal may only contain one codepoint: 'nope'
1+
error: character literal may only contain one codepoint
22
--> $DIR/lex-bad-char-literals-2.rs:3:5
33
|
4-
LL | 'nope' //~ ERROR: character literal may only contain one codepoint: 'nope'
4+
LL | 'nope' //~ ERROR: character literal may only contain one codepoint
55
| ^^^^^^
66

7-
error: aborting due to previous error
7+
error[E0601]: `main` function not found in crate `lex_bad_char_literals_2`
8+
|
9+
= note: consider adding a `main` function to `$DIR/lex-bad-char-literals-2.rs`
10+
11+
error: aborting due to 2 previous errors
812

13+
For more information about this error, try `rustc --explain E0601`.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// This test needs to the last one appearing in this file as it kills the parser
2-
static c: char =
3-
'●●' //~ ERROR: character literal may only contain one codepoint
4-
//~| ERROR: mismatched types
5-
;
1+
static c: char = '●●';
2+
//~^ ERROR: character literal may only contain one codepoint
63

7-
fn main() {}
4+
fn main() {
5+
let ch: &str = '●●';
6+
//~^ ERROR: character literal may only contain one codepoint
7+
}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
error: character literal may only contain one codepoint
2-
--> $DIR/lex-bad-char-literals-3.rs:3:5
2+
--> $DIR/lex-bad-char-literals-3.rs:1:18
33
|
4-
LL | '●●' //~ ERROR: character literal may only contain one codepoint
5-
| ^^^^
4+
LL | static c: char = '●●';
5+
| ^^^^
66
help: if you meant to write a `str` literal, use double quotes
77
|
8-
LL | "●●" //~ ERROR: character literal may only contain one codepoint
9-
| ^^^^
8+
LL | static c: char = "●●";
9+
| ^^^^
1010

11-
error[E0308]: mismatched types
12-
--> $DIR/lex-bad-char-literals-3.rs:3:5
11+
error: character literal may only contain one codepoint
12+
--> $DIR/lex-bad-char-literals-3.rs:5:20
1313
|
14-
LL | '●●' //~ ERROR: character literal may only contain one codepoint
15-
| ^^^^ expected char, found reference
14+
LL | let ch: &str = '●●';
15+
| ^^^^
16+
help: if you meant to write a `str` literal, use double quotes
1617
|
17-
= note: expected type `char`
18-
found type `&'static str`
18+
LL | let ch: &str = "●●";
19+
| ^^^^
1920

2021
error: aborting due to 2 previous errors
2122

22-
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
22
// This test needs to the last one appearing in this file as it kills the parser
33
static c: char =
4-
'//~ ERROR: character literal may only contain one codepoint: '●
4+
'//~ ERROR: character literal may only contain one codepoint
55
;

src/test/ui/parser/lex-bad-char-literals-4.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
error: character literal may only contain one codepoint: '●
22
--> $DIR/lex-bad-char-literals-4.rs:4:5
33
|
4-
LL | '● //~ ERROR: character literal may only contain one codepoint: '●
4+
LL | '● //~ ERROR: character literal may only contain one codepoint
55
| ^^
66

77
error: aborting due to previous error
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
//
2-
// This test needs to the last one appearing in this file as it kills the parser
3-
static c: char =
4-
'\x10\x10' //~ ERROR: character literal may only contain one codepoint
5-
//~| ERROR: mismatched types
6-
;
1+
static c: char = '\x10\x10';
2+
//~^ ERROR: character literal may only contain one codepoint
73

8-
fn main() {}
4+
fn main() {
5+
let ch: &str = '\x10\x10';
6+
//~^ ERROR: character literal may only contain one codepoint
7+
}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
error: character literal may only contain one codepoint
2-
--> $DIR/lex-bad-char-literals-5.rs:4:5
2+
--> $DIR/lex-bad-char-literals-5.rs:1:18
33
|
4-
LL | '/x10/x10' //~ ERROR: character literal may only contain one codepoint
5-
| ^^^^^^^^^^
4+
LL | static c: char = '/x10/x10';
5+
| ^^^^^^^^^^
66
help: if you meant to write a `str` literal, use double quotes
77
|
8-
LL | "/x10/x10" //~ ERROR: character literal may only contain one codepoint
9-
| ^^^^^^^^^^
8+
LL | static c: char = "/x10/x10";
9+
| ^^^^^^^^^^
1010

11-
error[E0308]: mismatched types
12-
--> $DIR/lex-bad-char-literals-5.rs:4:5
11+
error: character literal may only contain one codepoint
12+
--> $DIR/lex-bad-char-literals-5.rs:5:20
1313
|
14-
LL | '/x10/x10' //~ ERROR: character literal may only contain one codepoint
15-
| ^^^^^^^^^^ expected char, found reference
14+
LL | let ch: &str = '/x10/x10';
15+
| ^^^^^^^^^^
16+
help: if you meant to write a `str` literal, use double quotes
1617
|
17-
= note: expected type `char`
18-
found type `&'static str`
18+
LL | let ch: &str = "/x10/x10";
19+
| ^^^^^^^^^^
1920

2021
error: aborting due to 2 previous errors
2122

22-
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
fn main() {
2+
let x: &str = 'ab';
3+
//~^ ERROR: character literal may only contain one codepoint
4+
let y: char = 'cd';
5+
//~^ ERROR: character literal may only contain one codepoint
6+
let z = 'ef';
7+
//~^ ERROR: character literal may only contain one codepoint
8+
9+
if x == y {}
10+
//~^ ERROR: can't compare `&str` with `char`
11+
if y == z {} // no error here
12+
if x == z {}
13+
//~^ ERROR: can't compare `&str` with `char`
14+
15+
let a: usize = "";
16+
//~^ ERROR: mismatched types
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error: character literal may only contain one codepoint
2+
--> $DIR/lex-bad-char-literals-6.rs:2:19
3+
|
4+
LL | let x: &str = 'ab';
5+
| ^^^^
6+
7+
error: character literal may only contain one codepoint
8+
--> $DIR/lex-bad-char-literals-6.rs:4:19
9+
|
10+
LL | let y: char = 'cd';
11+
| ^^^^
12+
13+
error: character literal may only contain one codepoint
14+
--> $DIR/lex-bad-char-literals-6.rs:6:13
15+
|
16+
LL | let z = 'ef';
17+
| ^^^^
18+
19+
error[E0277]: can't compare `&str` with `char`
20+
--> $DIR/lex-bad-char-literals-6.rs:9:10
21+
|
22+
LL | if x == y {}
23+
| ^^ no implementation for `&str == char`
24+
|
25+
= help: the trait `std::cmp::PartialEq<char>` is not implemented for `&str`
26+
27+
error[E0308]: mismatched types
28+
--> $DIR/lex-bad-char-literals-6.rs:15:20
29+
|
30+
LL | let a: usize = "";
31+
| ^^ expected usize, found reference
32+
|
33+
= note: expected type `usize`
34+
found type `&'static str`
35+
36+
error[E0277]: can't compare `&str` with `char`
37+
--> $DIR/lex-bad-char-literals-6.rs:12:10
38+
|
39+
LL | if x == z {}
40+
| ^^ no implementation for `&str == char`
41+
|
42+
= help: the trait `std::cmp::PartialEq<char>` is not implemented for `&str`
43+
44+
error: aborting due to 6 previous errors
45+
46+
Some errors occurred: E0277, E0308.
47+
For more information about an error, try `rustc --explain E0277`.

src/test/ui/str/str-as-char.fixed

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-rustfix
22

33
fn main() {
4-
println!("●●");
5-
//~^ ERROR character literal may only contain one codepoint
4+
println!("{}", "●●"); //~ ERROR character literal may only contain one codepoint
5+
//~^ ERROR format argument must be a string literal
66
}

src/test/ui/str/str-as-char.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-rustfix
22

33
fn main() {
4-
println!('●●');
5-
//~^ ERROR character literal may only contain one codepoint
4+
println!('●●'); //~ ERROR character literal may only contain one codepoint
5+
//~^ ERROR format argument must be a string literal
66
}

0 commit comments

Comments
 (0)