Add line macro and tests

This commit is contained in:
Edwin Cheng 2019-11-11 14:15:09 +08:00
parent 1637a8a590
commit c4aa8b63bc
3 changed files with 84 additions and 7 deletions

View File

@ -4810,3 +4810,22 @@ fn no_such_field_diagnostics() {
"### "###
); );
} }
#[test]
fn infer_builtin_macros_line() {
assert_snapshot!(
infer(r#"
#[rustc_builtin_macro]
macro_rules! line {() => {}}
fn main() {
let x = line!();
}
"#),
@r###"
![0; 1) '6': i32
[64; 88) '{ ...!(); }': ()
[74; 75) 'x': i32
"###
);
}

View File

@ -1,14 +1,28 @@
//! Builtin macro //! Builtin macro
use crate::{ast, name, AstId, BuiltinMacro, CrateId, MacroDefId}; use crate::db::AstDatabase;
use crate::{
ast::{self, AstNode},
name, AstId, BuiltinMacro, CrateId, HirFileId, MacroCallId, MacroDefId, MacroFileKind,
TextUnit,
};
use crate::quote;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinExpander { pub enum BuiltinExpander {
Line Line,
} }
impl BuiltinExpander { impl BuiltinExpander {
pub fn expand(&self, _tt: &tt::Subtree) -> Result<tt::Subtree, mbe::ExpandError> { pub fn expand(
Err(mbe::ExpandError::UnexpectedToken) &self,
db: &dyn AstDatabase,
id: MacroCallId,
tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> {
match self {
BuiltinExpander::Line => line_expand(db, id, tt),
}
} }
} }
@ -18,9 +32,53 @@ pub fn find_builtin_macro(
ast_id: AstId<ast::MacroCall>, ast_id: AstId<ast::MacroCall>,
) -> Option<MacroDefId> { ) -> Option<MacroDefId> {
// FIXME: Better registering method // FIXME: Better registering method
if ident == &name::LINE { if ident == &name::LINE_MACRO {
Some(MacroDefId::BuiltinMacro(BuiltinMacro { expander: BuiltinExpander::Line, krate, ast_id })) Some(MacroDefId::BuiltinMacro(BuiltinMacro {
expander: BuiltinExpander::Line,
krate,
ast_id,
}))
} else { } else {
None None
} }
} }
fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
// FIXME: Use expansion info
let file_id = file.original_file(db);
let text = db.file_text(file_id);
let mut line_num = 1;
// Count line end
for (i, c) in text.chars().enumerate() {
if i == pos.to_usize() {
break;
}
if c == '\n' {
line_num += 1;
}
}
line_num
}
fn line_expand(
db: &dyn AstDatabase,
id: MacroCallId,
_tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> {
let loc = db.lookup_intern_macro(id);
let macro_call = loc.ast_id.to_node(db);
let arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
let arg_start = arg.syntax().text_range().start();
let file = id.as_file(MacroFileKind::Expr);
let line_num = to_line_number(db, file, arg_start);
let expanded = quote! {
#line_num
};
Ok(expanded)
}

View File

@ -28,7 +28,7 @@ impl TokenExpander {
) -> Result<tt::Subtree, mbe::ExpandError> { ) -> Result<tt::Subtree, mbe::ExpandError> {
match self { match self {
TokenExpander::MacroRules(it) => it.expand(tt), TokenExpander::MacroRules(it) => it.expand(tt),
TokenExpander::Builtin(it) => it.expand(tt), TokenExpander::Builtin(it) => it.expand(db, id, tt),
} }
} }