aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs138
-rw-r--r--crates/ra_hir_expand/src/name.rs2
-rw-r--r--crates/ra_hir_expand/src/quote.rs2
3 files changed, 99 insertions, 43 deletions
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index 857f8a444..2c119269c 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -26,6 +26,13 @@ macro_rules! register_builtin {
26 }; 26 };
27 expander(db, id, tt) 27 expander(db, id, tt)
28 } 28 }
29
30 fn by_name(ident: &name::Name) -> Option<BuiltinFnLikeExpander> {
31 match ident {
32 $( id if id == &name::name![$name] => Some(BuiltinFnLikeExpander::$kind), )*
33 _ => return None,
34 }
35 }
29 } 36 }
30 37
31 pub fn find_builtin_macro( 38 pub fn find_builtin_macro(
@@ -33,10 +40,7 @@ macro_rules! register_builtin {
33 krate: CrateId, 40 krate: CrateId,
34 ast_id: AstId<ast::MacroCall>, 41 ast_id: AstId<ast::MacroCall>,
35 ) -> Option<MacroDefId> { 42 ) -> Option<MacroDefId> {
36 let kind = match ident { 43 let kind = BuiltinFnLikeExpander::by_name(ident)?;
37 $( id if id == &name::name![$name] => BuiltinFnLikeExpander::$kind, )*
38 _ => return None,
39 };
40 44
41 Some(MacroDefId { krate: Some(krate), ast_id: Some(ast_id), kind: MacroDefKind::BuiltIn(kind) }) 45 Some(MacroDefId { krate: Some(krate), ast_id: Some(ast_id), kind: MacroDefKind::BuiltIn(kind) })
42 } 46 }
@@ -50,6 +54,8 @@ register_builtin! {
50 (line, Line) => line_expand, 54 (line, Line) => line_expand,
51 (stringify, Stringify) => stringify_expand, 55 (stringify, Stringify) => stringify_expand,
52 (format_args, FormatArgs) => format_args_expand, 56 (format_args, FormatArgs) => format_args_expand,
57 (env, Env) => env_expand,
58 (option_env, OptionEnv) => option_env_expand,
53 // format_args_nl only differs in that it adds a newline in the end, 59 // format_args_nl only differs in that it adds a newline in the end,
54 // so we use the same stub expansion for now 60 // so we use the same stub expansion for now
55 (format_args_nl, FormatArgsNl) => format_args_expand 61 (format_args_nl, FormatArgsNl) => format_args_expand
@@ -121,6 +127,28 @@ fn stringify_expand(
121 Ok(expanded) 127 Ok(expanded)
122} 128}
123 129
130fn env_expand(
131 _db: &dyn AstDatabase,
132 _id: MacroCallId,
133 _tt: &tt::Subtree,
134) -> Result<tt::Subtree, mbe::ExpandError> {
135 // dummy implementation for type-checking purposes
136 let expanded = quote! { "" };
137
138 Ok(expanded)
139}
140
141fn option_env_expand(
142 _db: &dyn AstDatabase,
143 _id: MacroCallId,
144 _tt: &tt::Subtree,
145) -> Result<tt::Subtree, mbe::ExpandError> {
146 // dummy implementation for type-checking purposes
147 let expanded = quote! { std::option::Option::None::<&str> };
148
149 Ok(expanded)
150}
151
124fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { 152fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
125 // FIXME: Use expansion info 153 // FIXME: Use expansion info
126 let file_id = file.original_file(db); 154 let file_id = file.original_file(db);
@@ -248,10 +276,11 @@ fn format_args_expand(
248#[cfg(test)] 276#[cfg(test)]
249mod tests { 277mod tests {
250 use super::*; 278 use super::*;
251 use crate::{test_db::TestDB, MacroCallKind, MacroCallLoc}; 279 use crate::{name::AsName, test_db::TestDB, MacroCallKind, MacroCallLoc};
252 use ra_db::{fixture::WithFixture, SourceDatabase}; 280 use ra_db::{fixture::WithFixture, SourceDatabase};
281 use ra_syntax::ast::NameOwner;
253 282
254 fn expand_builtin_macro(s: &str, expander: BuiltinFnLikeExpander) -> String { 283 fn expand_builtin_macro(s: &str) -> String {
255 let (db, file_id) = TestDB::with_single_file(&s); 284 let (db, file_id) = TestDB::with_single_file(&s);
256 let parsed = db.parse(file_id); 285 let parsed = db.parse(file_id);
257 let macro_calls: Vec<_> = 286 let macro_calls: Vec<_> =
@@ -259,6 +288,9 @@ mod tests {
259 288
260 let ast_id_map = db.ast_id_map(file_id.into()); 289 let ast_id_map = db.ast_id_map(file_id.into());
261 290
291 let expander =
292 BuiltinFnLikeExpander::by_name(&macro_calls[0].name().unwrap().as_name()).unwrap();
293
262 // the first one should be a macro_rules 294 // the first one should be a macro_rules
263 let def = MacroDefId { 295 let def = MacroDefId {
264 krate: Some(CrateId(0)), 296 krate: Some(CrateId(0)),
@@ -284,25 +316,23 @@ mod tests {
284 fn test_column_expand() { 316 fn test_column_expand() {
285 let expanded = expand_builtin_macro( 317 let expanded = expand_builtin_macro(
286 r#" 318 r#"
287 #[rustc_builtin_macro] 319 #[rustc_builtin_macro]
288 macro_rules! column {() => {}} 320 macro_rules! column {() => {}}
289 column!() 321 column!()
290"#, 322 "#,
291 BuiltinFnLikeExpander::Column,
292 ); 323 );
293 324
294 assert_eq!(expanded, "9"); 325 assert_eq!(expanded, "13");
295 } 326 }
296 327
297 #[test] 328 #[test]
298 fn test_line_expand() { 329 fn test_line_expand() {
299 let expanded = expand_builtin_macro( 330 let expanded = expand_builtin_macro(
300 r#" 331 r#"
301 #[rustc_builtin_macro] 332 #[rustc_builtin_macro]
302 macro_rules! line {() => {}} 333 macro_rules! line {() => {}}
303 line!() 334 line!()
304"#, 335 "#,
305 BuiltinFnLikeExpander::Line,
306 ); 336 );
307 337
308 assert_eq!(expanded, "4"); 338 assert_eq!(expanded, "4");
@@ -312,25 +342,49 @@ mod tests {
312 fn test_stringify_expand() { 342 fn test_stringify_expand() {
313 let expanded = expand_builtin_macro( 343 let expanded = expand_builtin_macro(
314 r#" 344 r#"
315 #[rustc_builtin_macro] 345 #[rustc_builtin_macro]
316 macro_rules! stringify {() => {}} 346 macro_rules! stringify {() => {}}
317 stringify!(a b c) 347 stringify!(a b c)
318"#, 348 "#,
319 BuiltinFnLikeExpander::Stringify,
320 ); 349 );
321 350
322 assert_eq!(expanded, "\"a b c\""); 351 assert_eq!(expanded, "\"a b c\"");
323 } 352 }
324 353
325 #[test] 354 #[test]
355 fn test_env_expand() {
356 let expanded = expand_builtin_macro(
357 r#"
358 #[rustc_builtin_macro]
359 macro_rules! env {() => {}}
360 env!("TEST_ENV_VAR")
361 "#,
362 );
363
364 assert_eq!(expanded, "\"\"");
365 }
366
367 #[test]
368 fn test_option_env_expand() {
369 let expanded = expand_builtin_macro(
370 r#"
371 #[rustc_builtin_macro]
372 macro_rules! option_env {() => {}}
373 option_env!("TEST_ENV_VAR")
374 "#,
375 );
376
377 assert_eq!(expanded, "std::option::Option::None:: <&str>");
378 }
379
380 #[test]
326 fn test_file_expand() { 381 fn test_file_expand() {
327 let expanded = expand_builtin_macro( 382 let expanded = expand_builtin_macro(
328 r#" 383 r#"
329 #[rustc_builtin_macro] 384 #[rustc_builtin_macro]
330 macro_rules! file {() => {}} 385 macro_rules! file {() => {}}
331 file!() 386 file!()
332"#, 387 "#,
333 BuiltinFnLikeExpander::File,
334 ); 388 );
335 389
336 assert_eq!(expanded, "\"\""); 390 assert_eq!(expanded, "\"\"");
@@ -340,14 +394,13 @@ mod tests {
340 fn test_compile_error_expand() { 394 fn test_compile_error_expand() {
341 let expanded = expand_builtin_macro( 395 let expanded = expand_builtin_macro(
342 r#" 396 r#"
343 #[rustc_builtin_macro] 397 #[rustc_builtin_macro]
344 macro_rules! compile_error { 398 macro_rules! compile_error {
345 ($msg:expr) => ({ /* compiler built-in */ }); 399 ($msg:expr) => ({ /* compiler built-in */ });
346 ($msg:expr,) => ({ /* compiler built-in */ }) 400 ($msg:expr,) => ({ /* compiler built-in */ })
347 } 401 }
348 compile_error!("error!"); 402 compile_error!("error!");
349"#, 403 "#,
350 BuiltinFnLikeExpander::CompileError,
351 ); 404 );
352 405
353 assert_eq!(expanded, r#"loop{"error!"}"#); 406 assert_eq!(expanded, r#"loop{"error!"}"#);
@@ -357,14 +410,13 @@ mod tests {
357 fn test_format_args_expand() { 410 fn test_format_args_expand() {
358 let expanded = expand_builtin_macro( 411 let expanded = expand_builtin_macro(
359 r#" 412 r#"
360 #[rustc_builtin_macro] 413 #[rustc_builtin_macro]
361 macro_rules! format_args { 414 macro_rules! format_args {
362 ($fmt:expr) => ({ /* compiler built-in */ }); 415 ($fmt:expr) => ({ /* compiler built-in */ });
363 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) 416 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
364 } 417 }
365 format_args!("{} {:?}", arg1(a, b, c), arg2); 418 format_args!("{} {:?}", arg1(a, b, c), arg2);
366"#, 419 "#,
367 BuiltinFnLikeExpander::FormatArgs,
368 ); 420 );
369 421
370 assert_eq!( 422 assert_eq!(
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs
index fd02ffa4e..e62693b68 100644
--- a/crates/ra_hir_expand/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs
@@ -170,6 +170,8 @@ pub mod known {
170 stringify, 170 stringify,
171 format_args, 171 format_args,
172 format_args_nl, 172 format_args_nl,
173 env,
174 option_env,
173 // Builtin derives 175 // Builtin derives
174 Copy, 176 Copy,
175 Clone, 177 Clone,
diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs
index 49155fe62..4de219ce4 100644
--- a/crates/ra_hir_expand/src/quote.rs
+++ b/crates/ra_hir_expand/src/quote.rs
@@ -102,6 +102,8 @@ macro_rules! __quote {
102 ( : ) => {$crate::__quote!(@PUNCT ':')}; 102 ( : ) => {$crate::__quote!(@PUNCT ':')};
103 ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; 103 ( :: ) => {$crate::__quote!(@PUNCT ':', ':')};
104 ( . ) => {$crate::__quote!(@PUNCT '.')}; 104 ( . ) => {$crate::__quote!(@PUNCT '.')};
105 ( < ) => {$crate::__quote!(@PUNCT '<')};
106 ( > ) => {$crate::__quote!(@PUNCT '>')};
105 107
106 ( $first:tt $($tail:tt)+ ) => { 108 ( $first:tt $($tail:tt)+ ) => {
107 { 109 {