aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-06-13 16:41:04 +0100
committerAleksey Kladov <[email protected]>2021-06-13 16:41:04 +0100
commit00303284b5cc3a82e32dc3ecbbcfeb2f99de6818 (patch)
tree685e3f21289eaeb25df597413528f25c6239813f /crates/ide
parent1e4aaee7bbc1d56698e70158aa35f578422623d9 (diff)
internal: refactor macro error
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/diagnostics.rs2
-rw-r--r--crates/ide/src/diagnostics/macro_error.rs163
2 files changed, 165 insertions, 0 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index f7965326d..c257ea8e7 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -9,6 +9,7 @@ mod unresolved_extern_crate;
9mod unresolved_import; 9mod unresolved_import;
10mod unresolved_macro_call; 10mod unresolved_macro_call;
11mod unresolved_proc_macro; 11mod unresolved_proc_macro;
12mod macro_error;
12mod inactive_code; 13mod inactive_code;
13mod missing_fields; 14mod missing_fields;
14 15
@@ -229,6 +230,7 @@ pub(crate) fn diagnostics(
229 AnyDiagnostic::UnresolvedMacroCall(d) => unresolved_macro_call::unresolved_macro_call(&ctx, &d), 230 AnyDiagnostic::UnresolvedMacroCall(d) => unresolved_macro_call::unresolved_macro_call(&ctx, &d),
230 AnyDiagnostic::UnresolvedProcMacro(d) => unresolved_proc_macro::unresolved_proc_macro(&ctx, &d), 231 AnyDiagnostic::UnresolvedProcMacro(d) => unresolved_proc_macro::unresolved_proc_macro(&ctx, &d),
231 AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d), 232 AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d),
233 AnyDiagnostic::MacroError(d) => macro_error::macro_error(&ctx, &d),
232 234
233 AnyDiagnostic::InactiveCode(d) => match inactive_code::inactive_code(&ctx, &d) { 235 AnyDiagnostic::InactiveCode(d) => match inactive_code::inactive_code(&ctx, &d) {
234 Some(it) => it, 236 Some(it) => it,
diff --git a/crates/ide/src/diagnostics/macro_error.rs b/crates/ide/src/diagnostics/macro_error.rs
new file mode 100644
index 000000000..8cc8cfb48
--- /dev/null
+++ b/crates/ide/src/diagnostics/macro_error.rs
@@ -0,0 +1,163 @@
1use crate::diagnostics::{Diagnostic, DiagnosticsContext};
2
3// Diagnostic: macro-error
4//
5// This diagnostic is shown for macro expansion errors.
6pub(super) 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::diagnostics::tests::{check_diagnostics, check_no_diagnostics};
18
19 #[test]
20 fn builtin_macro_fails_expansion() {
21 check_diagnostics(
22 r#"
23#[rustc_builtin_macro]
24macro_rules! include { () => {} }
25
26 include!("doesntexist");
27//^^^^^^^^^^^^^^^^^^^^^^^^ failed to load file `doesntexist`
28 "#,
29 );
30 }
31
32 #[test]
33 fn include_macro_should_allow_empty_content() {
34 check_diagnostics(
35 r#"
36//- /lib.rs
37#[rustc_builtin_macro]
38macro_rules! include { () => {} }
39
40include!("foo/bar.rs");
41//- /foo/bar.rs
42// empty
43"#,
44 );
45 }
46
47 #[test]
48 fn good_out_dir_diagnostic() {
49 check_diagnostics(
50 r#"
51#[rustc_builtin_macro]
52macro_rules! include { () => {} }
53#[rustc_builtin_macro]
54macro_rules! env { () => {} }
55#[rustc_builtin_macro]
56macro_rules! concat { () => {} }
57
58 include!(concat!(env!("OUT_DIR"), "/out.rs"));
59//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
60"#,
61 );
62 }
63
64 #[test]
65 fn register_attr_and_tool() {
66 cov_mark::check!(register_attr);
67 cov_mark::check!(register_tool);
68 check_no_diagnostics(
69 r#"
70#![register_tool(tool)]
71#![register_attr(attr)]
72
73#[tool::path]
74#[attr]
75struct S;
76"#,
77 );
78 // NB: we don't currently emit diagnostics here
79 }
80
81 #[test]
82 fn macro_diag_builtin() {
83 check_diagnostics(
84 r#"
85#[rustc_builtin_macro]
86macro_rules! env {}
87
88#[rustc_builtin_macro]
89macro_rules! include {}
90
91#[rustc_builtin_macro]
92macro_rules! compile_error {}
93
94#[rustc_builtin_macro]
95macro_rules! format_args { () => {} }
96
97fn main() {
98 // Test a handful of built-in (eager) macros:
99
100 include!(invalid);
101 //^^^^^^^^^^^^^^^^^ could not convert tokens
102 include!("does not exist");
103 //^^^^^^^^^^^^^^^^^^^^^^^^^^ failed to load file `does not exist`
104
105 env!(invalid);
106 //^^^^^^^^^^^^^ could not convert tokens
107
108 env!("OUT_DIR");
109 //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
110
111 compile_error!("compile_error works");
112 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compile_error works
113
114 // Lazy:
115
116 format_args!();
117 //^^^^^^^^^^^^^^ no rule matches input tokens
118}
119"#,
120 );
121 }
122
123 #[test]
124 fn macro_rules_diag() {
125 check_diagnostics(
126 r#"
127macro_rules! m {
128 () => {};
129}
130fn f() {
131 m!();
132
133 m!(hi);
134 //^^^^^^ leftover tokens
135}
136 "#,
137 );
138 }
139 #[test]
140 fn dollar_crate_in_builtin_macro() {
141 check_diagnostics(
142 r#"
143#[macro_export]
144#[rustc_builtin_macro]
145macro_rules! format_args {}
146
147#[macro_export]
148macro_rules! arg { () => {} }
149
150#[macro_export]
151macro_rules! outer {
152 () => {
153 $crate::format_args!( "", $crate::arg!(1) )
154 };
155}
156
157fn f() {
158 outer!();
159} //^^^^^^^^ leftover tokens
160"#,
161 )
162 }
163}