]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/errors.rs
Migrate irrefutable let pattern diagnostics
[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::{symbol::Ident, 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 }
432
433 #[derive(SessionDiagnostic)]
434 #[diag(mir_build::static_in_pattern, code = "E0158")]
435 pub struct StaticInPattern {
436     #[primary_span]
437     pub span: Span,
438 }
439
440 #[derive(SessionDiagnostic)]
441 #[diag(mir_build::assoc_const_in_pattern, code = "E0158")]
442 pub struct AssocConstInPattern {
443     #[primary_span]
444     pub span: Span,
445 }
446
447 #[derive(SessionDiagnostic)]
448 #[diag(mir_build::const_param_in_pattern, code = "E0158")]
449 pub struct ConstParamInPattern {
450     #[primary_span]
451     pub span: Span,
452 }
453
454 #[derive(SessionDiagnostic)]
455 #[diag(mir_build::non_const_path, code = "E0080")]
456 pub struct NonConstPath {
457     #[primary_span]
458     pub span: Span,
459 }
460
461 #[derive(LintDiagnostic)]
462 #[diag(mir_build::unreachable_pattern)]
463 pub struct UnreachablePattern {
464     #[label]
465     pub span: Option<Span>,
466     #[label(mir_build::catchall_label)]
467     pub catchall: Option<Span>,
468 }
469
470 #[derive(SessionDiagnostic)]
471 #[diag(mir_build::const_pattern_depends_on_generic_parameter)]
472 pub struct ConstPatternDependsOnGenericParameter {
473     #[primary_span]
474     pub span: Span,
475 }
476
477 #[derive(SessionDiagnostic)]
478 #[diag(mir_build::could_not_eval_const_pattern)]
479 pub struct CouldNotEvalConstPattern {
480     #[primary_span]
481     pub span: Span,
482 }
483
484 #[derive(SessionDiagnostic)]
485 #[diag(mir_build::lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")]
486 pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
487     #[primary_span]
488     #[label]
489     pub span: Span,
490     #[note(mir_build::teach_note)]
491     pub teach: Option<()>,
492 }
493
494 #[derive(SessionDiagnostic)]
495 #[diag(mir_build::lower_range_bound_must_be_less_than_upper, code = "E0579")]
496 pub struct LowerRangeBoundMustBeLessThanUpper {
497     #[primary_span]
498     pub span: Span,
499 }
500
501 #[derive(LintDiagnostic)]
502 #[diag(mir_build::leading_irrefutable_let_patterns)]
503 #[note]
504 #[help]
505 pub struct LeadingIrrefutableLetPatterns {
506     pub count: usize,
507 }
508
509 #[derive(LintDiagnostic)]
510 #[diag(mir_build::trailing_irrefutable_let_patterns)]
511 #[note]
512 #[help]
513 pub struct TrailingIrrefutableLetPatterns {
514     pub count: usize,
515 }
516
517 #[derive(LintDiagnostic)]
518 #[diag(mir_build::bindings_with_variant_name, code = "E0170")]
519 pub struct BindingsWithVariantName {
520     #[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")]
521     pub suggestion: Option<Span>,
522     pub ty_path: String,
523     pub ident: Ident,
524 }
525
526 #[derive(LintDiagnostic)]
527 #[diag(mir_build::irrefutable_let_patterns_generic_let)]
528 #[note]
529 #[help]
530 pub struct IrrefutableLetPatternsGenericLet {
531     pub count: usize,
532 }
533
534 #[derive(LintDiagnostic)]
535 #[diag(mir_build::irrefutable_let_patterns_if_let)]
536 #[note]
537 #[help]
538 pub struct IrrefutableLetPatternsIfLet {
539     pub count: usize,
540 }
541
542 #[derive(LintDiagnostic)]
543 #[diag(mir_build::irrefutable_let_patterns_if_let_guard)]
544 #[note]
545 #[help]
546 pub struct IrrefutableLetPatternsIfLetGuard {
547     pub count: usize,
548 }
549
550 #[derive(LintDiagnostic)]
551 #[diag(mir_build::irrefutable_let_patterns_let_else)]
552 #[note]
553 #[help]
554 pub struct IrrefutableLetPatternsLetElse {
555     pub count: usize,
556 }
557
558 #[derive(LintDiagnostic)]
559 #[diag(mir_build::irrefutable_let_patterns_while_let)]
560 #[note]
561 #[help]
562 pub struct IrrefutableLetPatternsWhileLet {
563     pub count: usize,
564 }