]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/structured_errors.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc_typeck / structured_errors.rs
CommitLineData
2c00a5a8
XL
1use rustc::session::Session;
2use syntax_pos::Span;
b7449926 3use errors::{Applicability, DiagnosticId, DiagnosticBuilder};
2c00a5a8
XL
4use rustc::ty::{Ty, TypeFoldable};
5
60c5eb7d
XL
6use rustc_error_codes::*;
7
2c00a5a8
XL
8pub trait StructuredDiagnostic<'tcx> {
9 fn session(&self) -> &Session;
10
11 fn code(&self) -> DiagnosticId;
12
13 fn common(&self) -> DiagnosticBuilder<'tcx>;
14
15 fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
16 let err = self.common();
17 if self.session().teach(&self.code()) {
18 self.extended(err)
19 } else {
20 self.regular(err)
21 }
22 }
23
24 fn regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
25 err
26 }
27
28 fn extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
29 err
30 }
31}
32
33pub struct VariadicError<'tcx> {
34 sess: &'tcx Session,
35 span: Span,
36 t: Ty<'tcx>,
37 cast_ty: &'tcx str,
38}
39
40impl<'tcx> VariadicError<'tcx> {
41 pub fn new(sess: &'tcx Session,
42 span: Span,
43 t: Ty<'tcx>,
44 cast_ty: &'tcx str) -> VariadicError<'tcx> {
45 VariadicError { sess, span, t, cast_ty }
46 }
47}
48
49impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> {
50 fn session(&self) -> &Session { self.sess }
51
52 fn code(&self) -> DiagnosticId {
e1599b0c 53 syntax::diagnostic_used!(E0617);
2c00a5a8
XL
54 DiagnosticId::Error("E0617".to_owned())
55 }
56
57 fn common(&self) -> DiagnosticBuilder<'tcx> {
58 let mut err = if self.t.references_error() {
59 self.sess.diagnostic().struct_dummy()
60 } else {
61 self.sess.struct_span_fatal_with_code(
62 self.span,
63 &format!("can't pass `{}` to variadic function", self.t),
64 self.code(),
65 )
66 };
b7449926 67 if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) {
9fa01778 68 err.span_suggestion(
b7449926
XL
69 self.span,
70 &format!("cast the value to `{}`", self.cast_ty),
71 format!("{} as {}", snippet, self.cast_ty),
72 Applicability::MachineApplicable,
73 );
2c00a5a8
XL
74 } else {
75 err.help(&format!("cast the value to `{}`", self.cast_ty));
76 }
77 err
78 }
79
80 fn extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
81 err.note(&format!("certain types, like `{}`, must be cast before passing them to a \
82 variadic function, because of arcane ABI rules dictated by the C \
83 standard",
84 self.t));
85 err
86 }
87}
88
89pub struct SizedUnsizedCastError<'tcx> {
90 sess: &'tcx Session,
91 span: Span,
92 expr_ty: Ty<'tcx>,
93 cast_ty: String,
94}
95
96impl<'tcx> SizedUnsizedCastError<'tcx> {
97 pub fn new(sess: &'tcx Session,
98 span: Span,
99 expr_ty: Ty<'tcx>,
100 cast_ty: String) -> SizedUnsizedCastError<'tcx> {
101 SizedUnsizedCastError { sess, span, expr_ty, cast_ty }
102 }
103}
104
105impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCastError<'tcx> {
106 fn session(&self) -> &Session { self.sess }
107
108 fn code(&self) -> DiagnosticId {
e1599b0c 109 syntax::diagnostic_used!(E0607);
2c00a5a8
XL
110 DiagnosticId::Error("E0607".to_owned())
111 }
112
113 fn common(&self) -> DiagnosticBuilder<'tcx> {
114 if self.expr_ty.references_error() {
115 self.sess.diagnostic().struct_dummy()
116 } else {
117 self.sess.struct_span_fatal_with_code(
118 self.span,
119 &format!("cannot cast thin pointer `{}` to fat pointer `{}`",
120 self.expr_ty,
121 self.cast_ty),
122 self.code(),
123 )
124 }
125 }
126
127 fn extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
128 err.help(
129 "Thin pointers are \"simple\" pointers: they are purely a reference to a
130memory address.
131
132Fat pointers are pointers referencing \"Dynamically Sized Types\" (also
133called DST). DST don't have a statically known size, therefore they can
134only exist behind some kind of pointers that contain additional
135information. Slices and trait objects are DSTs. In the case of slices,
136the additional information the fat pointer holds is their size.
137
138To fix this error, don't try to cast directly between thin and fat
139pointers.
140
141For more information about casts, take a look at The Book:
9fa01778 142https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions");
2c00a5a8
XL
143 err
144 }
145}