From d19294feeea5f09409974b94ddd3f441b8871bb3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jan 2019 09:27:43 +0900 Subject: Add new literal type Err --- src/libsyntax/ext/quote.rs | 1 + src/libsyntax/parse/mod.rs | 1 + src/libsyntax/parse/token.rs | 2 ++ src/libsyntax/print/pprust.rs | 1 + 4 files changed, 5 insertions(+) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index c3124144009..17c88a30bcd 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -646,6 +646,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), + token::Literal(token::Err(i), suf) => return mk_lit!("Err", suf, i), token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ea205530ca5..cbb503f56bc 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -466,6 +466,7 @@ crate fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Ha match lit { token::Byte(i) => (true, Some(LitKind::Byte(byte_lit(&i.as_str()).0))), token::Char(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), + token::Err(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), // There are some valid suffixes for integer and float literals, // so all the handling is done internally. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 25a4da38c8c..69e934d64c6 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -60,6 +60,7 @@ impl DelimToken { pub enum Lit { Byte(ast::Name), Char(ast::Name), + Err(ast::Name), Integer(ast::Name), Float(ast::Name), Str_(ast::Name), @@ -73,6 +74,7 @@ impl Lit { match *self { Byte(_) => "byte literal", Char(_) => "char literal", + Err(_) => "error literal", Integer(_) => "integer literal", Float(_) => "float literal", Str_(_) | StrRaw(..) => "string literal", diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 2ad3d3a6d64..123f9b49692 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -224,6 +224,7 @@ pub fn token_to_string(tok: &Token) -> String { let mut out = match lit { token::Byte(b) => format!("b'{}'", b), token::Char(c) => format!("'{}'", c), + token::Err(c) => format!("'{}'", c), token::Float(c) | token::Integer(c) => c.to_string(), token::Str_(s) => format!("\"{}\"", s), -- cgit 1.4.1-3-g733a5 From ec8db2a94446f2ef4da7ac89bbe5e171fe17e46f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jan 2019 09:28:06 +0900 Subject: Cancel process --- src/libsyntax/parse/lexer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0e1c3b4b61f..666653f9edf 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1445,7 +1445,7 @@ impl<'a> StringReader<'a> { format!("\"{}\"", &self.src[start..end]), Applicability::MachineApplicable ).emit(); - return Ok(token::Literal(token::Str_(Symbol::intern("??")), None)) + FatalError.raise(); } if self.ch_is('\n') || self.is_eof() || self.ch_is('/') { // Only attempt to infer single line string literals. If we encounter -- cgit 1.4.1-3-g733a5 From 32662c2953bfc05e0cbef30ee51647f679bb1f4f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:20:27 +0900 Subject: Change from error to invalid --- src/libsyntax/parse/token.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 69e934d64c6..99041fd7cd6 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -74,7 +74,7 @@ impl Lit { match *self { Byte(_) => "byte literal", Char(_) => "char literal", - Err(_) => "error literal", + Err(_) => "invalid literal", Integer(_) => "integer literal", Float(_) => "float literal", Str_(_) | StrRaw(..) => "string literal", -- cgit 1.4.1-3-g733a5 From bde3795d465c1a1768afa49cc5e79cea93cb99f3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:22:00 +0900 Subject: Continue cheking --- src/libsyntax/parse/lexer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 666653f9edf..2bf7ff4bd7a 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1445,7 +1445,7 @@ impl<'a> StringReader<'a> { format!("\"{}\"", &self.src[start..end]), Applicability::MachineApplicable ).emit(); - FatalError.raise(); + return Ok(token::Literal(token::Char(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 -- cgit 1.4.1-3-g733a5 From 7e2e61c618b53ccaa5d64b57b4c1872bc73746aa Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:23:25 +0900 Subject: Change from mk_lit! to cx.expr --- src/libsyntax/ext/quote.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 17c88a30bcd..01cb1341b9f 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -646,7 +646,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), - token::Literal(token::Err(i), suf) => return mk_lit!("Err", suf, i), + token::Literal(token::Err(_i), _suf) => return cx.expr(sp, ast::ExprKind::Err), token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), -- cgit 1.4.1-3-g733a5 From c502a79fa1a15de88623bc01d9a1c38db3ea2c1b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 04:37:29 +0900 Subject: [WIP] Improve error behavior --- src/libsyntax/parse/lexer/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 2bf7ff4bd7a..fcaa35d1fca 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1408,9 +1408,10 @@ impl<'a> StringReader<'a> { // lifetimes shouldn't end with a single quote // if we find one, then this is an invalid character literal if self.ch_is('\'') { - self.fatal_span_verbose(start_with_quote, self.next_pos, - String::from("character literal may only contain one codepoint")) - .raise(); + self.err_span_(start_with_quote, self.next_pos, + "character literal may only contain one codepoint"); + self.bump(); + return Ok(token::Literal(token::Err(Symbol::intern("??")), None)) } @@ -1445,7 +1446,7 @@ impl<'a> StringReader<'a> { format!("\"{}\"", &self.src[start..end]), Applicability::MachineApplicable ).emit(); - return Ok(token::Literal(token::Char(Symbol::intern("??")), None)) + return Ok(token::Literal(token::Err(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 @@ -1455,8 +1456,9 @@ impl<'a> StringReader<'a> { } } - self.fatal_span_verbose(start_with_quote, pos, - String::from("character literal may only contain one codepoint")).raise(); + self.err_span_(start_with_quote, pos, + "character literal may only contain one codepoint"); + self.bump(); } let id = if valid { -- cgit 1.4.1-3-g733a5 From a4ff1dcc534e9ae132e5b201a8f6e7dd06fbd9ee Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 14:51:54 +0900 Subject: Mark incorrect recovered `char` literals as `TyErr` to avoid type errors --- src/librustc/ich/impls_syntax.rs | 1 + src/librustc_mir/hair/constant.rs | 8 ++++++++ src/librustc_typeck/check/mod.rs | 3 ++- src/libsyntax/ast.rs | 3 +++ src/libsyntax/attr/mod.rs | 1 + src/libsyntax/parse/mod.rs | 2 +- src/libsyntax/parse/token.rs | 3 +-- src/libsyntax/print/pprust.rs | 8 ++++++++ src/libsyntax_ext/concat.rs | 1 + 9 files changed, 26 insertions(+), 4 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 6ffb771ffcc..ef113b8424d 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -164,6 +164,7 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType { impl_stable_hash_for_spanned!(::syntax::ast::LitKind); impl_stable_hash_for!(enum ::syntax::ast::LitKind { Str(value, style), + Err(value), ByteStr(value), Byte(value), Char(value), diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs index 37d741d2606..f63c3e2ff61 100644 --- a/src/librustc_mir/hair/constant.rs +++ b/src/librustc_mir/hair/constant.rs @@ -37,6 +37,14 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>( let id = tcx.allocate_bytes(s.as_bytes()); ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx) }, + LitKind::Err(ref s) => { + let s = s.as_str(); + let id = tcx.allocate_bytes(s.as_bytes()); + return Ok(ty::Const { + val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx), + ty: tcx.types.err, + }); + }, LitKind::ByteStr(ref data) => { let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::Ptr(id.into())) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1..6c228670ff6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3121,7 +3121,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { opt_ty.unwrap_or_else( || tcx.mk_float_var(self.next_float_var_id())) } - ast::LitKind::Bool(_) => tcx.types.bool + ast::LitKind::Bool(_) => tcx.types.bool, + ast::LitKind::Err(_) => tcx.types.err, } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 99ab9fbcf5f..1180c8c8c1c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1285,6 +1285,8 @@ pub enum LitKind { FloatUnsuffixed(Symbol), /// A boolean literal. Bool(bool), + /// A recovered character literal that contains mutliple `char`s, most likely a typo. + Err(Symbol), } impl LitKind { @@ -1321,6 +1323,7 @@ impl LitKind { | LitKind::ByteStr(..) | LitKind::Byte(..) | LitKind::Char(..) + | LitKind::Err(..) | LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::FloatUnsuffixed(..) | LitKind::Bool(..) => true, diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index d03563f8891..9c3ee0a3b02 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -661,6 +661,7 @@ impl LitKind { } else { "false" })), false), + LitKind::Err(val) => Token::Literal(token::Lit::Err(val), None), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index cbb503f56bc..9e55f359b5e 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -466,7 +466,7 @@ crate fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Ha match lit { token::Byte(i) => (true, Some(LitKind::Byte(byte_lit(&i.as_str()).0))), token::Char(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), - token::Err(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), + token::Err(i) => (true, Some(LitKind::Err(i))), // There are some valid suffixes for integer and float literals, // so all the handling is done internally. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 99041fd7cd6..f06e975a6d9 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -473,8 +473,7 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | - Question | OpenDelim(..) | CloseDelim(..) => return None, - + Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) | Whitespace | Comment | Shebang(..) | Eof => return None, }) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 123f9b49692..383baffa266 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -604,6 +604,14 @@ pub trait PrintState<'a> { } match lit.node { ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), + ast::LitKind::Err(st) => { + let st = st.as_str().escape_debug(); + let mut res = String::with_capacity(st.len() + 2); + res.push('\''); + res.push_str(&st); + res.push('\''); + self.writer().word(res) + } ast::LitKind::Byte(byte) => { let mut res = String::from("b'"); res.extend(ascii::escape_default(byte).map(|c| c as char)); diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index 807f190cb6a..f148f8e003d 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -23,6 +23,7 @@ pub fn expand_syntax_ext( match e.node { ast::ExprKind::Lit(ref lit) => match lit.node { ast::LitKind::Str(ref s, _) + | ast::LitKind::Err(ref s) | ast::LitKind::Float(ref s, _) | ast::LitKind::FloatUnsuffixed(ref s) => { accumulator.push_str(&s.as_str()); -- cgit 1.4.1-3-g733a5 From 6e59c6432612f87c7cb1309e89c41e1f0d9e0e25 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 14:53:16 +0900 Subject: Revert change --- src/libsyntax/parse/lexer/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index fcaa35d1fca..cf51d3ed58d 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1456,9 +1456,8 @@ impl<'a> StringReader<'a> { } } - self.err_span_(start_with_quote, pos, - "character literal may only contain one codepoint"); - self.bump(); + self.fatal_span_verbose(start_with_quote, pos, + String::from("character literal may only contain one codepoint")).raise(); } let id = if valid { -- cgit 1.4.1-3-g733a5