about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-02-14 20:12:05 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2024-02-15 14:46:08 +1100
commit25ed6e43b0ea03ca48692741624f3e70d717ea43 (patch)
tree7c4dc20f60c6c62d239cd710400998f405ab1bd8 /compiler
parent332c57723a03e97497d6fba6636e31c2e41fefe9 (diff)
downloadrust-25ed6e43b0ea03ca48692741624f3e70d717ea43.tar.gz
rust-25ed6e43b0ea03ca48692741624f3e70d717ea43.zip
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.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast/src/ast.rs4
-rw-r--r--compiler/rustc_ast/src/token.rs12
-rw-r--r--compiler/rustc_ast/src/util/literal.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs3
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs2
-rw-r--r--compiler/rustc_expand/src/base.rs2
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs22
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs12
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs22
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs4
18 files changed, 69 insertions, 53 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 098e2606a3b..b74938621b3 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1846,7 +1846,7 @@ pub enum LitKind {
     /// A boolean literal (`true`, `false`).
     Bool(bool),
     /// Placeholder for a literal that wasn't well-formed in some way.
-    Err,
+    Err(ErrorGuaranteed),
 }
 
 impl LitKind {
@@ -1893,7 +1893,7 @@ impl LitKind {
             | LitKind::Int(_, LitIntType::Unsuffixed)
             | LitKind::Float(_, LitFloatType::Unsuffixed)
             | LitKind::Bool(..)
-            | LitKind::Err => false,
+            | LitKind::Err(_) => false,
         }
     }
 }
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index d62462b1ae3..50fe37dcdb6 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -13,7 +13,7 @@ use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::{kw, sym};
 #[allow(hidden_glob_reexports)]
 use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{edition::Edition, Span, DUMMY_SP};
+use rustc_span::{edition::Edition, ErrorGuaranteed, Span, DUMMY_SP};
 use std::borrow::Cow;
 use std::fmt;
 
@@ -75,7 +75,7 @@ pub enum LitKind {
     ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols
     CStr,
     CStrRaw(u8),
-    Err,
+    Err(ErrorGuaranteed),
 }
 
 /// A literal token.
@@ -144,7 +144,7 @@ impl fmt::Display for Lit {
             CStrRaw(n) => {
                 write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))?
             }
-            Integer | Float | Bool | Err => write!(f, "{symbol}")?,
+            Integer | Float | Bool | Err(_) => write!(f, "{symbol}")?,
         }
 
         if let Some(suffix) = suffix {
@@ -159,7 +159,7 @@ impl LitKind {
     /// An English article for the literal token kind.
     pub fn article(self) -> &'static str {
         match self {
-            Integer | Err => "an",
+            Integer | Err(_) => "an",
             _ => "a",
         }
     }
@@ -174,12 +174,12 @@ impl LitKind {
             Str | StrRaw(..) => "string",
             ByteStr | ByteStrRaw(..) => "byte string",
             CStr | CStrRaw(..) => "C string",
-            Err => "error",
+            Err(_) => "error",
         }
     }
 
     pub(crate) fn may_have_suffix(self) -> bool {
-        matches!(self, Integer | Float | Err)
+        matches!(self, Integer | Float | Err(_))
     }
 }
 
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index fbe72252ec9..e4bb23675cb 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -144,7 +144,7 @@ impl LitKind {
                 buf.push(0);
                 LitKind::CStr(buf.into(), StrStyle::Raw(n))
             }
-            token::Err => LitKind::Err,
+            token::Err(guar) => LitKind::Err(guar),
         })
     }
 }
@@ -201,7 +201,7 @@ impl fmt::Display for LitKind {
                 }
             }
             LitKind::Bool(b) => write!(f, "{}", if b { "true" } else { "false" })?,
-            LitKind::Err => {
+            LitKind::Err(_) => {
                 // This only shows up in places like `-Zunpretty=hir` output, so we
                 // don't bother to produce something useful.
                 write!(f, "<bad-literal>")?;
@@ -237,7 +237,7 @@ impl MetaItemLit {
             LitKind::Char(_) => token::Char,
             LitKind::Int(..) => token::Integer,
             LitKind::Float(..) => token::Float,
-            LitKind::Err => token::Err,
+            LitKind::Err(guar) => token::Err(guar),
         };
 
         token::Lit::new(kind, self.symbol, self.suffix)
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 73d1d891bb9..2112040621e 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -124,8 +124,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let lit_kind = match LitKind::from_token_lit(*token_lit) {
                         Ok(lit_kind) => lit_kind,
                         Err(err) => {
-                            report_lit_error(&self.tcx.sess.parse_sess, err, *token_lit, e.span);
-                            LitKind::Err
+                            let guar = report_lit_error(
+                                &self.tcx.sess.parse_sess,
+                                err,
+                                *token_lit,
+                                e.span,
+                            );
+                            LitKind::Err(guar)
                         }
                     };
                     let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind));
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 6b5fc014240..eab1383b635 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -966,10 +966,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 {
                     lit
                 } else {
+                    let guar = self.dcx().has_errors().unwrap();
                     MetaItemLit {
                         symbol: kw::Empty,
                         suffix: None,
-                        kind: LitKind::Err,
+                        kind: LitKind::Err(guar),
                         span: DUMMY_SP,
                     }
                 };
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index cda746894e8..2765b235f99 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -254,7 +254,7 @@ fn literal_to_string(lit: token::Lit) -> String {
         token::CStrRaw(n) => {
             format!("cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))
         }
-        token::Integer | token::Float | token::Bool | token::Err => symbol.to_string(),
+        token::Integer | token::Float | token::Bool | token::Err(_) => symbol.to_string(),
     };
 
     if let Some(suffix) = suffix {
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index dade29593af..795161e65d8 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -40,7 +40,7 @@ pub fn expand_concat(
                     cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
                     has_errors = true;
                 }
-                Ok(ast::LitKind::Err) => {
+                Ok(ast::LitKind::Err(_)) => {
                     has_errors = true;
                 }
                 Err(err) => {
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index a01bbeac824..3ef8cb7bffe 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -44,7 +44,7 @@ fn invalid_type_err(
         Ok(ast::LitKind::Bool(_)) => {
             dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None });
         }
-        Ok(ast::LitKind::Err) => {}
+        Ok(ast::LitKind::Err(_)) => {}
         Ok(ast::LitKind::Int(_, _)) if !is_nested => {
             let sugg =
                 snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet });
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index cfeb31fc4c8..09ab26421d6 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1266,7 +1266,7 @@ pub fn expr_to_spanned_string<'a>(
                 );
                 Some((err, true))
             }
-            Ok(ast::LitKind::Err) => None,
+            Ok(ast::LitKind::Err(_)) => None,
             Err(err) => {
                 report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span);
                 None
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 3a78bd94505..8f31b5801da 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -10,7 +10,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{MultiSpan, PResult};
+use rustc_errors::{ErrorGuaranteed, MultiSpan, PResult};
 use rustc_parse::lexer::nfc_normalize;
 use rustc_parse::parse_stream_from_source_str;
 use rustc_session::parse::ParseSess;
@@ -63,7 +63,12 @@ impl FromInternal<token::LitKind> for LitKind {
             token::ByteStrRaw(n) => LitKind::ByteStrRaw(n),
             token::CStr => LitKind::CStr,
             token::CStrRaw(n) => LitKind::CStrRaw(n),
-            token::Err => LitKind::Err,
+            token::Err(_guar) => {
+                // This is the only place a `pm::bridge::LitKind::ErrWithGuar`
+                // is constructed. Note that an `ErrorGuaranteed` is available,
+                // as required. See the comment in `to_internal`.
+                LitKind::ErrWithGuar
+            }
             token::Bool => unreachable!(),
         }
     }
@@ -82,7 +87,16 @@ impl ToInternal<token::LitKind> for LitKind {
             LitKind::ByteStrRaw(n) => token::ByteStrRaw(n),
             LitKind::CStr => token::CStr,
             LitKind::CStrRaw(n) => token::CStrRaw(n),
-            LitKind::Err => token::Err,
+            LitKind::ErrWithGuar => {
+                // This is annoying but valid. `LitKind::ErrWithGuar` would
+                // have an `ErrorGuaranteed` except that type isn't available
+                // in that crate. So we have to fake one. And we don't want to
+                // use a delayed bug because there might be lots of these,
+                // which would be expensive.
+                #[allow(deprecated)]
+                let guar = ErrorGuaranteed::unchecked_error_guaranteed();
+                token::Err(guar)
+            }
         }
     }
 }
@@ -477,7 +491,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
                 | token::LitKind::ByteStrRaw(_)
                 | token::LitKind::CStr
                 | token::LitKind::CStrRaw(_)
-                | token::LitKind::Err => return Err(()),
+                | token::LitKind::Err(_) => return Err(()),
                 token::LitKind::Integer | token::LitKind::Float => {}
             }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 65b8505c090..3bce8a1dd45 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1319,7 +1319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span)))
                     .skip_binder(),
             ),
-            ast::LitKind::Err => Ty::new_misc_error(tcx),
+            ast::LitKind::Err(guar) => Ty::new_error(tcx, guar),
         }
     }
 
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 6636f75d998..7c3d2671d59 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -164,11 +164,7 @@ fn lit_to_mir_constant<'tcx>(
             })?,
         (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
         (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
-        (ast::LitKind::Err, _) => {
-            return Err(LitToConstError::Reported(
-                tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"),
-            ));
-        }
+        (ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
         _ => return Err(LitToConstError::TypeError),
     };
 
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index 71aebd13003..d444de8b28e 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -71,11 +71,7 @@ pub(crate) fn lit_to_const<'tcx>(
             ty::ValTree::from_scalar_int(bits)
         }
         (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
-        (ast::LitKind::Err, _) => {
-            return Err(LitToConstError::Reported(
-                tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"),
-            ));
-        }
+        (ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
         _ => return Err(LitToConstError::TypeError),
     };
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 99952e1c178..62762168cf4 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -897,12 +897,14 @@ impl<'tcx> Cx<'tcx> {
                 let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
                 let generics = self.tcx.generics_of(hir_id.owner);
                 let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
-                    self.tcx.dcx().has_errors().unwrap();
+                    let guar = self.tcx.dcx().has_errors().unwrap();
                     // We already errored about a late bound const
-                    return ExprKind::Literal {
-                        lit: &Spanned { span: DUMMY_SP, node: LitKind::Err },
-                        neg: false,
-                    };
+
+                    let lit = self
+                        .tcx
+                        .hir_arena
+                        .alloc(Spanned { span: DUMMY_SP, node: LitKind::Err(guar) });
+                    return ExprKind::Literal { lit, neg: false };
                 };
                 let name = self.tcx.hir().name(hir_id);
                 let param = ty::ParamConst::new(index, name);
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 7502a556794..c768ea93b5f 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -481,8 +481,8 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 let mut kind = token::Integer;
                 if empty_int {
                     let span = self.mk_sp(start, end);
-                    self.dcx().emit_err(errors::NoDigitsLiteral { span });
-                    kind = token::Err;
+                    let guar = self.dcx().emit_err(errors::NoDigitsLiteral { span });
+                    kind = token::Err(guar);
                 } else if matches!(base, Base::Binary | Base::Octal) {
                     let base = base as u32;
                     let s = self.str_from_to(start + BytePos(2), end);
@@ -492,8 +492,9 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             start + BytePos::from_usize(2 + idx + c.len_utf8()),
                         );
                         if c != '_' && c.to_digit(base).is_none() {
-                            self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
-                            kind = token::Err;
+                            let guar =
+                                self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
+                            kind = token::Err(guar);
                         }
                     }
                 }
@@ -711,7 +712,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 let hi = lo + BytePos(end - start);
                 let span = self.mk_sp(lo, hi);
                 let is_fatal = err.is_fatal();
-                if let Some(_guar) = emit_unescape_error(
+                if let Some(guar) = emit_unescape_error(
                     self.dcx(),
                     lit_content,
                     span_with_quotes,
@@ -721,18 +722,19 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                     err,
                 ) {
                     assert!(is_fatal);
-                    kind = token::Err;
+                    kind = token::Err(guar);
                 }
             }
         });
 
         // We normally exclude the quotes for the symbol, but for errors we
         // include it because it results in clearer error messages.
-        if kind != token::Err {
-            (kind, Symbol::intern(lit_content))
+        let sym = if !matches!(kind, token::Err(_)) {
+            Symbol::intern(lit_content)
         } else {
-            (token::Err, self.symbol_from_to(start, end))
-        }
+            self.symbol_from_to(start, end)
+        };
+        (kind, sym)
     }
 
     fn cook_unicode(
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 1a57474bac2..2424b6c130d 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2140,12 +2140,12 @@ impl<'a> Parser<'a> {
                     Err(err) => {
                         let span = token.uninterpolated_span();
                         self.bump();
-                        report_lit_error(self.sess, err, lit, span);
+                        let guar = report_lit_error(self.sess, err, lit, span);
                         // 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(&suffixless_lit.to_string());
-                        let lit = token::Lit::new(token::Err, symbol, lit.suffix);
+                        let lit = token::Lit::new(token::Err(guar), symbol, lit.suffix);
                         Some(
                             MetaItemLit::from_token_lit(lit, span)
                                 .unwrap_or_else(|_| unreachable!()),
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 623407eb380..dea2b9e6ca7 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1459,7 +1459,7 @@ impl<'a> Parser<'a> {
         match self.parse_str_lit() {
             Ok(str_lit) => Some(str_lit),
             Err(Some(lit)) => match lit.kind {
-                ast::LitKind::Err => None,
+                ast::LitKind::Err(_) => None,
                 _ => {
                     self.dcx().emit_err(NonStringAbiLiteral { span: lit.span });
                     None
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 2fafbd6d97b..b0982029657 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -70,11 +70,11 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
                             }
                         }
                         Err(err) => {
-                            report_lit_error(sess, err, token_lit, expr.span);
+                            let guar = report_lit_error(sess, err, token_lit, expr.span);
                             let lit = ast::MetaItemLit {
                                 symbol: token_lit.symbol,
                                 suffix: token_lit.suffix,
-                                kind: ast::LitKind::Err,
+                                kind: ast::LitKind::Err(guar),
                                 span: expr.span,
                             };
                             MetaItemKind::NameValue(lit)