aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_diagnostics/src/handlers/macro_error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_diagnostics/src/handlers/macro_error.rs')
-rw-r--r--crates/ide_diagnostics/src/handlers/macro_error.rs173
1 files changed, 173 insertions, 0 deletions
diff --git a/crates/ide_diagnostics/src/handlers/macro_error.rs b/crates/ide_diagnostics/src/handlers/macro_error.rs
new file mode 100644
index 000000000..d4d928ad1
--- /dev/null
+++ b/crates/ide_diagnostics/src/handlers/macro_error.rs
@@ -0,0 +1,173 @@
1use crate::{Diagnostic, DiagnosticsContext};
2
3// Diagnostic: macro-error
4//
5// This diagnostic is shown for macro expansion errors.
6pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic {
7 Diagnostic::new(
8 "macro-error",
9 d.message.clone(),
10 ctx.sema.diagnostics_display_range(d.node.clone()).range,
11 )
12 .experimental()
13}
14
15#[cfg(test)]
16mod tests {
17 use crate::{
18 tests::{check_diagnostics, check_diagnostics_with_config},
19 DiagnosticsConfig,
20 };
21
22 #[test]
23 fn builtin_macro_fails_expansion() {
24 check_diagnostics(
25 r#"
26#[rustc_builtin_macro]
27macro_rules! include { () => {} }
28
29 include!("doesntexist");
30//^^^^^^^^^^^^^^^^^^^^^^^^ failed to load file `doesntexist`
31 "#,
32 );
33 }
34
35 #[test]
36 fn include_macro_should_allow_empty_content() {
37 let mut config = DiagnosticsConfig::default();
38
39 // FIXME: This is a false-positive, the file is actually linked in via
40 // `include!` macro
41 config.disabled.insert("unlinked-file".to_string());
42
43 check_diagnostics_with_config(
44 config,
45 r#"
46//- /lib.rs
47#[rustc_builtin_macro]
48macro_rules! include { () => {} }
49
50include!("foo/bar.rs");
51//- /foo/bar.rs
52// empty
53"#,
54 );
55 }
56
57 #[test]
58 fn good_out_dir_diagnostic() {
59 check_diagnostics(
60 r#"
61#[rustc_builtin_macro]
62macro_rules! include { () => {} }
63#[rustc_builtin_macro]
64macro_rules! env { () => {} }
65#[rustc_builtin_macro]
66macro_rules! concat { () => {} }
67
68 include!(concat!(env!("OUT_DIR"), "/out.rs"));
69//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
70"#,
71 );
72 }
73
74 #[test]
75 fn register_attr_and_tool() {
76 cov_mark::check!(register_attr);
77 cov_mark::check!(register_tool);
78 check_diagnostics(
79 r#"
80#![register_tool(tool)]
81#![register_attr(attr)]
82
83#[tool::path]
84#[attr]
85struct S;
86"#,
87 );
88 // NB: we don't currently emit diagnostics here
89 }
90
91 #[test]
92 fn macro_diag_builtin() {
93 check_diagnostics(
94 r#"
95#[rustc_builtin_macro]
96macro_rules! env {}
97
98#[rustc_builtin_macro]
99macro_rules! include {}
100
101#[rustc_builtin_macro]
102macro_rules! compile_error {}
103
104#[rustc_builtin_macro]
105macro_rules! format_args { () => {} }
106
107fn main() {
108 // Test a handful of built-in (eager) macros:
109
110 include!(invalid);
111 //^^^^^^^^^^^^^^^^^ could not convert tokens
112 include!("does not exist");
113 //^^^^^^^^^^^^^^^^^^^^^^^^^^ failed to load file `does not exist`
114
115 env!(invalid);
116 //^^^^^^^^^^^^^ could not convert tokens
117
118 env!("OUT_DIR");
119 //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
120
121 compile_error!("compile_error works");
122 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compile_error works
123
124 // Lazy:
125
126 format_args!();
127 //^^^^^^^^^^^^^^ no rule matches input tokens
128}
129"#,
130 );
131 }
132
133 #[test]
134 fn macro_rules_diag() {
135 check_diagnostics(
136 r#"
137macro_rules! m {
138 () => {};
139}
140fn f() {
141 m!();
142
143 m!(hi);
144 //^^^^^^ leftover tokens
145}
146 "#,
147 );
148 }
149 #[test]
150 fn dollar_crate_in_builtin_macro() {
151 check_diagnostics(
152 r#"
153#[macro_export]
154#[rustc_builtin_macro]
155macro_rules! format_args {}
156
157#[macro_export]
158macro_rules! arg { () => {} }
159
160#[macro_export]
161macro_rules! outer {
162 () => {
163 $crate::format_args!( "", $crate::arg!(1) )
164 };
165}
166
167fn f() {
168 outer!();
169} //^^^^^^^^ leftover tokens
170"#,
171 )
172 }
173}