aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/ty/tests.rs19
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs70
-rw-r--r--crates/ra_hir_expand/src/db.rs2
3 files changed, 84 insertions, 7 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index e56b9356e..896bf2924 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -4810,3 +4810,22 @@ fn no_such_field_diagnostics() {
4810 "### 4810 "###
4811 ); 4811 );
4812} 4812}
4813
4814#[test]
4815fn infer_builtin_macros_line() {
4816 assert_snapshot!(
4817 infer(r#"
4818#[rustc_builtin_macro]
4819macro_rules! line {() => {}}
4820
4821fn main() {
4822 let x = line!();
4823}
4824"#),
4825 @r###"
4826 ![0; 1) '6': i32
4827 [64; 88) '{ ...!(); }': ()
4828 [74; 75) 'x': i32
4829 "###
4830 );
4831}
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index dca2f17ef..acb62da27 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -1,14 +1,28 @@
1//! Builtin macro 1//! Builtin macro
2use crate::{ast, name, AstId, BuiltinMacro, CrateId, MacroDefId}; 2use crate::db::AstDatabase;
3use crate::{
4 ast::{self, AstNode},
5 name, AstId, BuiltinMacro, CrateId, HirFileId, MacroCallId, MacroDefId, MacroFileKind,
6 TextUnit,
7};
8
9use crate::quote;
3 10
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum BuiltinExpander { 12pub enum BuiltinExpander {
6 Line 13 Line,
7} 14}
8 15
9impl BuiltinExpander { 16impl BuiltinExpander {
10 pub fn expand(&self, _tt: &tt::Subtree) -> Result<tt::Subtree, mbe::ExpandError> { 17 pub fn expand(
11 Err(mbe::ExpandError::UnexpectedToken) 18 &self,
19 db: &dyn AstDatabase,
20 id: MacroCallId,
21 tt: &tt::Subtree,
22 ) -> Result<tt::Subtree, mbe::ExpandError> {
23 match self {
24 BuiltinExpander::Line => line_expand(db, id, tt),
25 }
12 } 26 }
13} 27}
14 28
@@ -18,9 +32,53 @@ pub fn find_builtin_macro(
18 ast_id: AstId<ast::MacroCall>, 32 ast_id: AstId<ast::MacroCall>,
19) -> Option<MacroDefId> { 33) -> Option<MacroDefId> {
20 // FIXME: Better registering method 34 // FIXME: Better registering method
21 if ident == &name::LINE { 35 if ident == &name::LINE_MACRO {
22 Some(MacroDefId::BuiltinMacro(BuiltinMacro { expander: BuiltinExpander::Line, krate, ast_id })) 36 Some(MacroDefId::BuiltinMacro(BuiltinMacro {
37 expander: BuiltinExpander::Line,
38 krate,
39 ast_id,
40 }))
23 } else { 41 } else {
24 None 42 None
25 } 43 }
26} 44}
45
46fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
47 // FIXME: Use expansion info
48 let file_id = file.original_file(db);
49 let text = db.file_text(file_id);
50 let mut line_num = 1;
51
52 // Count line end
53 for (i, c) in text.chars().enumerate() {
54 if i == pos.to_usize() {
55 break;
56 }
57 if c == '\n' {
58 line_num += 1;
59 }
60 }
61
62 line_num
63}
64
65fn line_expand(
66 db: &dyn AstDatabase,
67 id: MacroCallId,
68 _tt: &tt::Subtree,
69) -> Result<tt::Subtree, mbe::ExpandError> {
70 let loc = db.lookup_intern_macro(id);
71 let macro_call = loc.ast_id.to_node(db);
72
73 let arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
74 let arg_start = arg.syntax().text_range().start();
75
76 let file = id.as_file(MacroFileKind::Expr);
77 let line_num = to_line_number(db, file, arg_start);
78
79 let expanded = quote! {
80 #line_num
81 };
82
83 Ok(expanded)
84}
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index 343c9e6bf..009ff5312 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -28,7 +28,7 @@ impl TokenExpander {
28 ) -> Result<tt::Subtree, mbe::ExpandError> { 28 ) -> Result<tt::Subtree, mbe::ExpandError> {
29 match self { 29 match self {
30 TokenExpander::MacroRules(it) => it.expand(tt), 30 TokenExpander::MacroRules(it) => it.expand(tt),
31 TokenExpander::Builtin(it) => it.expand(tt), 31 TokenExpander::Builtin(it) => it.expand(db, id, tt),
32 } 32 }
33 } 33 }
34 34