aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-12-03 14:31:04 +0000
committerJonas Schievink <[email protected]>2020-12-03 14:48:29 +0000
commit883c8d177d61d34d70d4fccef788fe4b35aaa7ea (patch)
treea7b245d83180d37ec2dacdaf46714db0e4d9a628
parent4634bfb332897f8478ed885970e7cb21bb9c4fce (diff)
Make `compile_error!` lazy and emit a diagnostic
-rw-r--r--crates/hir_def/src/body/tests.rs6
-rw-r--r--crates/hir_expand/src/builtin_macro.rs48
-rw-r--r--crates/hir_expand/src/db.rs1
3 files changed, 34 insertions, 21 deletions
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs
index c7003f2a6..7e78340ee 100644
--- a/crates/hir_def/src/body/tests.rs
+++ b/crates/hir_def/src/body/tests.rs
@@ -85,6 +85,9 @@ macro_rules! env {}
85macro_rules! include {} 85macro_rules! include {}
86 86
87#[rustc_builtin_macro] 87#[rustc_builtin_macro]
88macro_rules! compile_error {}
89
90#[rustc_builtin_macro]
88macro_rules! format_args { 91macro_rules! format_args {
89 () => {} 92 () => {}
90} 93}
@@ -103,6 +106,9 @@ fn f() {
103 env!("OUT_DIR"); 106 env!("OUT_DIR");
104 //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix 107 //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix
105 108
109 compile_error!("compile_error works");
110 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `compile_error!` called: compile_error works
111
106 // Lazy: 112 // Lazy:
107 113
108 format_args!(); 114 format_args!();
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 7bb42be6c..16c3c4d69 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -86,7 +86,6 @@ pub fn find_builtin_macro(
86register_builtin! { 86register_builtin! {
87 LAZY: 87 LAZY:
88 (column, Column) => column_expand, 88 (column, Column) => column_expand,
89 (compile_error, CompileError) => compile_error_expand,
90 (file, File) => file_expand, 89 (file, File) => file_expand,
91 (line, Line) => line_expand, 90 (line, Line) => line_expand,
92 (assert, Assert) => assert_expand, 91 (assert, Assert) => assert_expand,
@@ -97,6 +96,7 @@ register_builtin! {
97 (format_args_nl, FormatArgsNl) => format_args_expand, 96 (format_args_nl, FormatArgsNl) => format_args_expand,
98 97
99 EAGER: 98 EAGER:
99 (compile_error, CompileError) => compile_error_expand,
100 (concat, Concat) => concat_expand, 100 (concat, Concat) => concat_expand,
101 (include, Include) => include_expand, 101 (include, Include) => include_expand,
102 (include_bytes, IncludeBytes) => include_bytes_expand, 102 (include_bytes, IncludeBytes) => include_bytes_expand,
@@ -213,25 +213,6 @@ fn file_expand(
213 ExpandResult::ok(expanded) 213 ExpandResult::ok(expanded)
214} 214}
215 215
216fn compile_error_expand(
217 _db: &dyn AstDatabase,
218 _id: LazyMacroId,
219 tt: &tt::Subtree,
220) -> ExpandResult<tt::Subtree> {
221 if tt.count() == 1 {
222 if let tt::TokenTree::Leaf(tt::Leaf::Literal(it)) = &tt.token_trees[0] {
223 let s = it.text.as_str();
224 if s.contains('"') {
225 return ExpandResult::ok(quote! { loop { #it }});
226 }
227 };
228 }
229
230 ExpandResult::only_err(mbe::ExpandError::BindingError(
231 "`compile_error!` argument be a string".into(),
232 ))
233}
234
235fn format_args_expand( 216fn format_args_expand(
236 _db: &dyn AstDatabase, 217 _db: &dyn AstDatabase,
237 _id: LazyMacroId, 218 _id: LazyMacroId,
@@ -280,6 +261,30 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
280 token.value().map(|it| it.into_owned()) 261 token.value().map(|it| it.into_owned())
281} 262}
282 263
264fn compile_error_expand(
265 _db: &dyn AstDatabase,
266 _id: EagerMacroId,
267 tt: &tt::Subtree,
268) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
269 let err = match &*tt.token_trees {
270 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => {
271 let text = it.text.as_str();
272 if text.starts_with('"') && text.ends_with('"') {
273 // FIXME: does not handle raw strings
274 mbe::ExpandError::Other(format!(
275 "`compile_error!` called: {}",
276 &text[1..text.len() - 1]
277 ))
278 } else {
279 mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into())
280 }
281 }
282 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
283 };
284
285 ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) }
286}
287
283fn concat_expand( 288fn concat_expand(
284 _db: &dyn AstDatabase, 289 _db: &dyn AstDatabase,
285 _arg_id: EagerMacroId, 290 _arg_id: EagerMacroId,
@@ -646,7 +651,8 @@ mod tests {
646 "#, 651 "#,
647 ); 652 );
648 653
649 assert_eq!(expanded, r#"loop{"error!"}"#); 654 // This expands to nothing (since it's in item position), but emits an error.
655 assert_eq!(expanded, "");
650 } 656 }
651 657
652 #[test] 658 #[test]
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 4fd0ba290..842a177db 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -207,6 +207,7 @@ fn macro_expand_with_arg(
207 } else { 207 } else {
208 return ExpandResult { 208 return ExpandResult {
209 value: Some(db.lookup_intern_eager_expansion(id).subtree), 209 value: Some(db.lookup_intern_eager_expansion(id).subtree),
210 // FIXME: There could be errors here!
210 err: None, 211 err: None,
211 }; 212 };
212 } 213 }