]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/errors.rs
Migrate "non-exhaustive patterns: type is non-empty" diagnostic
[rust.git] / compiler / rustc_mir_build / src / errors.rs
1 use crate::thir::pattern::MatchCheckCtxt;
2 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
3 use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
4 use rustc_middle::ty::{self, Ty};
5 use rustc_session::{parse::ParseSess, SessionDiagnostic};
6 use rustc_span::Span;
7
8 #[derive(LintDiagnostic)]
9 #[diag(mir_build::unconditional_recursion)]
10 #[help]
11 pub struct UnconditionalRecursion {
12     #[label]
13     pub span: Span,
14     #[label(mir_build::unconditional_recursion_call_site_label)]
15     pub call_sites: Vec<Span>,
16 }
17
18 #[derive(LintDiagnostic)]
19 #[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
20 #[note]
21 pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> {
22     #[label]
23     pub span: Span,
24     pub function: &'a str,
25 }
26
27 #[derive(LintDiagnostic)]
28 #[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)]
29 #[note]
30 pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless {
31     #[label]
32     pub span: Span,
33 }
34
35 #[derive(LintDiagnostic)]
36 #[diag(mir_build::unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)]
37 #[note]
38 pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe {
39     #[label]
40     pub span: Span,
41 }
42
43 #[derive(LintDiagnostic)]
44 #[diag(mir_build::unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)]
45 #[note]
46 pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
47     #[label]
48     pub span: Span,
49 }
50
51 #[derive(LintDiagnostic)]
52 #[diag(mir_build::unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)]
53 #[note]
54 pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
55     #[label]
56     pub span: Span,
57 }
58
59 #[derive(LintDiagnostic)]
60 #[diag(mir_build::unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)]
61 #[note]
62 pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
63     #[label]
64     pub span: Span,
65 }
66
67 #[derive(LintDiagnostic)]
68 #[diag(mir_build::unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)]
69 #[note]
70 pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
71     #[label]
72     pub span: Span,
73 }
74
75 #[derive(LintDiagnostic)]
76 #[diag(mir_build::unsafe_op_in_unsafe_fn_union_field_requires_unsafe)]
77 #[note]
78 pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe {
79     #[label]
80     pub span: Span,
81 }
82
83 #[derive(LintDiagnostic)]
84 #[diag(mir_build::unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)]
85 #[note]
86 pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe {
87     #[label]
88     pub span: Span,
89 }
90
91 #[derive(LintDiagnostic)]
92 #[diag(mir_build::unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)]
93 pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
94     #[label]
95     pub span: Span,
96 }
97
98 #[derive(LintDiagnostic)]
99 #[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
100 #[note]
101 pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
102     #[label]
103     pub span: Span,
104     pub function: &'a str,
105 }
106
107 #[derive(SessionDiagnostic)]
108 #[diag(mir_build::call_to_unsafe_fn_requires_unsafe, code = "E0133")]
109 #[note]
110 pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
111     #[primary_span]
112     #[label]
113     pub span: Span,
114     pub function: &'a str,
115 }
116
117 #[derive(SessionDiagnostic)]
118 #[diag(mir_build::call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")]
119 #[note]
120 pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
121     #[primary_span]
122     #[label]
123     pub span: Span,
124 }
125
126 #[derive(SessionDiagnostic)]
127 #[diag(mir_build::call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
128 #[note]
129 pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
130     #[primary_span]
131     #[label]
132     pub span: Span,
133     pub function: &'a str,
134 }
135
136 #[derive(SessionDiagnostic)]
137 #[diag(
138     mir_build::call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed,
139     code = "E0133"
140 )]
141 #[note]
142 pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
143     #[primary_span]
144     #[label]
145     pub span: Span,
146 }
147
148 #[derive(SessionDiagnostic)]
149 #[diag(mir_build::inline_assembly_requires_unsafe, code = "E0133")]
150 #[note]
151 pub struct UseOfInlineAssemblyRequiresUnsafe {
152     #[primary_span]
153     #[label]
154     pub span: Span,
155 }
156
157 #[derive(SessionDiagnostic)]
158 #[diag(mir_build::inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
159 #[note]
160 pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
161     #[primary_span]
162     #[label]
163     pub span: Span,
164 }
165
166 #[derive(SessionDiagnostic)]
167 #[diag(mir_build::initializing_type_with_requires_unsafe, code = "E0133")]
168 #[note]
169 pub struct InitializingTypeWithRequiresUnsafe {
170     #[primary_span]
171     #[label]
172     pub span: Span,
173 }
174
175 #[derive(SessionDiagnostic)]
176 #[diag(
177     mir_build::initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
178     code = "E0133"
179 )]
180 #[note]
181 pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
182     #[primary_span]
183     #[label]
184     pub span: Span,
185 }
186
187 #[derive(SessionDiagnostic)]
188 #[diag(mir_build::mutable_static_requires_unsafe, code = "E0133")]
189 #[note]
190 pub struct UseOfMutableStaticRequiresUnsafe {
191     #[primary_span]
192     #[label]
193     pub span: Span,
194 }
195
196 #[derive(SessionDiagnostic)]
197 #[diag(mir_build::mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
198 #[note]
199 pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
200     #[primary_span]
201     #[label]
202     pub span: Span,
203 }
204
205 #[derive(SessionDiagnostic)]
206 #[diag(mir_build::extern_static_requires_unsafe, code = "E0133")]
207 #[note]
208 pub struct UseOfExternStaticRequiresUnsafe {
209     #[primary_span]
210     #[label]
211     pub span: Span,
212 }
213
214 #[derive(SessionDiagnostic)]
215 #[diag(mir_build::extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
216 #[note]
217 pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
218     #[primary_span]
219     #[label]
220     pub span: Span,
221 }
222
223 #[derive(SessionDiagnostic)]
224 #[diag(mir_build::deref_raw_pointer_requires_unsafe, code = "E0133")]
225 #[note]
226 pub struct DerefOfRawPointerRequiresUnsafe {
227     #[primary_span]
228     #[label]
229     pub span: Span,
230 }
231
232 #[derive(SessionDiagnostic)]
233 #[diag(mir_build::deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
234 #[note]
235 pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
236     #[primary_span]
237     #[label]
238     pub span: Span,
239 }
240
241 #[derive(SessionDiagnostic)]
242 #[diag(mir_build::union_field_requires_unsafe, code = "E0133")]
243 #[note]
244 pub struct AccessToUnionFieldRequiresUnsafe {
245     #[primary_span]
246     #[label]
247     pub span: Span,
248 }
249
250 #[derive(SessionDiagnostic)]
251 #[diag(mir_build::union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
252 #[note]
253 pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
254     #[primary_span]
255     #[label]
256     pub span: Span,
257 }
258
259 #[derive(SessionDiagnostic)]
260 #[diag(mir_build::mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")]
261 #[note]
262 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
263     #[primary_span]
264     #[label]
265     pub span: Span,
266 }
267
268 #[derive(SessionDiagnostic)]
269 #[diag(
270     mir_build::mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
271     code = "E0133"
272 )]
273 #[note]
274 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
275     #[primary_span]
276     #[label]
277     pub span: Span,
278 }
279
280 #[derive(SessionDiagnostic)]
281 #[diag(mir_build::borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")]
282 #[note]
283 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
284     #[primary_span]
285     #[label]
286     pub span: Span,
287 }
288
289 #[derive(SessionDiagnostic)]
290 #[diag(
291     mir_build::borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
292     code = "E0133"
293 )]
294 #[note]
295 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
296     #[primary_span]
297     #[label]
298     pub span: Span,
299 }
300
301 #[derive(SessionDiagnostic)]
302 #[diag(mir_build::call_to_fn_with_requires_unsafe, code = "E0133")]
303 #[note]
304 pub struct CallToFunctionWithRequiresUnsafe<'a> {
305     #[primary_span]
306     #[label]
307     pub span: Span,
308     pub function: &'a str,
309 }
310
311 #[derive(SessionDiagnostic)]
312 #[diag(mir_build::call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
313 #[note]
314 pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
315     #[primary_span]
316     #[label]
317     pub span: Span,
318     pub function: &'a str,
319 }
320
321 #[derive(LintDiagnostic)]
322 #[diag(mir_build::unused_unsafe)]
323 pub struct UnusedUnsafe {
324     #[label]
325     pub span: Span,
326     #[subdiagnostic]
327     pub enclosing: Option<UnusedUnsafeEnclosing>,
328 }
329
330 #[derive(SessionSubdiagnostic)]
331 pub enum UnusedUnsafeEnclosing {
332     #[label(mir_build::unused_unsafe_enclosing_block_label)]
333     Block {
334         #[primary_span]
335         span: Span,
336     },
337     #[label(mir_build::unused_unsafe_enclosing_fn_label)]
338     Function {
339         #[primary_span]
340         span: Span,
341     },
342 }
343
344 pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
345     pub cx: &'m MatchCheckCtxt<'p, 'tcx>,
346     pub expr_span: Span,
347     pub span: Span,
348     pub ty: Ty<'tcx>,
349 }
350
351 impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
352     fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
353         let mut diag = sess.span_diagnostic.struct_span_err_with_code(
354             self.span,
355             rustc_errors::fluent::mir_build::non_exhaustive_patterns_type_not_empty,
356             error_code!(E0004),
357         );
358
359         let peeled_ty = self.ty.peel_refs();
360         diag.set_arg("ty", self.ty);
361         diag.set_arg("peeled_ty", peeled_ty);
362
363         if let ty::Adt(def, _) = peeled_ty.kind() {
364             let def_span = self
365                 .cx
366                 .tcx
367                 .hir()
368                 .get_if_local(def.did())
369                 .and_then(|node| node.ident())
370                 .map(|ident| ident.span)
371                 .unwrap_or_else(|| self.cx.tcx.def_span(def.did()));
372
373             // workaround to make test pass
374             let mut span: MultiSpan = def_span.into();
375             span.push_span_label(def_span, "");
376
377             diag.span_note(span, rustc_errors::fluent::mir_build::def_note);
378         }
379
380         let is_variant_list_non_exhaustive = match self.ty.kind() {
381             ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => {
382                 true
383             }
384             _ => false,
385         };
386
387         if is_variant_list_non_exhaustive {
388             diag.note(rustc_errors::fluent::mir_build::non_exhaustive_type_note);
389         } else {
390             diag.note(rustc_errors::fluent::mir_build::type_note);
391         }
392
393         if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
394             if self.cx.tcx.is_ty_uninhabited_from(self.cx.module, *sub_ty, self.cx.param_env) {
395                 diag.note(rustc_errors::fluent::mir_build::reference_note);
396             }
397         }
398
399         let mut suggestion = None;
400         let sm = self.cx.tcx.sess.source_map();
401         if self.span.eq_ctxt(self.expr_span) {
402             // Get the span for the empty match body `{}`.
403             let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.span) {
404                 (format!("\n{}", snippet), "    ")
405             } else {
406                 (" ".to_string(), "")
407             };
408             suggestion = Some((
409                 self.span.shrink_to_hi().with_hi(self.expr_span.hi()),
410                 format!(
411                     " {{{indentation}{more}_ => todo!(),{indentation}}}",
412                     indentation = indentation,
413                     more = more,
414                 ),
415             ));
416         }
417
418         if let Some((span, sugg)) = suggestion {
419             diag.span_suggestion_verbose(
420                 span,
421                 rustc_errors::fluent::mir_build::suggestion,
422                 sugg,
423                 Applicability::HasPlaceholders,
424             );
425         } else {
426             diag.help(rustc_errors::fluent::mir_build::help);
427         }
428
429         diag
430     }
431 }