Skip to content

Commit e3e81f4

Browse files
authored
Rollup merge of rust-lang#61615 - petrochenkov:errlit, r=matklad
syntax: Treat error literals in more principled way Free them from their character literal origins. I actually tried to remove `LitKind::Err` entirely (by converting it into `ExprKind::Err` immediately), and it caused no diagnostic regressions in the test suite. However, I'd still want to use error literals as general purpose error tokens some day, so I kept them. The downside of having `LitKind::Err` in addition to `ExprKind::Err` is that every time you want to do something with `ExprKind::Err` you need to make sure that `ExprKind::Lit(LitKind::Err)` is treated in the same way. Fortunately, this usually happens automatically because both literals and errors are "leaf" expressions, however this PR does fix a couple of inconsistencies between them. Addresses rust-lang#60679 (comment) in a way
2 parents e166b16 + 2af47fa commit e3e81f4

File tree

11 files changed

+33
-27
lines changed

11 files changed

+33
-27
lines changed

src/librustc/hir/intravisit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
10201020
ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
10211021
visitor.visit_expr(subexpression)
10221022
}
1023-
ExprKind::Lit(_) => {}
10241023
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
10251024
visitor.visit_expr(subexpression);
10261025
visitor.visit_ty(typ)
@@ -1093,7 +1092,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
10931092
ExprKind::Yield(ref subexpression) => {
10941093
visitor.visit_expr(subexpression);
10951094
}
1096-
ExprKind::Err => {}
1095+
ExprKind::Lit(_) | ExprKind::Err => {}
10971096
}
10981097
}
10991098

src/librustc/ich/impls_syntax.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,14 @@ impl_stable_hash_for!(struct ::syntax::ast::Lit {
170170

171171
impl_stable_hash_for!(enum ::syntax::ast::LitKind {
172172
Str(value, style),
173-
Err(value),
174173
ByteStr(value),
175174
Byte(value),
176175
Char(value),
177176
Int(value, lit_int_type),
178177
Float(value, float_ty),
179178
FloatUnsuffixed(value),
180-
Bool(value)
179+
Bool(value),
180+
Err(value)
181181
});
182182

183183
impl_stable_hash_for_spanned!(::syntax::ast::LitKind);

src/librustc_mir/hair/constant.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,6 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
3434
let allocation = tcx.intern_const_alloc(allocation);
3535
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
3636
},
37-
LitKind::Err(ref s) => {
38-
let s = s.as_str();
39-
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes());
40-
let allocation = tcx.intern_const_alloc(allocation);
41-
return Ok(tcx.mk_const(ty::Const {
42-
val: ConstValue::Slice{ data: allocation, start: 0, end: s.len() },
43-
ty: tcx.types.err,
44-
}));
45-
},
4637
LitKind::ByteStr(ref data) => {
4738
let id = tcx.allocate_bytes(data);
4839
ConstValue::Scalar(Scalar::Ptr(id.into()))
@@ -66,6 +57,7 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
6657
}
6758
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
6859
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
60+
LitKind::Err(_) => unreachable!(),
6961
};
7062
Ok(tcx.mk_const(ty::Const { val: lit, ty }))
7163
}

src/libsyntax/ast.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ pub enum LitKind {
13681368
FloatUnsuffixed(Symbol),
13691369
/// A boolean literal.
13701370
Bool(bool),
1371-
/// A recovered character literal that contains mutliple `char`s, most likely a typo.
1371+
/// Placeholder for a literal that wasn't well-formed in some way.
13721372
Err(Symbol),
13731373
}
13741374

@@ -1406,10 +1406,10 @@ impl LitKind {
14061406
| LitKind::ByteStr(..)
14071407
| LitKind::Byte(..)
14081408
| LitKind::Char(..)
1409-
| LitKind::Err(..)
14101409
| LitKind::Int(_, LitIntType::Unsuffixed)
14111410
| LitKind::FloatUnsuffixed(..)
1412-
| LitKind::Bool(..) => true,
1411+
| LitKind::Bool(..)
1412+
| LitKind::Err(..) => true,
14131413
// suffixed variants
14141414
LitKind::Int(_, LitIntType::Signed(..))
14151415
| LitKind::Int(_, LitIntType::Unsigned(..))

src/libsyntax/mut_visit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,6 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
11011101
vis.visit_expr(rhs);
11021102
}
11031103
ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
1104-
ExprKind::Lit(_lit) => {}
11051104
ExprKind::Cast(expr, ty) => {
11061105
vis.visit_expr(expr);
11071106
vis.visit_ty(ty);
@@ -1225,7 +1224,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
12251224
}
12261225
ExprKind::Try(expr) => vis.visit_expr(expr),
12271226
ExprKind::TryBlock(body) => vis.visit_block(body),
1228-
ExprKind::Err => {}
1227+
ExprKind::Lit(_) | ExprKind::Err => {}
12291228
}
12301229
vis.visit_id(id);
12311230
vis.visit_span(span);

