delay expand macro bang when there has indeterminate path
This commit is contained in:
parent
5a6c1aa2bc
commit
8fcdf54a6b
22 changed files with 509 additions and 263 deletions
|
@ -3,10 +3,9 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_expand::base::{
|
||||
check_zero_tts, get_single_str_from_tts, parse_expr, resolve_path, DummyResult, ExtCtxt,
|
||||
MacEager, MacResult,
|
||||
};
|
||||
use rustc_expand::base::{check_zero_tts, get_single_str_from_tts, parse_expr, resolve_path};
|
||||
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt};
|
||||
use rustc_expand::base::{MacEager, MacResult, MacroExpanderResult};
|
||||
use rustc_expand::module::DirOwnership;
|
||||
use rustc_parse::new_parser_from_file;
|
||||
use rustc_parse::parser::{ForceCollect, Parser};
|
||||
|
@ -26,14 +25,14 @@ pub fn expand_line(
|
|||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
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());
|
||||
|
||||
MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
|
||||
ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.line as u32)))
|
||||
}
|
||||
|
||||
/* column!(): expands to the current column number */
|
||||
|
@ -41,14 +40,14 @@ pub fn expand_column(
|
|||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
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());
|
||||
|
||||
MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
|
||||
ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1)))
|
||||
}
|
||||
|
||||
/// file!(): expands to the current filename */
|
||||
|
@ -58,7 +57,7 @@ pub fn expand_file(
|
|||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
check_zero_tts(cx, sp, tts, "file!");
|
||||
|
||||
|
@ -66,35 +65,35 @@ pub fn expand_file(
|
|||
let loc = cx.source_map().lookup_char_pos(topmost.lo());
|
||||
|
||||
use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
|
||||
MacEager::expr(cx.expr_str(
|
||||
ExpandResult::Ready(MacEager::expr(cx.expr_str(
|
||||
topmost,
|
||||
Symbol::intern(
|
||||
&loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
|
||||
),
|
||||
))
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn expand_stringify(
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
let s = pprust::tts_to_string(&tts);
|
||||
MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
|
||||
ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s))))
|
||||
}
|
||||
|
||||
pub fn expand_mod(
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
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("::");
|
||||
|
||||
MacEager::expr(cx.expr_str(sp, Symbol::intern(&string)))
|
||||
ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&string))))
|
||||
}
|
||||
|
||||
/// include! : parse the given file as an expr
|
||||
|
@ -104,18 +103,21 @@ pub fn expand_include<'cx>(
|
|||
cx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'cx> {
|
||||
) -> MacroExpanderResult<'cx> {
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
|
||||
let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include!") else {
|
||||
return ExpandResult::Retry(());
|
||||
};
|
||||
let file = match mac {
|
||||
Ok(file) => file,
|
||||
Err(guar) => return DummyResult::any(sp, guar),
|
||||
Err(guar) => return ExpandResult::Ready(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) => {
|
||||
let guar = err.emit();
|
||||
return DummyResult::any(sp, guar);
|
||||
return ExpandResult::Ready(DummyResult::any(sp, guar));
|
||||
}
|
||||
};
|
||||
let p = new_parser_from_file(cx.psess(), &file, Some(sp));
|
||||
|
@ -128,12 +130,12 @@ pub fn expand_include<'cx>(
|
|||
cx.current_expansion.module = Rc::new(cx.current_expansion.module.with_dir_path(dir_path));
|
||||
cx.current_expansion.dir_ownership = DirOwnership::Owned { relative: None };
|
||||
|
||||
struct ExpandResult<'a> {
|
||||
struct ExpandInclude<'a> {
|
||||
p: Parser<'a>,
|
||||
node_id: ast::NodeId,
|
||||
}
|
||||
impl<'a> MacResult for ExpandResult<'a> {
|
||||
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
|
||||
impl<'a> MacResult for ExpandInclude<'a> {
|
||||
fn make_expr(mut self: Box<ExpandInclude<'a>>) -> Option<P<ast::Expr>> {
|
||||
let expr = parse_expr(&mut self.p).ok()?;
|
||||
if self.p.token != token::Eof {
|
||||
self.p.psess.buffer_lint(
|
||||
|
@ -146,7 +148,7 @@ pub fn expand_include<'cx>(
|
|||
Some(expr)
|
||||
}
|
||||
|
||||
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
||||
fn make_items(mut self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
||||
let mut ret = SmallVec::new();
|
||||
loop {
|
||||
match self.p.parse_item(ForceCollect::No) {
|
||||
|
@ -170,7 +172,7 @@ pub fn expand_include<'cx>(
|
|||
}
|
||||
}
|
||||
|
||||
Box::new(ExpandResult { p, node_id: cx.current_expansion.lint_node_id })
|
||||
ExpandResult::Ready(Box::new(ExpandInclude { p, node_id: cx.current_expansion.lint_node_id }))
|
||||
}
|
||||
|
||||
/// `include_str!`: read the given file, insert it as a literal string expr
|
||||
|
@ -178,20 +180,23 @@ pub fn expand_include_str(
|
|||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
|
||||
let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
|
||||
return ExpandResult::Retry(());
|
||||
};
|
||||
let file = match mac {
|
||||
Ok(file) => file,
|
||||
Err(guar) => return DummyResult::any(sp, guar),
|
||||
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
|
||||
};
|
||||
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
let guar = err.emit();
|
||||
return DummyResult::any(sp, guar);
|
||||
return ExpandResult::Ready(DummyResult::any(sp, guar));
|
||||
}
|
||||
};
|
||||
match cx.source_map().load_binary_file(&file) {
|
||||
ExpandResult::Ready(match cx.source_map().load_binary_file(&file) {
|
||||
Ok(bytes) => match std::str::from_utf8(&bytes) {
|
||||
Ok(src) => {
|
||||
let interned_src = Symbol::intern(src);
|
||||
|
@ -206,27 +211,30 @@ pub fn expand_include_str(
|
|||
let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
|
||||
DummyResult::any(sp, guar)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expand_include_bytes(
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'static> {
|
||||
) -> MacroExpanderResult<'static> {
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
|
||||
let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
|
||||
return ExpandResult::Retry(());
|
||||
};
|
||||
let file = match mac {
|
||||
Ok(file) => file,
|
||||
Err(guar) => return DummyResult::any(sp, guar),
|
||||
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
|
||||
};
|
||||
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
let guar = err.emit();
|
||||
return DummyResult::any(sp, guar);
|
||||
return ExpandResult::Ready(DummyResult::any(sp, guar));
|
||||
}
|
||||
};
|
||||
match cx.source_map().load_binary_file(&file) {
|
||||
ExpandResult::Ready(match cx.source_map().load_binary_file(&file) {
|
||||
Ok(bytes) => {
|
||||
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes));
|
||||
MacEager::expr(expr)
|
||||
|
@ -235,5 +243,5 @@ pub fn expand_include_bytes(
|
|||
let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
|
||||
DummyResult::any(sp, guar)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue