Skip to content

Commit 25ed6e4

Browse files
committed
Add ErrorGuaranteed to ast::LitKind::Err, token::LitKind::Err.
This mostly works well, and eliminates a couple of delayed bugs. One annoying thing is that we should really also add an `ErrorGuaranteed` to `proc_macro::bridge::LitKind::Err`. But that's difficult because `proc_macro` doesn't have access to `ErrorGuaranteed`, so we have to fake it.
1 parent 332c577 commit 25ed6e4

File tree

26 files changed

+85
-64
lines changed

26 files changed

+85
-64
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1846,7 +1846,7 @@ pub enum LitKind {
18461846
/// A boolean literal (`true`, `false`).
18471847
Bool(bool),
18481848
/// Placeholder for a literal that wasn't well-formed in some way.
1849-
Err,
1849+
Err(ErrorGuaranteed),
18501850
}
18511851

18521852
impl LitKind {
@@ -1893,7 +1893,7 @@ impl LitKind {
18931893
| LitKind::Int(_, LitIntType::Unsuffixed)
18941894
| LitKind::Float(_, LitFloatType::Unsuffixed)
18951895
| LitKind::Bool(..)
1896-
| LitKind::Err => false,
1896+
| LitKind::Err(_) => false,
18971897
}
18981898
}
18991899
}

Diff for: compiler/rustc_ast/src/token.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_macros::HashStable_Generic;
1313
use rustc_span::symbol::{kw, sym};
1414
#[allow(hidden_glob_reexports)]
1515
use rustc_span::symbol::{Ident, Symbol};
16-
use rustc_span::{edition::Edition, Span, DUMMY_SP};
16+
use rustc_span::{edition::Edition, ErrorGuaranteed, Span, DUMMY_SP};
1717
use std::borrow::Cow;
1818
use std::fmt;
1919

@@ -75,7 +75,7 @@ pub enum LitKind {
7575
ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols
7676
CStr,
7777
CStrRaw(u8),
78-
Err,
78+
Err(ErrorGuaranteed),
7979
}
8080

8181
/// A literal token.
@@ -144,7 +144,7 @@ impl fmt::Display for Lit {
144144
CStrRaw(n) => {
145145
write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))?
146146
}
147-
Integer | Float | Bool | Err => write!(f, "{symbol}")?,
147+
Integer | Float | Bool | Err(_) => write!(f, "{symbol}")?,
148148
}
149149

150150
if let Some(suffix) = suffix {
@@ -159,7 +159,7 @@ impl LitKind {
159159
/// An English article for the literal token kind.
160160
pub fn article(self) -> &'static str {
161161
match self {
162-
Integer | Err => "an",
162+
Integer | Err(_) => "an",
163163
_ => "a",
164164
}
165165
}
@@ -174,12 +174,12 @@ impl LitKind {
174174
Str | StrRaw(..) => "string",
175175
ByteStr | ByteStrRaw(..) => "byte string",
176176
CStr | CStrRaw(..) => "C string",
177-
Err => "error",
177+
Err(_) => "error",
178178
}
179179
}
180180

181181
pub(crate) fn may_have_suffix(self) -> bool {
182-
matches!(self, Integer | Float | Err)
182+
matches!(self, Integer | Float | Err(_))
183183
}
184184
}
185185

Diff for: compiler/rustc_ast/src/util/literal.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl LitKind {
144144
buf.push(0);
145145
LitKind::CStr(buf.into(), StrStyle::Raw(n))
146146
}
147-
token::Err => LitKind::Err,
147+
token::Err(guar) => LitKind::Err(guar),
148148
})
149149
}
150150
}
@@ -201,7 +201,7 @@ impl fmt::Display for LitKind {
201201
}
202202
}
203203
LitKind::Bool(b) => write!(f, "{}", if b { "true" } else { "false" })?,
204-
LitKind::Err => {
204+
LitKind::Err(_) => {
205205
// This only shows up in places like `-Zunpretty=hir` output, so we
206206
// don't bother to produce something useful.
207207
write!(f, "<bad-literal>")?;
@@ -237,7 +237,7 @@ impl MetaItemLit {
237237
LitKind::Char(_) => token::Char,
238238
LitKind::Int(..) => token::Integer,
239239
LitKind::Float(..) => token::Float,
240-
LitKind::Err => token::Err,
240+
LitKind::Err(guar) => token::Err(guar),
241241
};
242242

243243
token::Lit::new(kind, self.symbol, self.suffix)

Diff for: compiler/rustc_ast_lowering/src/expr.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
124124
let lit_kind = match LitKind::from_token_lit(*token_lit) {
125125
Ok(lit_kind) => lit_kind,
126126
Err(err) => {
127-
report_lit_error(&self.tcx.sess.parse_sess, err, *token_lit, e.span);
128-
LitKind::Err
127+
let guar = report_lit_error(
128+
&self.tcx.sess.parse_sess,
129+
err,
130+
*token_lit,
131+
e.span,
132+
);
133+
LitKind::Err(guar)
129134
}
130135
};
131136
let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind));

Diff for: compiler/rustc_ast_lowering/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
966966
{
967967
lit
968968
} else {
969+
let guar = self.dcx().has_errors().unwrap();
969970
MetaItemLit {
970971
symbol: kw::Empty,
971972
suffix: None,
972-
kind: LitKind::Err,
973+
kind: LitKind::Err(guar),
973974
span: DUMMY_SP,
974975
}
975976
};

Diff for: compiler/rustc_ast_pretty/src/pprust/state.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ fn literal_to_string(lit: token::Lit) -> String {
254254
token::CStrRaw(n) => {
255255
format!("cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))
256256
}
257-
token::Integer | token::Float | token::Bool | token::Err => symbol.to_string(),
257+
token::Integer | token::Float | token::Bool | token::Err(_) => symbol.to_string(),
258258
};
259259

260260
if let Some(suffix) = suffix {

Diff for: compiler/rustc_builtin_macros/src/concat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn expand_concat(
4040
cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
4141
has_errors = true;
4242
}
43-
Ok(ast::LitKind::Err) => {
43+
Ok(ast::LitKind::Err(_)) => {
4444
has_errors = true;
4545
}
4646
Err(err) => {

Diff for: compiler/rustc_builtin_macros/src/concat_bytes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn invalid_type_err(
4444
Ok(ast::LitKind::Bool(_)) => {
4545
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None });
4646
}
47-
Ok(ast::LitKind::Err) => {}
47+
Ok(ast::LitKind::Err(_)) => {}
4848
Ok(ast::LitKind::Int(_, _)) if !is_nested => {
4949
let sugg =
5050
snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet });

Diff for: compiler/rustc_expand/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,7 @@ pub fn expr_to_spanned_string<'a>(
12661266
);
12671267
Some((err, true))
12681268
}
1269-
Ok(ast::LitKind::Err) => None,
1269+
Ok(ast::LitKind::Err(_)) => None,
12701270
Err(err) => {
12711271
report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span);
12721272
None

Diff for: compiler/rustc_expand/src/proc_macro_server.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
1010
use rustc_ast_pretty::pprust;
1111
use rustc_data_structures::fx::FxHashMap;
1212
use rustc_data_structures::sync::Lrc;
13-
use rustc_errors::{MultiSpan, PResult};
13+
use rustc_errors::{ErrorGuaranteed, MultiSpan, PResult};
1414
use rustc_parse::lexer::nfc_normalize;
1515
use rustc_parse::parse_stream_from_source_str;
1616
use rustc_session::parse::ParseSess;
@@ -63,7 +63,12 @@ impl FromInternal<token::LitKind> for LitKind {
6363
token::ByteStrRaw(n) => LitKind::ByteStrRaw(n),
6464
token::CStr => LitKind::CStr,
6565
token::CStrRaw(n) => LitKind::CStrRaw(n),
66-
token::Err => LitKind::Err,
66+
token::Err(_guar) => {
67+
// This is the only place a `pm::bridge::LitKind::ErrWithGuar`
68+
// is constructed. Note that an `ErrorGuaranteed` is available,
69+
// as required. See the comment in `to_internal`.
70+
LitKind::ErrWithGuar
71+
}
6772
token::Bool => unreachable!(),
6873
}
6974
}
@@ -82,7 +87,16 @@ impl ToInternal<token::LitKind> for LitKind {
8287
LitKind::ByteStrRaw(n) => token::ByteStrRaw(n),
8388
LitKind::CStr => token::CStr,
8489
LitKind::CStrRaw(n) => token::CStrRaw(n),
85-
LitKind::Err => token::Err,
90+
LitKind::ErrWithGuar => {
91+
// This is annoying but valid. `LitKind::ErrWithGuar` would
92+
// have an `ErrorGuaranteed` except that type isn't available
93+
// in that crate. So we have to fake one. And we don't want to
94+
// use a delayed bug because there might be lots of these,
95+
// which would be expensive.
96+
#[allow(deprecated)]
97+
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
98+
token::Err(guar)
99+
}
86100
}
87101
}
88102
}
@@ -477,7 +491,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
477491
| token::LitKind::ByteStrRaw(_)
478492
| token::LitKind::CStr
479493
| token::LitKind::CStrRaw(_)
480-
| token::LitKind::Err => return Err(()),
494+
| token::LitKind::Err(_) => return Err(()),
481495
token::LitKind::Integer | token::LitKind::Float => {}
482496
}
483497

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13191319
tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span)))
13201320
.skip_binder(),
13211321
),
1322-
ast::LitKind::Err => Ty::new_misc_error(tcx),
1322+
ast::LitKind::Err(guar) => Ty::new_error(tcx, guar),
13231323
}
13241324
}
13251325

Diff for: compiler/rustc_mir_build/src/build/expr/as_constant.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,7 @@ fn lit_to_mir_constant<'tcx>(
164164
})?,
165165
(ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
166166
(ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
167-
(ast::LitKind::Err, _) => {
168-
return Err(LitToConstError::Reported(
169-
tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"),
170-
));
171-
}
167+
(ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
172168
_ => return Err(LitToConstError::TypeError),
173169
};
174170

Diff for: compiler/rustc_mir_build/src/thir/constant.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,7 @@ pub(crate) fn lit_to_const<'tcx>(
7171
ty::ValTree::from_scalar_int(bits)
7272
}
7373
(ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
74-
(ast::LitKind::Err, _) => {
75-
return Err(LitToConstError::Reported(
76-
tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"),
77-
));
78-
}
74+
(ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
7975
_ => return Err(LitToConstError::TypeError),
8076
};
8177

Diff for: compiler/rustc_mir_build/src/thir/cx/expr.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,14 @@ impl<'tcx> Cx<'tcx> {
897897
let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
898898
let generics = self.tcx.generics_of(hir_id.owner);
899899
let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
900-
self.tcx.dcx().has_errors().unwrap();
900+
let guar = self.tcx.dcx().has_errors().unwrap();
901901
// We already errored about a late bound const
902-
return ExprKind::Literal {
903-
lit: &Spanned { span: DUMMY_SP, node: LitKind::Err },
904-
neg: false,
905-
};
902+
903+
let lit = self
904+
.tcx
905+
.hir_arena
906+
.alloc(Spanned { span: DUMMY_SP, node: LitKind::Err(guar) });
907+
return ExprKind::Literal { lit, neg: false };
906908
};
907909
let name = self.tcx.hir().name(hir_id);
908910
let param = ty::ParamConst::new(index, name);

Diff for: compiler/rustc_parse/src/lexer/mod.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,8 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
481481
let mut kind = token::Integer;
482482
if empty_int {
483483
let span = self.mk_sp(start, end);
484-
self.dcx().emit_err(errors::NoDigitsLiteral { span });
485-
kind = token::Err;
484+
let guar = self.dcx().emit_err(errors::NoDigitsLiteral { span });
485+
kind = token::Err(guar);
486486
} else if matches!(base, Base::Binary | Base::Octal) {
487487
let base = base as u32;
488488
let s = self.str_from_to(start + BytePos(2), end);
@@ -492,8 +492,9 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
492492
start + BytePos::from_usize(2 + idx + c.len_utf8()),
493493
);
494494
if c != '_' && c.to_digit(base).is_none() {
495-
self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
496-
kind = token::Err;
495+
let guar =
496+
self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
497+
kind = token::Err(guar);
497498
}
498499
}
499500
}
@@ -711,7 +712,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
711712
let hi = lo + BytePos(end - start);
712713
let span = self.mk_sp(lo, hi);
713714
let is_fatal = err.is_fatal();
714-
if let Some(_guar) = emit_unescape_error(
715+
if let Some(guar) = emit_unescape_error(
715716
self.dcx(),
716717
lit_content,
717718
span_with_quotes,
@@ -721,18 +722,19 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
721722
err,
722723
) {
723724
assert!(is_fatal);
724-
kind = token::Err;
725+
kind = token::Err(guar);
725726
}
726727
}
727728
});
728729

729730
// We normally exclude the quotes for the symbol, but for errors we
730731
// include it because it results in clearer error messages.
731-
if kind != token::Err {
732-
(kind, Symbol::intern(lit_content))
732+
let sym = if !matches!(kind, token::Err(_)) {
733+
Symbol::intern(lit_content)
733734
} else {
734-
(token::Err, self.symbol_from_to(start, end))
735-
}
735+
self.symbol_from_to(start, end)
736+
};
737+
(kind, sym)
736738
}
737739

738740
fn cook_unicode(

Diff for: compiler/rustc_parse/src/parser/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2140,12 +2140,12 @@ impl<'a> Parser<'a> {
21402140
Err(err) => {
21412141
let span = token.uninterpolated_span();
21422142
self.bump();
2143-
report_lit_error(self.sess, err, lit, span);
2143+
let guar = report_lit_error(self.sess, err, lit, span);
21442144
// Pack possible quotes and prefixes from the original literal into
21452145
// the error literal's symbol so they can be pretty-printed faithfully.
21462146
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
21472147
let symbol = Symbol::intern(&suffixless_lit.to_string());
2148-
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
2148+
let lit = token::Lit::new(token::Err(guar), symbol, lit.suffix);
21492149
Some(
21502150
MetaItemLit::from_token_lit(lit, span)
21512151
.unwrap_or_else(|_| unreachable!()),

Diff for: compiler/rustc_parse/src/parser/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,7 @@ impl<'a> Parser<'a> {
14591459
match self.parse_str_lit() {
14601460
Ok(str_lit) => Some(str_lit),
14611461
Err(Some(lit)) => match lit.kind {
1462-
ast::LitKind::Err => None,
1462+
ast::LitKind::Err(_) => None,
14631463
_ => {
14641464
self.dcx().emit_err(NonStringAbiLiteral { span: lit.span });
14651465
None

Diff for: compiler/rustc_parse/src/validate_attr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
7070
}
7171
}
7272
Err(err) => {
73-
report_lit_error(sess, err, token_lit, expr.span);
73+
let guar = report_lit_error(sess, err, token_lit, expr.span);
7474
let lit = ast::MetaItemLit {
7575
symbol: token_lit.symbol,
7676
suffix: token_lit.suffix,
77-
kind: ast::LitKind::Err,
77+
kind: ast::LitKind::Err(guar),
7878
span: expr.span,
7979
};
8080
MetaItemKind::NameValue(lit)

Diff for: library/proc_macro/src/bridge/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,11 @@ pub enum LitKind {
337337
ByteStrRaw(u8),
338338
CStr,
339339
CStrRaw(u8),
340-
Err,
340+
// This should have an `ErrorGuaranteed`, except that type isn't available
341+
// in this crate. (Imagine it is there.) Hence the `WithGuar` suffix. Must
342+
// only be constructed in `LitKind::from_internal`, where an
343+
// `ErrorGuaranteed` is available.
344+
ErrWithGuar,
341345
}
342346

343347
rpc_encode_decode!(
@@ -352,7 +356,7 @@ rpc_encode_decode!(
352356
ByteStrRaw(n),
353357
CStr,
354358
CStrRaw(n),
355-
Err,
359+
ErrWithGuar,
356360
}
357361
);
358362

Diff for: library/proc_macro/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ impl Literal {
14511451
f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
14521452
}
14531453

1454-
bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::Err => {
1454+
bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
14551455
f(&[symbol, suffix])
14561456
}
14571457
})

0 commit comments

Comments
 (0)