Skip to content

Commit

Permalink
delay expand macro bang when there has indeterminate path
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanjoi committed Mar 13, 2024
1 parent e61dcc7 commit 988c172
Show file tree
Hide file tree
Showing 26 changed files with 497 additions and 255 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3599,6 +3599,7 @@ dependencies = [
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_lexer",
"rustc_lint_defs",
Expand Down Expand Up @@ -3873,6 +3874,7 @@ dependencies = [
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_lexer",
"rustc_lint_defs",
"rustc_macros",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = {path = "../rustc_hir"}
rustc_index = { path = "../rustc_index" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
Expand Down
76 changes: 44 additions & 32 deletions compiler/rustc_builtin_macros/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_ast::token::{self, Delimiter};
use rustc_ast::tokenstream::TokenStream;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::PResult;
use rustc_expand::base::{self, *};
use rustc_expand::base::*;
use rustc_index::bit_set::GrowableBitSet;
use rustc_parse::parser::Parser;
use rustc_parse_format as parse;
Expand Down Expand Up @@ -443,7 +443,7 @@ fn parse_reg<'a>(
fn expand_preparsed_asm(
ecx: &mut ExtCtxt<'_>,
args: AsmArgs,
) -> Result<ast::InlineAsm, ErrorGuaranteed> {
) -> ExpandResult<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.
Expand All @@ -465,16 +465,20 @@ fn expand_preparsed_asm(

let msg = "asm template must be a string literal";
let template_sp = template_expr.span;
let (template_str, template_style, template_span) =
match expr_to_spanned_string(ecx, template_expr, msg) {
let (template_str, template_style, template_span) = {
let ExpandResult::Ready(mac) = expr_to_spanned_string(ecx, template_expr, msg) else {
return ExpandResult::Retry(());
};
match mac {
Ok(template_part) => template_part,
Err(err) => {
return Err(match err {
return ExpandResult::Ready(Err(match err {
Ok((err, _)) => err.emit(),
Err(guar) => guar,
});
}));
}
};
}
};

let str_style = match template_style {
ast::StrStyle::Cooked => None,
Expand Down Expand Up @@ -562,7 +566,7 @@ fn expand_preparsed_asm(
e.span_label(err_sp, label);
}
let guar = e.emit();
return Err(guar);
return ExpandResult::Ready(Err(guar));
}

curarg = parser.curarg;
Expand Down Expand Up @@ -729,24 +733,27 @@ fn expand_preparsed_asm(
}
}

Ok(ast::InlineAsm {
ExpandResult::Ready(Ok(ast::InlineAsm {
template,
template_strs: template_strs.into_boxed_slice(),
operands: args.operands,
clobber_abis: args.clobber_abis,
options: args.options,
line_spans,
})
}))
}

pub(super) fn expand_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> Box<dyn base::MacResult + 'cx> {
match parse_args(ecx, sp, tts, false) {
) -> MacroExpanderResult<'cx> {
ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
Ok(args) => {
let expr = match expand_preparsed_asm(ecx, args) {
let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
return ExpandResult::Retry(());
};
let expr = match mac {
Ok(inline_asm) => P(ast::Expr {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
Expand All @@ -762,34 +769,39 @@ pub(super) fn expand_asm<'cx>(
let guar = err.emit();
DummyResult::any(sp, guar)
}
}
})
}

pub(super) fn expand_global_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> Box<dyn base::MacResult + 'cx> {
match parse_args(ecx, sp, tts, true) {
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,
) -> MacroExpanderResult<'cx> {
ExpandResult::Ready(match parse_args(ecx, sp, tts, true) {
Ok(args) => {
let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
return ExpandResult::Retry(());
};
match mac {
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,
},
span: sp,
tokens: None,
},
span: sp,
tokens: None,
})]),
Err(guar) => DummyResult::any(sp, guar),
},
})]),
Err(guar) => DummyResult::any(sp, guar),
}
}
Err(err) => {
let guar = err.emit();
DummyResult::any(sp, guar)
}
}
})
}
8 changes: 4 additions & 4 deletions compiler/rustc_builtin_macros/src/assert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment, UnOp};
use rustc_ast_pretty::pprust;
use rustc_errors::PResult;
use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_parse::parser::Parser;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
Expand All @@ -19,12 +19,12 @@ pub fn expand_assert<'cx>(
cx: &'cx mut ExtCtxt<'_>,
span: Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'cx> {
) -> MacroExpanderResult<'cx> {
let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) {
Ok(assert) => assert,
Err(err) => {
let guar = err.emit();
return DummyResult::any(span, guar);
return ExpandResult::Ready(DummyResult::any(span, guar));
}
};

Expand Down Expand Up @@ -92,7 +92,7 @@ pub fn expand_assert<'cx>(
expr_if_not(cx, call_site_span, cond_expr, then, None)
};

MacEager::expr(expr)
ExpandResult::Ready(MacEager::expr(expr))
}

struct Assert {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_builtin_macros/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_attr as attr;
use rustc_errors::PResult;
use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::Span;

pub fn expand_cfg(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'static> {
) -> MacroExpanderResult<'static> {
let sp = cx.with_def_site_ctxt(sp);

match parse_cfg(cx, sp, tts) {
ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
Ok(cfg) => {
let matches_cfg = attr::cfg_matches(
&cfg,
Expand All @@ -32,7 +32,7 @@ pub fn expand_cfg(
let guar = err.emit();
DummyResult::any(sp, guar)
}
}
})
}

fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_builtin_macros/src/cfg_accessible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::errors;
use rustc_ast as ast;
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate;
use rustc_hir::def::Namespace::*;
use rustc_parse::validate_attr;
use rustc_span::symbol::sym;
use rustc_span::Span;
Expand Down Expand Up @@ -57,7 +58,11 @@ impl MultiItemModifier for Expander {
return ExpandResult::Ready(Vec::new());
};

match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
match ecx.resolver.path_accessible(
ecx.current_expansion.id,
path,
&[TypeNS, ValueNS, MacroNS],
) {
Ok(true) => ExpandResult::Ready(vec![item]),
Ok(false) => ExpandResult::Ready(Vec::new()),
Err(Indeterminate) if ecx.force_mode => {
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_builtin_macros/src/compile_error.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
// The compiler code necessary to support the compile_error! extension.

use rustc_ast::tokenstream::TokenStream;
use rustc_expand::base::{get_single_str_from_tts, DummyResult, ExtCtxt, MacResult};
use rustc_expand::base::get_single_str_from_tts;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
use rustc_span::Span;

pub fn expand_compile_error<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'cx> {
let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
) -> MacroExpanderResult<'cx> {
let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "compile_error!") else {
return ExpandResult::Retry(());
};
let var = match mac {
Ok(var) => var,
Err(guar) => return DummyResult::any(sp, guar),
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
};

#[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")]
#[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
let guar = cx.dcx().span_err(sp, var.to_string());

DummyResult::any(sp, guar)
ExpandResult::Ready(DummyResult::any(sp, guar))
}
25 changes: 15 additions & 10 deletions compiler/rustc_builtin_macros/src/concat.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{ExprKind, LitKind, UnOp};
use rustc_expand::base::{get_exprs_from_tts, DummyResult, ExtCtxt, MacEager, MacResult};
use rustc_expand::base::get_exprs_from_tts;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_session::errors::report_lit_error;
use rustc_span::symbol::Symbol;

Expand All @@ -10,10 +11,13 @@ pub fn expand_concat(
cx: &mut ExtCtxt<'_>,
sp: rustc_span::Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'static> {
let es = match get_exprs_from_tts(cx, tts) {
) -> MacroExpanderResult<'static> {
let ExpandResult::Ready(mac) = get_exprs_from_tts(cx, tts) else {
return ExpandResult::Retry(());
};
let es = match mac {
Ok(es) => es,
Err(guar) => return DummyResult::any(sp, guar),
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
};
let mut accumulator = String::new();
let mut missing_literal = vec![];
Expand Down Expand Up @@ -70,12 +74,13 @@ pub fn expand_concat(
}
}

if !missing_literal.is_empty() {
ExpandResult::Ready(if !missing_literal.is_empty() {
let guar = cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal });
return DummyResult::any(sp, guar);
DummyResult::any(sp, guar)
} else if let Some(guar) = guar {
return DummyResult::any(sp, guar);
}
let sp = cx.with_def_site_ctxt(sp);
MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
DummyResult::any(sp, guar)
} else {
let sp = cx.with_def_site_ctxt(sp);
MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
})
}
25 changes: 15 additions & 10 deletions compiler/rustc_builtin_macros/src/concat_bytes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_ast::{ptr::P, token, tokenstream::TokenStream, ExprKind, LitIntType, LitKind, UintTy};
use rustc_expand::base::{get_exprs_from_tts, DummyResult, ExtCtxt, MacEager, MacResult};
use rustc_expand::base::get_exprs_from_tts;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_session::errors::report_lit_error;
use rustc_span::{ErrorGuaranteed, Span};

Expand Down Expand Up @@ -111,10 +112,13 @@ pub fn expand_concat_bytes(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'static> {
let es = match get_exprs_from_tts(cx, tts) {
) -> MacroExpanderResult<'static> {
let ExpandResult::Ready(mac) = get_exprs_from_tts(cx, tts) else {
return ExpandResult::Retry(());
};
let es = match mac {
Ok(es) => es,
Err(guar) => return DummyResult::any(sp, guar),
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
};
let mut accumulator = Vec::new();
let mut missing_literals = vec![];
Expand Down Expand Up @@ -170,12 +174,13 @@ pub fn expand_concat_bytes(
}
}
}
if !missing_literals.is_empty() {
ExpandResult::Ready(if !missing_literals.is_empty() {
let guar = cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals });
return MacEager::expr(DummyResult::raw_expr(sp, Some(guar)));
MacEager::expr(DummyResult::raw_expr(sp, Some(guar)))
} else if let Some(guar) = guar {
return MacEager::expr(DummyResult::raw_expr(sp, Some(guar)));
}
let sp = cx.with_def_site_ctxt(sp);
MacEager::expr(cx.expr_byte_str(sp, accumulator))
MacEager::expr(DummyResult::raw_expr(sp, Some(guar)))
} else {
let sp = cx.with_def_site_ctxt(sp);
MacEager::expr(cx.expr_byte_str(sp, accumulator))
})
}
Loading

0 comments on commit 988c172

Please sign in to comment.