Add ErrorGuaranteed
to ast::ExprKind::Err
This commit is contained in:
parent
a3fce72a27
commit
c440a5b814
37 changed files with 660 additions and 602 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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(_)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, expr.span, true));
|
||||
}
|
||||
};
|
||||
}
|
||||
ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
|
||||
guar.get_or_insert_with(|| {
|
||||
dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false })
|
||||
});
|
||||
}
|
||||
ast::ExprKind::IncludedBytes(..) => {
|
||||
if !*has_errors {
|
||||
dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
|
||||
}
|
||||
*has_errors = true;
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
missing_literals.push(expr.span);
|
||||
None
|
||||
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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#![feature(lint_reasons)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(proc_macro_quote)]
|
||||
#![feature(try_blocks)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue