about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-06-07 12:53:33 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-06-07 18:01:50 +0300
commit2af47facc3fd7eda3fb4e52f0589bb6f48eff15c (patch)
tree46549007a191f5676a28704a3da1cfbd5eacdf7d /src
parentc1c60d292e2dd2deff7084208274f9a02f750d43 (diff)
downloadrust-2af47facc3fd7eda3fb4e52f0589bb6f48eff15c.tar.gz
rust-2af47facc3fd7eda3fb4e52f0589bb6f48eff15c.zip
syntax: Treat error literals in more principled way
Diffstat (limited to 'src')
-rw-r--r--src/librustc/hir/intravisit.rs3
-rw-r--r--src/librustc/ich/impls_syntax.rs4
-rw-r--r--src/librustc_mir/hair/constant.rs10
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/mut_visit.rs3
-rw-r--r--src/libsyntax/parse/literal.rs6
-rw-r--r--src/libsyntax/print/pprust.rs8
-rw-r--r--src/libsyntax/visit.rs3
-rw-r--r--src/libsyntax_ext/concat.rs4
-rw-r--r--src/test/ui/extenv/issue-55897.rs5
-rw-r--r--src/test/ui/extenv/issue-55897.stderr8
11 files changed, 33 insertions, 27 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 1c66f8bdf81..f4f9d6261de 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -1020,7 +1020,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
         ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
             visitor.visit_expr(subexpression)
         }
-        ExprKind::Lit(_) => {}
         ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
             visitor.visit_expr(subexpression);
             visitor.visit_ty(typ)
@@ -1093,7 +1092,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
         ExprKind::Yield(ref subexpression) => {
             visitor.visit_expr(subexpression);
         }
-        ExprKind::Err => {}
+        ExprKind::Lit(_) | ExprKind::Err => {}
     }
 }
 
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index abe4196abd1..e0c01277801 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -170,14 +170,14 @@ impl_stable_hash_for!(struct ::syntax::ast::Lit {
 
 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
     Str(value, style),
-    Err(value),
     ByteStr(value),
     Byte(value),
     Char(value),
     Int(value, lit_int_type),
     Float(value, float_ty),
     FloatUnsuffixed(value),
-    Bool(value)
+    Bool(value),
+    Err(value)
 });
 
 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs
index a5be55d16d4..b5604f4cb0f 100644
--- a/src/librustc_mir/hair/constant.rs
+++ b/src/librustc_mir/hair/constant.rs
@@ -34,15 +34,6 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
             let allocation = tcx.intern_const_alloc(allocation);
             ConstValue::Slice { data: allocation, start: 0, end: s.len() }
         },
-        LitKind::Err(ref s) => {
-            let s = s.as_str();
-            let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes());
-            let allocation = tcx.intern_const_alloc(allocation);
-            return Ok(tcx.mk_const(ty::Const {
-                val: ConstValue::Slice{ data: allocation, start: 0, end: s.len() },
-                ty: tcx.types.err,
-            }));
-        },
         LitKind::ByteStr(ref data) => {
             let id = tcx.allocate_bytes(data);
             ConstValue::Scalar(Scalar::Ptr(id.into()))
@@ -66,6 +57,7 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
         }
         LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
         LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
+        LitKind::Err(_) => unreachable!(),
     };
     Ok(tcx.mk_const(ty::Const { val: lit, ty }))
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 598232f9f8f..02fbcb14fa5 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1368,7 +1368,7 @@ pub enum LitKind {
     FloatUnsuffixed(Symbol),
     /// A boolean literal.
     Bool(bool),
-    /// A recovered character literal that contains mutliple `char`s, most likely a typo.
+    /// Placeholder for a literal that wasn't well-formed in some way.
     Err(Symbol),
 }
 
@@ -1406,10 +1406,10 @@ impl LitKind {
             | LitKind::ByteStr(..)
             | LitKind::Byte(..)
             | LitKind::Char(..)
-            | LitKind::Err(..)
             | LitKind::Int(_, LitIntType::Unsuffixed)
             | LitKind::FloatUnsuffixed(..)
-            | LitKind::Bool(..) => true,
+            | LitKind::Bool(..)
+            | LitKind::Err(..) => true,
             // suffixed variants
             LitKind::Int(_, LitIntType::Signed(..))
             | LitKind::Int(_, LitIntType::Unsigned(..))
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index d2a614c4a54..2889f8edfc6 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -1101,7 +1101,6 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
             vis.visit_expr(rhs);
         }
         ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
