diff options
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 44 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/name.rs | 1 |
3 files changed, 63 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index b4bdd81f6..17a50cf74 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -4876,3 +4876,22 @@ fn main() { | |||
4876 | "### | 4876 | "### |
4877 | ); | 4877 | ); |
4878 | } | 4878 | } |
4879 | |||
4880 | #[test] | ||
4881 | fn infer_builtin_macros_column() { | ||
4882 | assert_snapshot!( | ||
4883 | infer(r#" | ||
4884 | #[rustc_builtin_macro] | ||
4885 | macro_rules! column {() => {}} | ||
4886 | |||
4887 | fn main() { | ||
4888 | let x = column!(); | ||
4889 | } | ||
4890 | "#), | ||
4891 | @r###" | ||
4892 | ![0; 2) '13': i32 | ||
4893 | [66; 92) '{ ...!(); }': () | ||
4894 | [76; 77) 'x': i32 | ||
4895 | "### | ||
4896 | ); | ||
4897 | } | ||
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index d7057e005..4da56529d 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -10,6 +10,7 @@ use crate::quote; | |||
10 | 10 | ||
11 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 11 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
12 | pub enum BuiltinExpander { | 12 | pub enum BuiltinExpander { |
13 | Column, | ||
13 | File, | 14 | File, |
14 | Line, | 15 | Line, |
15 | Stringify, | 16 | Stringify, |
@@ -23,6 +24,7 @@ impl BuiltinExpander { | |||
23 | tt: &tt::Subtree, | 24 | tt: &tt::Subtree, |
24 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 25 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
25 | match self { | 26 | match self { |
27 | BuiltinExpander::Column => column_expand(db, id, tt), | ||
26 | BuiltinExpander::File => file_expand(db, id, tt), | 28 | BuiltinExpander::File => file_expand(db, id, tt), |
27 | BuiltinExpander::Line => line_expand(db, id, tt), | 29 | BuiltinExpander::Line => line_expand(db, id, tt), |
28 | BuiltinExpander::Stringify => stringify_expand(db, id, tt), | 30 | BuiltinExpander::Stringify => stringify_expand(db, id, tt), |
@@ -36,7 +38,9 @@ pub fn find_builtin_macro( | |||
36 | ast_id: AstId<ast::MacroCall>, | 38 | ast_id: AstId<ast::MacroCall>, |
37 | ) -> Option<MacroDefId> { | 39 | ) -> Option<MacroDefId> { |
38 | // FIXME: Better registering method | 40 | // FIXME: Better registering method |
39 | if ident == &name::FILE_MACRO { | 41 | if ident == &name::COLUMN_MACRO { |
42 | Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Column) }) | ||
43 | } else if ident == &name::FILE_MACRO { | ||
40 | Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::File) }) | 44 | Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::File) }) |
41 | } else if ident == &name::LINE_MACRO { | 45 | } else if ident == &name::LINE_MACRO { |
42 | Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Line) }) | 46 | Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Line) }) |
@@ -110,6 +114,43 @@ fn stringify_expand( | |||
110 | Ok(expanded) | 114 | Ok(expanded) |
111 | } | 115 | } |
112 | 116 | ||
117 | fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { | ||
118 | // FIXME: Use expansion info | ||
119 | let file_id = file.original_file(db); | ||
120 | let text = db.file_text(file_id); | ||
121 | let mut col_num = 1; | ||
122 | |||
123 | for c in text[..pos.to_usize()].chars().rev() { | ||
124 | if c == '\n' { | ||
125 | break; | ||
126 | } | ||
127 | col_num = col_num + 1; | ||
128 | } | ||
129 | |||
130 | col_num | ||
131 | } | ||
132 | |||
133 | fn column_expand( | ||
134 | db: &dyn AstDatabase, | ||
135 | id: MacroCallId, | ||
136 | _tt: &tt::Subtree, | ||
137 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
138 | let loc = db.lookup_intern_macro(id); | ||
139 | let macro_call = loc.ast_id.to_node(db); | ||
140 | |||
141 | let _arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; | ||
142 | let col_start = macro_call.syntax().text_range().start(); | ||
143 | |||
144 | let file = id.as_file(MacroFileKind::Expr); | ||
145 | let col_num = to_col_number(db, file, col_start); | ||
146 | |||
147 | let expanded = quote! { | ||
148 | #col_num | ||
149 | }; | ||
150 | |||
151 | Ok(expanded) | ||
152 | } | ||
153 | |||
113 | fn file_expand( | 154 | fn file_expand( |
114 | db: &dyn AstDatabase, | 155 | db: &dyn AstDatabase, |
115 | id: MacroCallId, | 156 | id: MacroCallId, |
@@ -117,6 +158,7 @@ fn file_expand( | |||
117 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 158 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
118 | let loc = db.lookup_intern_macro(id); | 159 | let loc = db.lookup_intern_macro(id); |
119 | let macro_call = loc.ast_id.to_node(db); | 160 | let macro_call = loc.ast_id.to_node(db); |
161 | |||
120 | let _ = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; | 162 | let _ = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; |
121 | 163 | ||
122 | // FIXME: RA purposefully lacks knowledge of absolute file names | 164 | // FIXME: RA purposefully lacks knowledge of absolute file names |
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs index 05fe6afd9..eaea7a6a8 100644 --- a/crates/ra_hir_expand/src/name.rs +++ b/crates/ra_hir_expand/src/name.rs | |||
@@ -143,5 +143,6 @@ pub const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box"); | |||
143 | 143 | ||
144 | // Builtin Macros | 144 | // Builtin Macros |
145 | pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file"); | 145 | pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file"); |
146 | pub const COLUMN_MACRO: Name = Name::new_inline_ascii(6, b"column"); | ||
146 | pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line"); | 147 | pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line"); |
147 | pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify"); | 148 | pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify"); |