]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_typeck/src/structured_errors.rs
Rollup merge of #81904 - jhpratt:const_int_fn-stabilization, r=jyn514
[rust.git] / compiler / rustc_typeck / src / structured_errors.rs
index 83125a3e2feb67f2733b2dec843b2cf21e70933b..04d04304e70f919e63cd3e95277f1fe88d6adff0 100644 (file)
-use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
-use rustc_middle::ty::{Ty, TypeFoldable};
+mod missing_cast_for_variadic_arg;
+mod sized_unsized_cast;
+mod wrong_number_of_generic_args;
+
+pub use self::{
+    missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*,
+};
+
+use rustc_errors::{DiagnosticBuilder, DiagnosticId};
 use rustc_session::Session;
-use rustc_span::Span;
 
 pub trait StructuredDiagnostic<'tcx> {
     fn session(&self) -> &Session;
 
     fn code(&self) -> DiagnosticId;
 
-    fn common(&self) -> DiagnosticBuilder<'tcx>;
-
     fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
-        let err = self.common();
-        if self.session().teach(&self.code()) { self.extended(err) } else { self.regular(err) }
-    }
-
-    fn regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
-        err
-    }
-
-    fn extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
-        err
-    }
-}
-
-pub struct VariadicError<'tcx> {
-    sess: &'tcx Session,
-    span: Span,
-    t: Ty<'tcx>,
-    cast_ty: &'tcx str,
-}
-
-impl<'tcx> VariadicError<'tcx> {
-    pub fn new(
-        sess: &'tcx Session,
-        span: Span,
-        t: Ty<'tcx>,
-        cast_ty: &'tcx str,
-    ) -> VariadicError<'tcx> {
-        VariadicError { sess, span, t, cast_ty }
-    }
-}
-
-impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> {
-    fn session(&self) -> &Session {
-        self.sess
-    }
-
-    fn code(&self) -> DiagnosticId {
-        rustc_errors::error_code!(E0617)
-    }
+        let err = self.diagnostic_common();
 
-    fn common(&self) -> DiagnosticBuilder<'tcx> {
-        let mut err = if self.t.references_error() {
-            self.sess.diagnostic().struct_dummy()
+        if self.session().teach(&self.code()) {
+            self.diagnostic_extended(err)
         } else {
-            self.sess.struct_span_fatal_with_code(
-                self.span,
-                &format!("can't pass `{}` to variadic function", self.t),
-                self.code(),
-            )
-        };
-        if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) {
-            err.span_suggestion(
-                self.span,
-                &format!("cast the value to `{}`", self.cast_ty),
-                format!("{} as {}", snippet, self.cast_ty),
-                Applicability::MachineApplicable,
-            );
-        } else {
-            err.help(&format!("cast the value to `{}`", self.cast_ty));
+            self.diagnostic_regular(err)
         }
-        err
-    }
-
-    fn extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
-        err.note(&format!(
-            "certain types, like `{}`, must be cast before passing them to a \
-                           variadic function, because of arcane ABI rules dictated by the C \
-                           standard",
-            self.t
-        ));
-        err
-    }
-}
-
-pub struct SizedUnsizedCastError<'tcx> {
-    sess: &'tcx Session,
-    span: Span,
-    expr_ty: Ty<'tcx>,
-    cast_ty: String,
-}
-
-impl<'tcx> SizedUnsizedCastError<'tcx> {
-    pub fn new(
-        sess: &'tcx Session,
-        span: Span,
-        expr_ty: Ty<'tcx>,
-        cast_ty: String,
-    ) -> SizedUnsizedCastError<'tcx> {
-        SizedUnsizedCastError { sess, span, expr_ty, cast_ty }
     }
-}
 
-impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCastError<'tcx> {
-    fn session(&self) -> &Session {
-        self.sess
-    }
+    fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx>;
 
-    fn code(&self) -> DiagnosticId {
-        rustc_errors::error_code!(E0607)
-    }
-
-    fn common(&self) -> DiagnosticBuilder<'tcx> {
-        if self.expr_ty.references_error() {
-            self.sess.diagnostic().struct_dummy()
-        } else {
-            self.sess.struct_span_fatal_with_code(
-                self.span,
-                &format!(
-                    "cannot cast thin pointer `{}` to fat pointer `{}`",
-                    self.expr_ty, self.cast_ty
-                ),
-                self.code(),
-            )
-        }
+    fn diagnostic_regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
+        err
     }
 
-    fn extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
-        err.help(
-            "Thin pointers are \"simple\" pointers: they are purely a reference to a
-memory address.
-
-Fat pointers are pointers referencing \"Dynamically Sized Types\" (also
-called DST). DST don't have a statically known size, therefore they can
-only exist behind some kind of pointers that contain additional
-information. Slices and trait objects are DSTs. In the case of slices,
-the additional information the fat pointer holds is their size.
-
-To fix this error, don't try to cast directly between thin and fat
-pointers.
-
-For more information about casts, take a look at The Book:
-https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions",
-        );
+    fn diagnostic_extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
         err
     }
 }