-        ExprKind::Lit(_lit) => {}
         ExprKind::Cast(expr, ty) => {
             vis.visit_expr(expr);
             vis.visit_ty(ty);
@@ -1225,7 +1224,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
         }
         ExprKind::Try(expr) => vis.visit_expr(expr),
         ExprKind::TryBlock(body) => vis.visit_block(body),
-        ExprKind::Err => {}
+        ExprKind::Lit(_) | ExprKind::Err => {}
     }
     vis.visit_id(id);
     vis.visit_span(span);
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs
index 7d5356ffe4d..467ad6ccfbe 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/parse/literal.rs
@@ -311,7 +311,11 @@ impl<'a> Parser<'a> {
                 let (lit, span) = (token.expect_lit(), token.span);
                 self.bump();
                 err.report(&self.sess.span_diagnostic, lit, span);
-                let lit = token::Lit::new(token::Err, lit.symbol, lit.suffix);
+                // Pack possible quotes and prefixes from the original literal into
+                // the error literal's symbol so they can be pretty-printed faithfully.
+                let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
+                let symbol = Symbol::intern(&pprust::literal_to_string(suffixless_lit));
+                let lit = token::Lit::new(token::Err, symbol, lit.suffix);
                 Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
             }
         }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 07acfb5dc86..d922e1896cc 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -168,9 +168,6 @@ pub fn literal_to_string(lit: token::Lit) -> String {
     let mut out = match kind {
         token::Byte          => format!("b'{}'", symbol),
         token::Char          => format!("'{}'", symbol),
-        token::Bool          |
-        token::Float         |
-        token::Integer       => symbol.to_string(),
         token::Str           => format!("\"{}\"", symbol),
         token::StrRaw(n)     => format!("r{delim}\"{string}\"{delim}",
                                         delim="#".repeat(n as usize),
@@ -179,7 +176,10 @@ pub fn literal_to_string(lit: token::Lit) -> String {
         token::ByteStrRaw(n) => format!("br{delim}\"{string}\"{delim}",
                                         delim="#".repeat(n as usize),
                                         string=symbol),
-        token::Err           => format!("'{}'", symbol),
+        token::Integer       |
+        token::Float         |
+        token::Bool          |
+        token::Err           => symbol.to_string(),
     };
 
     if let Some(suffix) = suffix {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 4e6a8274a47..24b0c372471 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -714,7 +714,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
             visitor.visit_expr(subexpression)
         }
-        ExprKind::Lit(_) => {}
         ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
             visitor.visit_expr(subexpression);
             visitor.visit_ty(typ)
@@ -826,7 +825,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::TryBlock(ref body) => {
             visitor.visit_block(body)
         }
-        ExprKind::Err => {}
+        ExprKind::Lit(_) | ExprKind::Err => {}
     }
 
     visitor.visit_expr_post(expression)
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index 230b00c0f8f..68d5178372e 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -22,7 +22,6 @@ 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());
@@ -41,6 +40,9 @@ pub fn expand_syntax_ext(
                 ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
                     cx.span_err(e.span, "cannot concatenate a byte string literal");
                 }
+                ast::LitKind::Err(_) => {
+                    has_errors = true;
+                }
             },
             ast::ExprKind::Err => {
                 has_errors = true;
diff --git a/src/test/ui/extenv/issue-55897.rs b/src/test/ui/extenv/issue-55897.rs
index bd151c8a4e4..c3975f6b925 100644
--- a/src/test/ui/extenv/issue-55897.rs
+++ b/src/test/ui/extenv/issue-55897.rs
@@ -12,4 +12,9 @@ mod nonexistent_env {
     //~^ ERROR environment variable `NON_EXISTENT` not defined
 }
 
+mod erroneous_literal {
+    include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
+    //~^ ERROR suffixes on a string literal are invalid
+}
+
 fn main() {}
diff --git a/src/test/ui/extenv/issue-55897.stderr b/src/test/ui/extenv/issue-55897.stderr
index 9f6570ab2a0..9d68131beab 100644
--- a/src/test/ui/extenv/issue-55897.stderr
+++ b/src/test/ui/extenv/issue-55897.stderr
@@ -4,6 +4,12 @@ error: environment variable `NON_EXISTENT` not defined
 LL |     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
    |                      ^^^^^^^^^^^^^^^^^^^^
 
+error: suffixes on a string literal are invalid
+  --> $DIR/issue-55897.rs:16:22
+   |
+LL |     include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
+   |                      ^^^^^^^^^^^^^^^^^^^^ invalid suffix `suffix`
+
 error[E0432]: unresolved import `prelude`
   --> $DIR/issue-55897.rs:1:5
    |
@@ -21,6 +27,6 @@ LL |     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
    |
    = note: import resolution is stuck, try simplifying macro imports
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0432`.