From 883c8d177d61d34d70d4fccef788fe4b35aaa7ea Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 3 Dec 2020 15:31:04 +0100 Subject: [PATCH] Make `compile_error!` lazy and emit a diagnostic --- crates/hir_def/src/body/tests.rs | 6 ++++ crates/hir_expand/src/builtin_macro.rs | 48 +++++++++++++++----------- crates/hir_expand/src/db.rs | 1 + 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 c7003f2a6a3..7e78340ee4b 100644 --- a/crates/hir_def/src/body/tests.rs +++ b/crates/hir_def/src/body/tests.rs @@ -84,6 +84,9 @@ macro_rules! env {} #[rustc_builtin_macro] macro_rules! include {} +#[rustc_builtin_macro] +macro_rules! compile_error {} + #[rustc_builtin_macro] macro_rules! format_args { () => {} @@ -103,6 +106,9 @@ fn f() { env!("OUT_DIR"); //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix + compile_error!("compile_error works"); + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `compile_error!` called: compile_error works + // Lazy: format_args!(); diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index 7bb42be6cb4..16c3c4d69c1 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( register_builtin! { LAZY: (column, Column) => column_expand, - (compile_error, CompileError) => compile_error_expand, (file, File) => file_expand, (line, Line) => line_expand, (assert, Assert) => assert_expand, @@ -97,6 +96,7 @@ register_builtin! { (format_args_nl, FormatArgsNl) => format_args_expand, EAGER: + (compile_error, CompileError) => compile_error_expand, (concat, Concat) => concat_expand, (include, Include) => include_expand, (include_bytes, IncludeBytes) => include_bytes_expand, @@ -213,25 +213,6 @@ fn file_expand( ExpandResult::ok(expanded) } -fn compile_error_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, - tt: &tt::Subtree, -) -> ExpandResult { - if tt.count() == 1 { - if let tt::TokenTree::Leaf(tt::Leaf::Literal(it)) = &tt.token_trees[0] { - let s = it.text.as_str(); - if s.contains('"') { - return ExpandResult::ok(quote! { loop { #it }}); - } - }; - } - - ExpandResult::only_err(mbe::ExpandError::BindingError( - "`compile_error!` argument be a string".into(), - )) -} - fn format_args_expand( _db: &dyn AstDatabase, _id: LazyMacroId, @@ -280,6 +261,30 @@ fn unquote_str(lit: &tt::Literal) -> Option { token.value().map(|it| it.into_owned()) } +fn compile_error_expand( + _db: &dyn AstDatabase, + _id: EagerMacroId, + tt: &tt::Subtree, +) -> ExpandResult> { + let err = match &*tt.token_trees { + [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => { + let text = it.text.as_str(); + if text.starts_with('"') && text.ends_with('"') { + // FIXME: does not handle raw strings + mbe::ExpandError::Other(format!( + "`compile_error!` called: {}", + &text[1..text.len() - 1] + )) + } else { + mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()) + } + } + _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()), + }; + + ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) } +} + fn concat_expand( _db: &dyn AstDatabase, _arg_id: EagerMacroId, @@ -646,7 +651,8 @@ mod tests { "#, ); - assert_eq!(expanded, r#"loop{"error!"}"#); + // This expands to nothing (since it's in item position), but emits an error. + assert_eq!(expanded, ""); } #[test] diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 4fd0ba290f1..842a177db3f 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -207,6 +207,7 @@ fn macro_expand_with_arg( } else { return ExpandResult { value: Some(db.lookup_intern_eager_expansion(id).subtree), + // FIXME: There could be errors here! err: None, }; }