1 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
2 use rustc::session::Session;
3 use rustc::ty::{Ty, TypeFoldable};
6 use rustc_error_codes::*;
8 pub trait StructuredDiagnostic<'tcx> {
9 fn session(&self) -> &Session;
11 fn code(&self) -> DiagnosticId;
13 fn common(&self) -> DiagnosticBuilder<'tcx>;
15 fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
16 let err = self.common();
17 if self.session().teach(&self.code()) { self.extended(err) } else { self.regular(err) }
20 fn regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
24 fn extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
29 pub struct VariadicError<'tcx> {
36 impl<'tcx> VariadicError<'tcx> {
42 ) -> VariadicError<'tcx> {
43 VariadicError { sess, span, t, cast_ty }
47 impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> {
48 fn session(&self) -> &Session {
52 fn code(&self) -> DiagnosticId {
53 errors::error_code!(E0617)
56 fn common(&self) -> DiagnosticBuilder<'tcx> {
57 let mut err = if self.t.references_error() {
58 self.sess.diagnostic().struct_dummy()
60 self.sess.struct_span_fatal_with_code(
62 &format!("can't pass `{}` to variadic function", self.t),
66 if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) {
69 &format!("cast the value to `{}`", self.cast_ty),
70 format!("{} as {}", snippet, self.cast_ty),
71 Applicability::MachineApplicable,
74 err.help(&format!("cast the value to `{}`", self.cast_ty));
79 fn extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
81 "certain types, like `{}`, must be cast before passing them to a \
82 variadic function, because of arcane ABI rules dictated by the C \
90 pub struct SizedUnsizedCastError<'tcx> {
97 impl<'tcx> SizedUnsizedCastError<'tcx> {
103 ) -> SizedUnsizedCastError<'tcx> {
104 SizedUnsizedCastError { sess, span, expr_ty, cast_ty }
108 impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCastError<'tcx> {
109 fn session(&self) -> &Session {
113 fn code(&self) -> DiagnosticId {
114 errors::error_code!(E0607)
117 fn common(&self) -> DiagnosticBuilder<'tcx> {
118 if self.expr_ty.references_error() {
119 self.sess.diagnostic().struct_dummy()
121 self.sess.struct_span_fatal_with_code(
124 "cannot cast thin pointer `{}` to fat pointer `{}`",
125 self.expr_ty, self.cast_ty
132 fn extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
134 "Thin pointers are \"simple\" pointers: they are purely a reference to a
137 Fat pointers are pointers referencing \"Dynamically Sized Types\" (also
138 called DST). DST don't have a statically known size, therefore they can
139 only exist behind some kind of pointers that contain additional
140 information. Slices and trait objects are DSTs. In the case of slices,
141 the additional information the fat pointer holds is their size.
143 To fix this error, don't try to cast directly between thin and fat
146 For more information about casts, take a look at The Book:
147 https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions",