diff options
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
| -rw-r--r-- | compiler/rustc_builtin_macros/src/asm.rs | 71 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/assert.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/assert/context.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/cfg.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/compile_error.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/concat.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/concat_bytes.rs | 131 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/concat_idents.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/default.rs | 53 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/env.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format.rs | 90 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/source_util.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/type_ascribe.rs | 4 |
14 files changed, 248 insertions, 252 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 263081ea19e..29bf5e9f304 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -13,7 +13,7 @@ use rustc_session::lint; use rustc_session::parse::ParseSess; use rustc_span::symbol::Ident; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::{InnerSpan, Span}; +use rustc_span::{ErrorGuaranteed, InnerSpan, Span}; use rustc_target::asm::InlineAsmArch; use smallvec::smallvec; @@ -433,7 +433,10 @@ fn parse_reg<'a>( Ok(result) } -fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::InlineAsm> { +fn expand_preparsed_asm( + ecx: &mut ExtCtxt<'_>, + args: AsmArgs, +) -> Result<ast::InlineAsm, ErrorGuaranteed> { let mut template = vec![]; // Register operands are implicitly used since they are not allowed to be // referenced in the template string. @@ -459,10 +462,10 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl match expr_to_spanned_string(ecx, template_expr, msg) { Ok(template_part) => template_part, Err(err) => { - if let Some((err, _)) = err { - err.emit(); - } - return None; + return Err(match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }); } }; @@ -551,8 +554,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end)); e.span_label(err_sp, label); } - e.emit(); - return None; + let guar = e.emit(); + return Err(guar); } curarg = parser.curarg; @@ -719,7 +722,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl } } - Some(ast::InlineAsm { + Ok(ast::InlineAsm { template, template_strs: template_strs.into_boxed_slice(), operands: args.operands, @@ -736,22 +739,21 @@ pub(super) fn expand_asm<'cx>( ) -> Box<dyn base::MacResult + 'cx> { match parse_args(ecx, sp, tts, false) { Ok(args) => { - let expr = if let Some(inline_asm) = expand_preparsed_asm(ecx, args) { - P(ast::Expr { + let expr = match expand_preparsed_asm(ecx, args) { + Ok(inline_asm) => P(ast::Expr { id: ast::DUMMY_NODE_ID, kind: ast::ExprKind::InlineAsm(P(inline_asm)), span: sp, attrs: ast::AttrVec::new(), tokens: None, - }) - } else { - DummyResult::raw_expr(sp, true) + }), + Err(guar) => DummyResult::raw_expr(sp, Some(guar)), }; MacEager::expr(expr) } Err(err) => { - err.emit(); - DummyResult::any(sp) + let guar = err.emit(); + DummyResult::any(sp, guar) } } } @@ -762,28 +764,25 @@ pub(super) fn expand_global_asm<'cx>( tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { match parse_args(ecx, sp, tts, true) { - Ok(args) => { - if let Some(inline_asm) = expand_preparsed_asm(ecx, args) { - MacEager::items(smallvec![P(ast::Item { - ident: Ident::empty(), - attrs: ast::AttrVec::new(), - id: ast::DUMMY_NODE_ID, - kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), - vis: ast::Visibility { - span: sp.shrink_to_lo(), - kind: ast::VisibilityKind::Inherited, - tokens: None, - }, - span: sp, + Ok(args) => match expand_preparsed_asm(ecx, args) { + Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item { + ident: Ident::empty(), + attrs: ast::AttrVec::new(), + id: ast::DUMMY_NODE_ID, + kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), + vis: ast::Visibility { + span: sp.shrink_to_lo(), + kind: ast::VisibilityKind::Inherited, tokens: None, - })]) - } else { - DummyResult::any(sp) - } - } + }, + span: sp, + tokens: None, + })]), + Err(guar) => DummyResult::any(sp, guar), + }, Err(err) => { - err.emit(); - DummyResult::any(sp) + let guar = err.emit(); + DummyResult::any(sp, guar) } } } diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 501d557f3ab..613ce43dec2 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -23,8 +23,8 @@ pub fn expand_assert<'cx>( let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) { Ok(assert) => assert, Err(err) => { - err.emit(); - return DummyResult::any(span); + let guar = err.emit(); + return DummyResult::any(span, guar); } }; diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 7737041090b..56c56b2704b 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -304,7 +304,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::ConstBlock(_) | ExprKind::Continue(_) | ExprKind::Dummy - | ExprKind::Err + | ExprKind::Err(_) | ExprKind::Field(_, _) | ExprKind::ForLoop { .. } | ExprKind::FormatArgs(_) diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 581d390992a..ca66bc0da0c 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -29,8 +29,8 @@ pub fn expand_cfg( MacEager::expr(cx.expr_bool(sp, matches_cfg)) } Err(err) => { - err.emit(); - DummyResult::any(sp) + let guar = err.emit(); + DummyResult::any(sp, guar) } } } diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs index f157575da79..66500351272 100644 --- a/compiler/rustc_builtin_macros/src/compile_error.rs +++ b/compiler/rustc_builtin_macros/src/compile_error.rs @@ -9,16 +9,14 @@ pub fn expand_compile_error<'cx>( sp: Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { - let Some(var) = get_single_str_from_tts(cx, sp, tts, "compile_error!") else { - return DummyResult::any(sp); + let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") { + Ok(var) => var, + Err(guar) => return DummyResult::any(sp, guar), }; - #[expect( - rustc::diagnostic_outside_of_impl, - reason = "diagnostic message is specified by user" - )] + #[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")] #[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")] - cx.dcx().span_err(sp, var.to_string()); + let guar = cx.dcx().span_err(sp, var.to_string()); - DummyResult::any(sp) + DummyResult::any(sp, guar) } diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 691142c03ed..dd4a0e7f228 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -11,12 +11,13 @@ pub fn expand_concat( sp: rustc_span::Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'static> { - let Some(es) = base::get_exprs_from_tts(cx, tts) else { - return DummyResult::any(sp); + let es = match base::get_exprs_from_tts(cx, tts) { + Ok(es) => es, + Err(guar) => return DummyResult::any(sp, guar), }; let mut accumulator = String::new(); let mut missing_literal = vec![]; - let mut has_errors = false; + let mut guar = None; for e in es { match e.kind { ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { @@ -33,19 +34,16 @@ pub fn expand_concat( accumulator.push_str(&b.to_string()); } Ok(ast::LitKind::CStr(..)) => { - cx.dcx().emit_err(errors::ConcatCStrLit { span: e.span }); - has_errors = true; + guar = Some(cx.dcx().emit_err(errors::ConcatCStrLit { span: e.span })); } Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => { - cx.dcx().emit_err(errors::ConcatBytestr { span: e.span }); - has_errors = true; + guar = Some(cx.dcx().emit_err(errors::ConcatBytestr { span: e.span })); } - Ok(ast::LitKind::Err(_)) => { - has_errors = true; + Ok(ast::LitKind::Err(guarantee)) => { + guar = Some(guarantee); } Err(err) => { - report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span); - has_errors = true; + guar = Some(report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span)); } }, // We also want to allow negative numeric literals. @@ -56,8 +54,7 @@ pub fn expand_concat( Ok(ast::LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")), Ok(ast::LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")), Err(err) => { - report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span); - has_errors = true; + guar = Some(report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span)); } _ => missing_literal.push(e.span), } @@ -65,8 +62,8 @@ pub fn expand_concat( ast::ExprKind::IncludedBytes(..) => { cx.dcx().emit_err(errors::ConcatBytestr { span: e.span }); } - ast::ExprKind::Err => { - has_errors = true; + ast::ExprKind::Err(guarantee) => { + guar = Some(guarantee); } ast::ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"), _ => { @@ -76,10 +73,10 @@ pub fn expand_concat( } if !missing_literal.is_empty() { - cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal }); - return DummyResult::any(sp); - } else if has_errors { - return DummyResult::any(sp); + let guar = cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal }); + return DummyResult::any(sp, guar); + } else if let Some(guar) = guar { + return DummyResult::any(sp, guar); } let sp = cx.with_def_site_ctxt(sp); base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator))) diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 8ce004586ce..32e17112d8c 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_ast::{ptr::P, tokenstream::TokenStream}; use rustc_expand::base::{self, DummyResult}; use rustc_session::errors::report_lit_error; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use crate::errors; @@ -12,7 +12,7 @@ fn invalid_type_err( token_lit: ast::token::Lit, span: Span, is_nested: bool, -) { +) -> ErrorGuaranteed { use errors::{ ConcatBytesInvalid, ConcatBytesInvalidSuggestion, ConcatBytesNonU8, ConcatBytesOob, }; @@ -22,12 +22,12 @@ fn invalid_type_err( Ok(ast::LitKind::CStr(_, _)) => { // Avoid ambiguity in handling of terminal `NUL` by refusing to // concatenate C string literals as bytes. - dcx.emit_err(errors::ConcatCStrLit { span: span }); + dcx.emit_err(errors::ConcatCStrLit { span }) } Ok(ast::LitKind::Char(_)) => { let sugg = snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet }); - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg }); + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg }) } Ok(ast::LitKind::Str(_, _)) => { // suggestion would be invalid if we are nested @@ -36,86 +36,79 @@ fn invalid_type_err( } else { None }; - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg }); + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg }) } Ok(ast::LitKind::Float(_, _)) => { - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None }); + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None }) } Ok(ast::LitKind::Bool(_)) => { - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None }); + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None }) } - Ok(ast::LitKind::Err(_)) => {} Ok(ast::LitKind::Int(_, _)) if !is_nested => { let sugg = snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet }); - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg }); + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg }) } Ok(ast::LitKind::Int( val, ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8), )) => { assert!(val.get() > u8::MAX.into()); // must be an error - dcx.emit_err(ConcatBytesOob { span }); - } - Ok(ast::LitKind::Int(_, _)) => { - dcx.emit_err(ConcatBytesNonU8 { span }); + dcx.emit_err(ConcatBytesOob { span }) } + Ok(ast::LitKind::Int(_, _)) => dcx.emit_err(ConcatBytesNonU8 { span }), Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(), - Err(err) => { - report_lit_error(&cx.sess.parse_sess, err, token_lit, span); - } + Ok(ast::LitKind::Err(guar)) => guar, + Err(err) => report_lit_error(&cx.sess.parse_sess, err, token_lit, span), } } +/// Returns `expr` as a *single* byte literal if applicable. +/// +/// Otherwise, returns `None`, and either pushes the `expr`'s span to `missing_literals` or +/// updates `guar` accordingly. fn handle_array_element( cx: &mut base::ExtCtxt<'_>, - has_errors: &mut bool, + guar: &mut Option<ErrorGuaranteed>, missing_literals: &mut Vec<rustc_span::Span>, expr: &P<rustc_ast::Expr>, ) -> Option<u8> { let dcx = cx.dcx(); - match expr.kind { - ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => { - if !*has_errors { - dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false }); - } - *has_errors = true; - None - } - ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { - Ok(ast::LitKind::Int( - val, - ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8), - )) if val.get() <= u8::MAX.into() => Some(val.get() as u8), - Ok(ast::LitKind::Byte(val)) => Some(val), - Ok(ast::LitKind::ByteStr(..)) => { - if !*has_errors { - dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true }); + match expr.kind { + ast::ExprKind::Lit(token_lit) => { + match ast::LitKind::from_token_lit(token_lit) { + Ok(ast::LitKind::Int( + val, + ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8), + )) if let Ok(val) = u8::try_from(val.get()) => { + return Some(val); } - *has_errors = true; - None - } - _ => { - if !*has_errors { - invalid_type_err(cx, token_lit, expr.span, true); + Ok(ast::LitKind::Byte(val)) => return Some(val), + Ok(ast::LitKind::ByteStr(..)) => { + guar.get_or_insert_with(|| { + dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true }) + }); } - *has_errors = true; - None - } - }, - ast::ExprKind::IncludedBytes(..) => { - if !*has_errors { - dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false }); - } - *has_errors = true; - None + _ => { + guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, expr.span, true)); + } + }; } - _ => { - missing_literals.push(expr.span); - None + ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => { + guar.get_or_insert_with(|| { + dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false }) + }); + } + ast::ExprKind::IncludedBytes(..) => { + guar.get_or_insert_with(|| { + dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false }) + }); } + _ => missing_literals.push(expr.span), } + + None } pub fn expand_concat_bytes( @@ -123,18 +116,19 @@ pub fn expand_concat_bytes( sp: rustc_span::Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'static> { - let Some(es) = base::get_exprs_from_tts(cx, tts) else { - return DummyResult::any(sp); + let es = match base::get_exprs_from_tts(cx, tts) { + Ok(es) => es, + Err(guar) => return DummyResult::any(sp, guar), }; let mut accumulator = Vec::new(); let mut missing_literals = vec![]; - let mut has_errors = false; + let mut guar = None; for e in es { match &e.kind { ast::ExprKind::Array(exprs) => { for expr in exprs { if let Some(elem) = - handle_array_element(cx, &mut has_errors, &mut missing_literals, expr) + handle_array_element(cx, &mut guar, &mut missing_literals, expr) { accumulator.push(elem); } @@ -146,14 +140,16 @@ pub fn expand_concat_bytes( ast::LitKind::from_token_lit(token_lit) { if let Some(elem) = - handle_array_element(cx, &mut has_errors, &mut missing_literals, expr) + handle_array_element(cx, &mut guar, &mut missing_literals, expr) { for _ in 0..count_val.get() { accumulator.push(elem); } } } else { - cx.dcx().emit_err(errors::ConcatBytesBadRepeat { span: count.value.span }); + guar = Some( + cx.dcx().emit_err(errors::ConcatBytesBadRepeat { span: count.value.span }), + ); } } &ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { @@ -164,17 +160,14 @@ pub fn expand_concat_bytes( accumulator.extend_from_slice(bytes); } _ => { - if !has_errors { - invalid_type_err(cx, token_lit, e.span, false); - } - has_errors = true; + guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, e.span, false)); } }, ast::ExprKind::IncludedBytes(bytes) => { accumulator.extend_from_slice(bytes); } - ast::ExprKind::Err => { - has_errors = true; + ast::ExprKind::Err(guarantee) => { + guar = Some(*guarantee); } ast::ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"), _ => { @@ -183,10 +176,10 @@ pub fn expand_concat_bytes( } } if !missing_literals.is_empty() { - cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals }); - return base::MacEager::expr(DummyResult::raw_expr(sp, true)); - } else if has_errors { - return base::MacEager::expr(DummyResult::raw_expr(sp, true)); + let guar = cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals }); + return base::MacEager::expr(DummyResult::raw_expr(sp, Some(guar))); + } else if let Some(guar) = guar { + return base::MacEager::expr(DummyResult::raw_expr(sp, Some(guar))); } let sp = cx.with_def_site_ctxt(sp); base::MacEager::expr(cx.expr_byte_str(sp, accumulator)) diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs index 17fd3901cc6..29d3f6164aa 100644 --- a/compiler/rustc_builtin_macros/src/concat_idents.rs +++ b/compiler/rustc_builtin_macros/src/concat_idents.rs @@ -14,8 +14,8 @@ pub fn expand_concat_idents<'cx>( tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { if tts.is_empty() { - cx.dcx().emit_err(errors::ConcatIdentsMissingArgs { span: sp }); - return DummyResult::any(sp); + let guar = cx.dcx().emit_err(errors::ConcatIdentsMissingArgs { span: sp }); + return DummyResult::any(sp, guar); } let mut res_str = String::new(); @@ -24,8 +24,8 @@ pub fn expand_concat_idents<'cx>( match e { TokenTree::Token(Token { kind: token::Comma, .. }, _) => {} _ => { - cx.dcx().emit_err(errors::ConcatIdentsMissingComma { span: sp }); - return DummyResult::any(sp); + let guar = cx.dcx().emit_err(errors::ConcatIdentsMissingComma { span: sp }); + return DummyResult::any(sp, guar); } } } else { @@ -36,8 +36,8 @@ pub fn expand_concat_idents<'cx>( } } - cx.dcx().emit_err(errors::ConcatIdentsIdentArgs { span: sp }); - return DummyResult::any(sp); + let guar = cx.dcx().emit_err(errors::ConcatIdentsIdentArgs { span: sp }); + return DummyResult::any(sp, guar); } } diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 0bd2d423a29..386d4a54b65 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -6,7 +6,7 @@ use rustc_ast::{attr, walk_list, EnumDef, VariantData}; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::symbol::Ident; use rustc_span::symbol::{kw, sym}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use smallvec::SmallVec; use thin_vec::{thin_vec, ThinVec}; @@ -83,16 +83,19 @@ fn default_enum_substructure( trait_span: Span, enum_def: &EnumDef, ) -> BlockOrExpr { - let expr = if let Ok(default_variant) = extract_default_variant(cx, enum_def, trait_span) - && let Ok(_) = validate_default_attribute(cx, default_variant) - { - // We now know there is exactly one unit variant with exactly one `#[default]` attribute. - cx.expr_path(cx.path( - default_variant.span, - vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident], - )) - } else { - DummyResult::raw_expr(trait_span, true) + let expr = match try { + let default_variant = extract_default_variant(cx, enum_def, trait_span)?; + validate_default_attribute(cx, default_variant)?; + default_variant + } { + Ok(default_variant) => { + // We now know there is exactly one unit variant with exactly one `#[default]` attribute. + cx.expr_path(cx.path( + default_variant.span, + vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident], + )) + } + Err(guar) => DummyResult::raw_expr(trait_span, Some(guar)), }; BlockOrExpr::new_expr(expr) } @@ -101,7 +104,7 @@ fn extract_default_variant<'a>( cx: &mut ExtCtxt<'_>, enum_def: &'a EnumDef, trait_span: Span, -) -> Result<&'a rustc_ast::Variant, ()> { +) -> Result<&'a rustc_ast::Variant, ErrorGuaranteed> { let default_variants: SmallVec<[_; 1]> = enum_def .variants .iter() @@ -120,9 +123,9 @@ fn extract_default_variant<'a>( let suggs = possible_defaults .map(|v| errors::NoDefaultVariantSugg { span: v.span, ident: v.ident }) .collect(); - cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs }); + let guar = cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs }); - return Err(()); + return Err(guar); } [first, rest @ ..] => { let suggs = default_variants @@ -140,28 +143,28 @@ fn extract_default_variant<'a>( .then_some(errors::MultipleDefaultsSugg { spans, ident: variant.ident }) }) .collect(); - cx.dcx().emit_err(errors::MultipleDefaults { + let guar = cx.dcx().emit_err(errors::MultipleDefaults { span: trait_span, first: first.span, additional: rest.iter().map(|v| v.span).collect(), suggs, }); - return Err(()); + return Err(guar); } }; if !matches!(variant.data, VariantData::Unit(..)) { - cx.dcx().emit_err(errors::NonUnitDefault { span: variant.ident.span }); - return Err(()); + let guar = cx.dcx().emit_err(errors::NonUnitDefault { span: variant.ident.span }); + return Err(guar); } if let Some(non_exhaustive_attr) = attr::find_by_name(&variant.attrs, sym::non_exhaustive) { - cx.dcx().emit_err(errors::NonExhaustiveDefault { + let guar = cx.dcx().emit_err(errors::NonExhaustiveDefault { span: variant.ident.span, non_exhaustive: non_exhaustive_attr.span, }); - return Err(()); + return Err(guar); } Ok(variant) @@ -170,7 +173,7 @@ fn extract_default_variant<'a>( fn validate_default_attribute( cx: &mut ExtCtxt<'_>, default_variant: &rustc_ast::Variant, -) -> Result<(), ()> { +) -> Result<(), ErrorGuaranteed> { let attrs: SmallVec<[_; 1]> = attr::filter_by_name(&default_variant.attrs, kw::Default).collect(); @@ -183,7 +186,7 @@ fn validate_default_attribute( let sugg = errors::MultipleDefaultAttrsSugg { spans: rest.iter().map(|attr| attr.span).collect(), }; - cx.dcx().emit_err(errors::MultipleDefaultAttrs { + let guar = cx.dcx().emit_err(errors::MultipleDefaultAttrs { span: default_variant.ident.span, first: first.span, first_rest: rest[0].span, @@ -192,13 +195,13 @@ fn validate_default_attribute( sugg, }); - return Err(()); + return Err(guar); } }; if !attr.is_word() { - cx.dcx().emit_err(errors::DefaultHasArg { span: attr.span }); + let guar = cx.dcx().emit_err(errors::DefaultHasArg { span: attr.span }); - return Err(()); + return Err(guar); } Ok(()) } diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index a0fd0e3f9be..67ace546ad0 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -28,8 +28,9 @@ pub fn expand_option_env<'cx>( sp: Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { - let Some(var) = get_single_str_from_tts(cx, sp, tts, "option_env!") else { - return DummyResult::any(sp); + let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") { + Ok(var) => var, + Err(guar) => return DummyResult::any(sp, guar), }; let sp = cx.with_def_site_ctxt(sp); @@ -65,24 +66,25 @@ pub fn expand_env<'cx>( tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { let mut exprs = match get_exprs_from_tts(cx, tts) { - Some(exprs) if exprs.is_empty() || exprs.len() > 2 => { - cx.dcx().emit_err(errors::EnvTakesArgs { span: sp }); - return DummyResult::any(sp); + Ok(exprs) if exprs.is_empty() || exprs.len() > 2 => { + let guar = cx.dcx().emit_err(errors::EnvTakesArgs { span: sp }); + return DummyResult::any(sp, guar); } - None => return DummyResult::any(sp), - Some(exprs) => exprs.into_iter(), + Err(guar) => return DummyResult::any(sp, guar), + Ok(exprs) => exprs.into_iter(), }; let var_expr = exprs.next().unwrap(); - let Some((var, _)) = expr_to_string(cx, var_expr.clone(), "expected string literal") else { - return DummyResult::any(sp); + let var = match expr_to_string(cx, var_expr.clone(), "expected string literal") { + Ok((var, _)) => var, + Err(guar) => return DummyResult::any(sp, guar), }; let custom_msg = match exprs.next() { None => None, Some(second) => match expr_to_string(cx, second, "expected string literal") { - None => return DummyResult::any(sp), - Some((s, _)) => Some(s), + Ok((s, _)) => Some(s), + Err(guar) => return DummyResult::any(sp, guar), }, }; @@ -100,23 +102,23 @@ pub fn expand_env<'cx>( unreachable!("`expr_to_string` ensures this is a string lit") }; - if let Some(msg_from_user) = custom_msg { - cx.dcx().emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user }); + let guar = if let Some(msg_from_user) = custom_msg { + cx.dcx().emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user }) } else if is_cargo_env_var(var.as_str()) { cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar { span, var: *symbol, var_expr: var_expr.ast_deref(), - }); + }) } else { cx.dcx().emit_err(errors::EnvNotDefined::CustomEnvVar { span, var: *symbol, var_expr: var_expr.ast_deref(), - }); - } + }) + }; - return DummyResult::any(sp); + return DummyResult::any(sp, guar); } Some(value) => cx.expr_str(span, value), }; diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 3366378d38d..06c2b617706 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -13,7 +13,7 @@ use rustc_expand::base::{self, *}; use rustc_parse::parser::Recovered; use rustc_parse_format as parse; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::{BytePos, InnerSpan, Span}; +use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span}; use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId}; @@ -160,7 +160,7 @@ fn make_format_args( ecx: &mut ExtCtxt<'_>, input: MacroInput, append_newline: bool, -) -> Result<FormatArgs, ()> { +) -> Result<FormatArgs, ErrorGuaranteed> { let msg = "format argument must be a string literal"; let unexpanded_fmt_span = input.fmtstr.span; @@ -173,38 +173,41 @@ fn make_format_args( } Ok(fmt) => fmt, Err(err) => { - if let Some((mut err, suggested)) = err { - if !suggested { - if let ExprKind::Block(block, None) = &efmt.kind - && block.stmts.len() == 1 - && let StmtKind::Expr(expr) = &block.stmts[0].kind - && let ExprKind::Path(None, path) = &expr.kind - && path.is_potential_trivial_const_arg() - { - err.multipart_suggestion( - "quote your inlined format argument to use as string literal", - vec![ - (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()), - (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()), - ], - Applicability::MaybeIncorrect, - ); - } else { - let sugg_fmt = match args.explicit_args().len() { - 0 => "{}".to_string(), - _ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())), - }; - err.span_suggestion( - unexpanded_fmt_span.shrink_to_lo(), - "you might be missing a string literal to format with", - format!("\"{sugg_fmt}\", "), - Applicability::MaybeIncorrect, - ); + let guar = match err { + Ok((mut err, suggested)) => { + if !suggested { + if let ExprKind::Block(block, None) = &efmt.kind + && block.stmts.len() == 1 + && let StmtKind::Expr(expr) = &block.stmts[0].kind + && let ExprKind::Path(None, path) = &expr.kind + && path.is_potential_trivial_const_arg() + { + err.multipart_suggestion( + "quote your inlined format argument to use as string literal", + vec![ + (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()), + (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } else { + let sugg_fmt = match args.explicit_args().len() { + 0 => "{}".to_string(), + _ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())), + }; + err.span_suggestion( + unexpanded_fmt_span.shrink_to_lo(), + "you might be missing a string literal to format with", + format!("\"{sugg_fmt}\", "), + Applicability::MaybeIncorrect, + ); + } } + err.emit() } - err.emit(); - } - return Err(()); + Err(guar) => guar, + }; + return Err(guar); } }; @@ -293,8 +296,8 @@ fn make_format_args( } } } - ecx.dcx().emit_err(e); - return Err(()); + let guar = ecx.dcx().emit_err(e); + return Err(guar); } let to_span = |inner_span: rustc_parse_format::InnerSpan| { @@ -353,9 +356,9 @@ fn make_format_args( } else { // For the moment capturing variables from format strings expanded from macros is // disabled (see RFC #2795) - ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name }); + let guar = ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name }); unnamed_arg_after_named_arg = true; - DummyResult::raw_expr(span, true) + DummyResult::raw_expr(span, Some(guar)) }; Ok(args.add(FormatArgument { kind: FormatArgumentKind::Captured(ident), expr })) } @@ -972,16 +975,13 @@ fn expand_format_args_impl<'cx>( ) -> Box<dyn base::MacResult + 'cx> { sp = ecx.with_def_site_ctxt(sp); match parse_args(ecx, sp, tts) { - Ok(input) => { - if let Ok(format_args) = make_format_args(ecx, input, nl) { - MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args)))) - } else { - MacEager::expr(DummyResult::raw_expr(sp, true)) - } - } + Ok(input) => match make_format_args(ecx, input, nl) { + Ok(format_args) => MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args)))), + Err(guar) => MacEager::expr(DummyResult::raw_expr(sp, Some(guar))), + }, Err(err) => { - err.emit(); - DummyResult::any(sp) + let guar = err.emit(); + DummyResult::any(sp, guar) } } } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index d30ccab2394..f344dbcd10c 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -15,6 +15,7 @@ #![feature(lint_reasons)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] +#![feature(try_blocks)] extern crate proc_macro; diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 43d13569d1e..3860057e1d4 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -103,15 +103,16 @@ pub fn expand_include<'cx>( tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { let sp = cx.with_def_site_ctxt(sp); - let Some(file) = get_single_str_from_tts(cx, sp, tts, "include!") else { - return DummyResult::any(sp); + let file = match get_single_str_from_tts(cx, sp, tts, "include!") { + Ok(file) => file, + Err(guar) => return DummyResult::any(sp, guar), }; // The file will be added to the code map by the parser let file = match resolve_path(&cx.sess, file.as_str(), sp) { Ok(f) => f, Err(err) => { - err.emit(); - return DummyResult::any(sp); + let guar = err.emit(); + return DummyResult::any(sp, guar); } }; let p = new_parser_from_file(cx.parse_sess(), &file, Some(sp)); @@ -130,7 +131,7 @@ pub fn expand_include<'cx>( } impl<'a> base::MacResult for ExpandResult<'a> { fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> { - let r = base::parse_expr(&mut self.p)?; + let expr = base::parse_expr(&mut self.p).ok()?; if self.p.token != token::Eof { self.p.sess.buffer_lint( INCOMPLETE_INCLUDE, @@ -139,7 +140,7 @@ pub fn expand_include<'cx>( "include macro expected single expression in source", ); } - Some(r) + Some(expr) } fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> { @@ -176,14 +177,15 @@ pub fn expand_include_str( tts: TokenStream, ) -> Box<dyn base::MacResult + 'static> { let sp = cx.with_def_site_ctxt(sp); - let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else { - return DummyResult::any(sp); + let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") { + Ok(file) => file, + Err(guar) => return DummyResult::any(sp, guar), }; let file = match resolve_path(&cx.sess, file.as_str(), sp) { Ok(f) => f, Err(err) => { - err.emit(); - return DummyResult::any(sp); + let guar = err.emit(); + return DummyResult::any(sp, guar); } }; match cx.source_map().load_binary_file(&file) { @@ -193,13 +195,13 @@ pub fn expand_include_str( base::MacEager::expr(cx.expr_str(sp, interned_src)) } Err(_) => { - cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display())); - DummyResult::any(sp) + let guar = cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display())); + DummyResult::any(sp, guar) } }, Err(e) => { - cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e)); - DummyResult::any(sp) + let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e)); + DummyResult::any(sp, guar) } } } @@ -210,14 +212,15 @@ pub fn expand_include_bytes( tts: TokenStream, ) -> Box<dyn base::MacResult + 'static> { let sp = cx.with_def_site_ctxt(sp); - let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else { - return DummyResult::any(sp); + let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") { + Ok(file) => file, + Err(guar) => return DummyResult::any(sp, guar), }; let file = match resolve_path(&cx.sess, file.as_str(), sp) { Ok(f) => f, Err(err) => { - err.emit(); - return DummyResult::any(sp); + let guar = err.emit(); + return DummyResult::any(sp, guar); } }; match cx.source_map().load_binary_file(&file) { @@ -226,8 +229,8 @@ pub fn expand_include_bytes( base::MacEager::expr(expr) } Err(e) => { - cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e)); - DummyResult::any(sp) + let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e)); + DummyResult::any(sp, guar) } } } diff --git a/compiler/rustc_builtin_macros/src/type_ascribe.rs b/compiler/rustc_builtin_macros/src/type_ascribe.rs index 564797012ae..e8b8fe75338 100644 --- a/compiler/rustc_builtin_macros/src/type_ascribe.rs +++ b/compiler/rustc_builtin_macros/src/type_ascribe.rs @@ -13,8 +13,8 @@ pub fn expand_type_ascribe( let (expr, ty) = match parse_ascribe(cx, tts) { Ok(parsed) => parsed, Err(err) => { - err.emit(); - return DummyResult::any(span); + let guar = err.emit(); + return DummyResult::any(span, guar); } }; |