src/libsyntax/parse/literal.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,11 @@ impl<'a> Parser<'a> {
311311
let (lit, span) = (token.expect_lit(), token.span);
312312
self.bump();
313313
err.report(&self.sess.span_diagnostic, lit, span);
314-
let lit = token::Lit::new(token::Err, lit.symbol, lit.suffix);
314+
// Pack possible quotes and prefixes from the original literal into
315+
// the error literal's symbol so they can be pretty-printed faithfully.
316+
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
317+
let symbol = Symbol::intern(&pprust::literal_to_string(suffixless_lit));
318+
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
315319
Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
316320
}
317321
}

src/libsyntax/print/pprust.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ pub fn literal_to_string(lit: token::Lit) -> String {
168168
let mut out = match kind {
169169
token::Byte => format!("b'{}'", symbol),
170170
token::Char => format!("'{}'", symbol),
171-
token::Bool |
172-
token::Float |
173-
token::Integer => symbol.to_string(),
174171
token::Str => format!("\"{}\"", symbol),
175172
token::StrRaw(n) => format!("r{delim}\"{string}\"{delim}",
176173
delim="#".repeat(n as usize),
@@ -179,7 +176,10 @@ pub fn literal_to_string(lit: token::Lit) -> String {
179176
token::ByteStrRaw(n) => format!("br{delim}\"{string}\"{delim}",
180177
delim="#".repeat(n as usize),
181178
string=symbol),
182-
token::Err => format!("'{}'", symbol),
179+
token::Integer |
180+
token::Float |
181+
token::Bool |
182+
token::Err => symbol.to_string(),
183183
};
184184

185185
if let Some(suffix) = suffix {

src/libsyntax/visit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
714714
ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
715715
visitor.visit_expr(subexpression)
716716
}
717-
ExprKind::Lit(_) => {}
718717
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
719718
visitor.visit_expr(subexpression);
720719
visitor.visit_ty(typ)
@@ -826,7 +825,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
826825
ExprKind::TryBlock(ref body) => {
827826
visitor.visit_block(body)
828827
}
829-
ExprKind::Err => {}
828+
ExprKind::Lit(_) | ExprKind::Err => {}
830829
}
831830

832831
visitor.visit_expr_post(expression)

src/libsyntax_ext/concat.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ pub fn expand_syntax_ext(
2222
match e.node {
2323
ast::ExprKind::Lit(ref lit) => match lit.node {
2424
ast::LitKind::Str(ref s, _)
25-
| ast::LitKind::Err(ref s)
2625
| ast::LitKind::Float(ref s, _)
2726
| ast::LitKind::FloatUnsuffixed(ref s) => {
2827
accumulator.push_str(&s.as_str());
@@ -41,6 +40,9 @@ pub fn expand_syntax_ext(
4140
ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
4241
cx.span_err(e.span, "cannot concatenate a byte string literal");
4342
}
43+
ast::LitKind::Err(_) => {
44+
has_errors = true;
45+
}
4446
},
4547
ast::ExprKind::Err => {
4648
has_errors = true;

src/test/ui/extenv/issue-55897.rs

+5
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ mod nonexistent_env {
1212
//~^ ERROR environment variable `NON_EXISTENT` not defined
1313
}
1414

15+
mod erroneous_literal {
16+
include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
17+
//~^ ERROR suffixes on a string literal are invalid
18+
}
19+
1520
fn main() {}

src/test/ui/extenv/issue-55897.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ error: environment variable `NON_EXISTENT` not defined
44
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
55
| ^^^^^^^^^^^^^^^^^^^^
66

7+
error: suffixes on a string literal are invalid
8+
--> $DIR/issue-55897.rs:16:22
9+
|
10+
LL | include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
11+
| ^^^^^^^^^^^^^^^^^^^^ invalid suffix `suffix`
12+
713
error[E0432]: unresolved import `prelude`
814
--> $DIR/issue-55897.rs:1:5
915
|
@@ -21,6 +27,6 @@ LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
2127
|
2228
= note: import resolution is stuck, try simplifying macro imports
2329

24-
error: aborting due to 3 previous errors
30+
error: aborting due to 4 previous errors
2531

2632
For more information about this error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)