aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-11-22 16:37:10 +0000
committerGitHub <[email protected]>2019-11-22 16:37:10 +0000
commit4d49b5d174430feede9833c5e66c39ee41b5fa3e (patch)
tree3042ee2fb92cac71a841b920dfd3ac708db10924
parent506131e3e01a81546ab218e1764073061875ea2e (diff)
parent1ee5592be28a980d75cc6e3e2fd9796a07772480 (diff)
Merge #2355
2355: Expand column!() r=kjeremy a=kjeremy Co-authored-by: Jeremy Kolb <[email protected]>
-rw-r--r--crates/ra_hir/src/ty/tests.rs19
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs44
-rw-r--r--crates/ra_hir_expand/src/name.rs1
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]
4881fn infer_builtin_macros_column() {
4882 assert_snapshot!(
4883 infer(r#"
4884#[rustc_builtin_macro]
4885macro_rules! column {() => {}}
4886
4887fn 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)]
12pub enum BuiltinExpander { 12pub 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
117fn 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
133fn 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
113fn file_expand( 154fn 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
145pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file"); 145pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file");
146pub const COLUMN_MACRO: Name = Name::new_inline_ascii(6, b"column");
146pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line"); 147pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line");
147pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify"); 148pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify");