Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions compiler/rustc_builtin_macros/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,34 @@ use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_attr as attr;
use rustc_errors::PResult;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_expand::base::ExtCtxt;
use rustc_span::symbol::kw;
use rustc_span::Span;

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

ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
let kind = match parse_cfg(cx, sp, tts) {
Ok(cfg) => {
let matches_cfg = attr::cfg_matches(
&cfg,
&cx.sess,
cx.current_expansion.lint_node_id,
Some(cx.ecfg.features),
);
MacEager::expr(cx.expr_bool(sp, matches_cfg))
let sym = if matches_cfg { kw::True } else { kw::False };
token::TokenKind::Ident(sym, token::IdentIsRaw::No)
}
Err(err) => {
let guar = err.emit();
DummyResult::any(sp, guar)
token::TokenKind::lit(
token::LitKind::Err(guar), // njn: ?
kw::Empty,
None,
)
}
})
};
TokenStream::token_alone(kind, sp)
}

fn parse_cfg<'a>(cx: &ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
Expand Down
26 changes: 17 additions & 9 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,38 +59,46 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
macro register_bang($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::Bang(Box::new($f)));)*
}
macro register_legacy_bang($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
}
macro register_attr($($name:ident: $f:expr,)*) {
macro register_legacy_attr($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
}
macro register_derive($($name:ident: $f:expr,)*) {
macro register_legacy_derive($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
}

register_bang! {
// tidy-alphabetical-start
asm: asm::expand_asm,
assert: assert::expand_assert,
cfg: cfg::expand_cfg,
column: source_util::expand_column,
file: source_util::expand_file,
line: source_util::expand_line,
module_path: source_util::expand_module_path,
// tidy-alphabetical-end
}

register_legacy_bang! {
// tidy-alphabetical-start
asm: asm::expand_asm,
assert: assert::expand_assert,
compile_error: compile_error::expand_compile_error,
concat: concat::expand_concat,
concat_bytes: concat_bytes::expand_concat_bytes,
concat_idents: concat_idents::expand_concat_idents,
const_format_args: format::expand_format_args,
core_panic: edition_panic::expand_panic,
env: env::expand_env,
file: source_util::expand_file,
format_args: format::expand_format_args,
format_args_nl: format::expand_format_args_nl,
global_asm: asm::expand_global_asm,
include: source_util::expand_include,
include_bytes: source_util::expand_include_bytes,
include_str: source_util::expand_include_str,
line: source_util::expand_line,
log_syntax: log_syntax::expand_log_syntax,
module_path: source_util::expand_mod,
option_env: env::expand_option_env,
pattern_type: pattern_type::expand,
std_panic: edition_panic::expand_panic,
Expand All @@ -100,7 +108,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
// tidy-alphabetical-end
}

register_attr! {
register_legacy_attr! {
alloc_error_handler: alloc_error_handler::expand,
bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander,
Expand All @@ -112,7 +120,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
test_case: test::expand_test_case,
}

register_derive! {
register_legacy_derive! {
Clone: clone::expand_deriving_clone,
Copy: bounds::expand_deriving_copy,
ConstParamTy: bounds::expand_deriving_const_param_ty,
Expand Down
55 changes: 26 additions & 29 deletions compiler/rustc_builtin_macros/src/source_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_parse::new_parser_from_file;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
use rustc_span::source_map::SourceMap;
use rustc_span::sym;
use rustc_span::symbol::Symbol;
use rustc_span::{Pos, Span};
use smallvec::SmallVec;
Expand All @@ -26,56 +27,54 @@ use std::rc::Rc;
// a given file into the current one.

/// line!(): expands to the current line number
pub(crate) fn expand_line(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'static> {
pub(crate) fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream) -> TokenStream {
let sp = cx.with_def_site_ctxt(sp);
check_zero_tts(cx, sp, tts, "line!");

let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.source_map().lookup_char_pos(topmost.lo());

ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.line as u32)))
let kind = token::TokenKind::lit(
token::LitKind::Integer,
sym::integer(loc.line as u32),
Some(sym::u32),
);
TokenStream::token_alone(kind, topmost)
}

/* column!(): expands to the current column number */
pub(crate) fn expand_column(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'static> {
pub(crate) fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream) -> TokenStream {
let sp = cx.with_def_site_ctxt(sp);
check_zero_tts(cx, sp, tts, "column!");

let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.source_map().lookup_char_pos(topmost.lo());

ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1)))
let kind = token::TokenKind::lit(
token::LitKind::Integer,
sym::integer(loc.col.to_usize() as u32 + 1),
Some(sym::u32),
);
TokenStream::token_alone(kind, topmost)
}

/// file!(): expands to the current filename */
/// The source_file (`loc.file`) contains a bunch more information we could spit
/// out if we wanted.
pub(crate) fn expand_file(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'static> {
pub(crate) fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream) -> TokenStream {
let sp = cx.with_def_site_ctxt(sp);
check_zero_tts(cx, sp, tts, "file!");

let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.source_map().lookup_char_pos(topmost.lo());

use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
ExpandResult::Ready(MacEager::expr(cx.expr_str(
topmost,
Symbol::intern(
&loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
),
)))

let symbol = Symbol::intern(
&loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
);
let kind = token::TokenKind::lit(token::LitKind::Str, symbol, None);
TokenStream::token_alone(kind, topmost)
}

pub(crate) fn expand_stringify(
Expand All @@ -88,17 +87,15 @@ pub(crate) fn expand_stringify(
ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s))))
}

pub(crate) fn expand_mod(
cx: &mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'static> {
pub(crate) fn expand_module_path(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream) -> TokenStream {
let sp = cx.with_def_site_ctxt(sp);
check_zero_tts(cx, sp, tts, "module_path!");
let mod_path = &cx.current_expansion.module.mod_path;
let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");

ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&string))))
let symbol = Symbol::intern(&string);
let kind = token::TokenKind::lit(token::LitKind::Str, symbol, None);
TokenStream::token_alone(kind, sp)
}

/// include! : parse the given file as an expr
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,16 +290,15 @@ pub trait BangProcMacro {

impl<F> BangProcMacro for F
where
F: Fn(TokenStream) -> TokenStream,
F: Fn(&mut ExtCtxt<'_>, Span, TokenStream) -> TokenStream,
{
fn expand<'cx>(
&self,
_ecx: &'cx mut ExtCtxt<'_>,
_span: Span,
ecx: &'cx mut ExtCtxt<'_>,
span: Span,
ts: TokenStream,
) -> Result<TokenStream, ErrorGuaranteed> {
// FIXME setup implicit context in TLS before calling self.
Ok(self(ts))
Ok(self(ecx, span, ts))
Comment on lines -293 to +301
Copy link
Member

@SparrowLii SparrowLii May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can improve the return types here to handle ExpandResult::Retry(()) . e.g.

pub enum BangRetry {
    Yes,
    No,
}

impl<F> BangProcMacro for F
where
    F: Fn(&mut ExtCtxt<'_>, Span, TokenStream) -> Result<TokenStream, BangRetry>,
{
    fn expand<'cx>(
        &self,
        ecx: &'cx mut ExtCtxt<'_>,
        span: Span,
        ts: TokenStream,
    ) -> Result<TokenStream, (BangRetry, ErrorGuaranteed)> {
        self(ecx, span, ts).map_err(|retry| (retry, ErrorGuaranteed(())))
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good suggestion. But I'll wait for feedback from @petrochenkov about whether converting LegacyBang to Bang is a good idea in general before putting more effort in.

@petrochenkov, what do you think?

}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/macros/macro-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ macro_rules! foo {
fn main() {
foo!(0); // Check that we report errors at macro definition, not expansion.

let _: cfg!(FALSE) = (); //~ ERROR non-type macro in type position
let _: cfg!(FALSE) = (); //~ ERROR expected type, found keyword `false`
}
7 changes: 6 additions & 1 deletion tests/ui/macros/macro-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ error: macro rhs must be delimited
LL | ($a:expr) => a;
| ^

error: non-type macro in type position: cfg
error: expected type, found keyword `false`
--> $DIR/macro-error.rs:8:12
|
LL | let _: cfg!(FALSE) = ();
| ^^^^^^^^^^^
| |
| expected type
| this macro call doesn't expand to a type
|
= note: this error originates in the macro `cfg` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors