about summary refs log tree commit diff
diff options
context:
space:
mode:
authorObei Sideg <obei.sideg@gmail.com>2023-09-14 21:50:22 +0300
committerObei Sideg <obei.sideg@gmail.com>2023-09-14 21:50:22 +0300
commit8723af511601969b536d0faa78b886dd4561a559 (patch)
tree8ca812576854e8a5132c4a1353789238d83e0073
parent5e719131567bae5b973b6adb3e3fa756a5f7eb73 (diff)
downloadrust-8723af511601969b536d0faa78b886dd4561a559.tar.gz
rust-8723af511601969b536d0faa78b886dd4561a559.zip
Migrate `rustc_hir_analysis` to session diagnostic
Part 6: Finish `coherence/inherent_impls.rs`
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl28
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs93
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs72
3 files changed, 116 insertions, 77 deletions
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 50da2278312..1a38657dff4 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -95,6 +95,34 @@ hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a par
 hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
     .note = parent implementation is in crate `{$cname}`
 
+hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait
+    .label = impl requires at least one non-auto trait
+    .note = define and implement a new trait or type instead
+
+hir_analysis_inherent_nominal = no nominal type found for inherent implementation
+    .label = impl requires a nominal type
+    .note = either implement a trait on it or create a newtype to wrap it instead
+hir_analysis_inherent_primitive_ty = cannot define inherent `impl` for primitive types
+    .help = consider using an extension trait instead
+
+hir_analysis_inherent_primitive_ty_note = you could also try moving the reference to uses of `{$subty}` (such as `self`) within the implementation
+
+hir_analysis_inherent_ty_outside = cannot define inherent `impl` for a type outside of the crate where the type is defined
+    .help = consider moving this inherent impl into the crate defining the type if possible
+    .span_help = alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items
+
+hir_analysis_inherent_ty_outside_new = cannot define inherent `impl` for a type outside of the crate where the type is defined
+    .label = impl for type defined outside of crate.
+    .note = define and implement a trait or new type instead
+
+hir_analysis_inherent_ty_outside_primitive = cannot define inherent `impl` for primitive types outside of `core`
+    .help = consider moving this inherent impl into `core` if possible
+    .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
+
+hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a type outside of the crate where the type is defined
+    .help = consider moving this inherent impl into the crate defining the type if possible
+    .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
+
 hir_analysis_invalid_union_field =
     field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
     .note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index a94c75f918a..aa7c9e504c1 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -7,7 +7,6 @@
 //! `tcx.inherent_impls(def_id)`). That value, however,
 //! is computed by selecting an idea from this table.
 
-use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -15,6 +14,8 @@ use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
 use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 
+use crate::errors;
+
 /// On-demand query: yields a map containing all types mapped to their inherent impls.
 pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls {
     let mut collect = InherentCollect { tcx, impls_map: Default::default() };
@@ -45,14 +46,6 @@ struct InherentCollect<'tcx> {
     impls_map: CrateInherentImpls,
 }
 
-const INTO_CORE: &str = "consider moving this inherent impl into `core` if possible";
-const INTO_DEFINING_CRATE: &str =
-    "consider moving this inherent impl into the crate defining the type if possible";
-const ADD_ATTR_TO_TY: &str = "alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type \
-     and `#[rustc_allow_incoherent_impl]` to the relevant impl items";
-const ADD_ATTR: &str =
-    "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items";
-
 impl<'tcx> InherentCollect<'tcx> {
     fn check_def_id(&mut self, impl_def_id: LocalDefId, self_ty: Ty<'tcx>, ty_def_id: DefId) {
         if let Some(ty_def_id) = ty_def_id.as_local() {
@@ -69,30 +62,17 @@ impl<'tcx> InherentCollect<'tcx> {
 
             if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) {
                 let impl_span = self.tcx.def_span(impl_def_id);
-                struct_span_err!(
-                    self.tcx.sess,
-                    impl_span,
-                    E0390,
-                    "cannot define inherent `impl` for a type outside of the crate where the type is defined",
-                )
-                .help(INTO_DEFINING_CRATE)
-                .span_help(impl_span, ADD_ATTR_TO_TY)
-                .emit();
+                self.tcx.sess.emit_err(errors::InherentTyOutside { span: impl_span });
                 return;
             }
 
             for &impl_item in items {
                 if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) {
                     let impl_span = self.tcx.def_span(impl_def_id);
-                    struct_span_err!(
-                        self.tcx.sess,
-                        impl_span,
-                        E0390,
-                        "cannot define inherent `impl` for a type outside of the crate where the type is defined",
-                    )
-                    .help(INTO_DEFINING_CRATE)
-                    .span_help(self.tcx.def_span(impl_item), ADD_ATTR)
-                    .emit();
+                    self.tcx.sess.emit_err(errors::InherentTyOutsideRelevant {
+                        span: impl_span,
+                        help_span: self.tcx.def_span(impl_item),
+                    });
                     return;
                 }
             }
@@ -104,16 +84,7 @@ impl<'tcx> InherentCollect<'tcx> {
             }
         } else {
             let impl_span = self.tcx.def_span(impl_def_id);
-            struct_span_err!(
-                self.tcx.sess,
-                impl_span,
-                E0116,
-                "cannot define inherent `impl` for a type outside of the crate \
-                              where the type is defined"
-            )
-            .span_label(impl_span, "impl for type defined outside of crate.")
-            .note("define and implement a trait or new type instead")
-            .emit();
+            self.tcx.sess.emit_err(errors::InherentTyOutsideNew { span: impl_span });
         }
     }
 
@@ -124,34 +95,20 @@ impl<'tcx> InherentCollect<'tcx> {
                 for &impl_item in items {
                     if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) {
                         let span = self.tcx.def_span(impl_def_id);
-                        struct_span_err!(
-                            self.tcx.sess,
+                        self.tcx.sess.emit_err(errors::InherentTyOutsidePrimitive {
                             span,
-                            E0390,
-                            "cannot define inherent `impl` for primitive types outside of `core`",
-                        )
-                        .help(INTO_CORE)
-                        .span_help(self.tcx.def_span(impl_item), ADD_ATTR)
-                        .emit();
+                            help_span: self.tcx.def_span(impl_item),
+                        });
                         return;
                     }
                 }
             } else {
                 let span = self.tcx.def_span(impl_def_id);
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0390,
-                    "cannot define inherent `impl` for primitive types",
-                );
-                err.help("consider using an extension trait instead");
+                let mut note = None;
                 if let ty::Ref(_, subty, _) = ty.kind() {
-                    err.note(format!(
-                        "you could also try moving the reference to \
-                            uses of `{subty}` (such as `self`) within the implementation"
-                    ));
+                    note = Some(errors::InherentPrimitiveTyNote { subty: *subty });
                 }
-                err.emit();
+                self.tcx.sess.emit_err(errors::InherentPrimitiveTy { span, note });
                 return;
             }
         }
@@ -178,15 +135,7 @@ impl<'tcx> InherentCollect<'tcx> {
                 self.check_def_id(id, self_ty, data.principal_def_id().unwrap());
             }
             ty::Dynamic(..) => {
-                struct_span_err!(
-                    self.tcx.sess,
-                    item_span,
-                    E0785,
-                    "cannot define inherent `impl` for a dyn auto trait"
-                )
-                .span_label(item_span, "impl requires at least one non-auto trait")
-                .note("define and implement a new trait or type instead")
-                .emit();
+                self.tcx.sess.emit_err(errors::InherentDyn { span: item_span });
             }
             ty::Bool
             | ty::Char
@@ -202,17 +151,7 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::FnPtr(_)
             | ty::Tuple(..) => self.check_primitive_impl(id, self_ty),
             ty::Alias(..) | ty::Param(_) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    item_span,
-                    E0118,
-                    "no nominal type found for inherent implementation"
-                );
-
-                err.span_label(item_span, "impl requires a nominal type")
-                    .note("either implement a trait on it or create a newtype to wrap it instead");
-
-                err.emit();
+                self.tcx.sess.emit_err(errors::InherentNominal { span: item_span });
             }
             ty::FnDef(..)
             | ty::Closure(..)
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 7614913f4bf..b83ef8d07db 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -943,3 +943,75 @@ pub struct AssocBoundOnConst {
     pub span: Span,
     pub descr: &'static str,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_ty_outside, code = "E0390")]
+#[help]
+pub struct InherentTyOutside {
+    #[primary_span]
+    #[help(hir_analysis_span_help)]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_ty_outside_relevant, code = "E0390")]
+#[help]
+pub struct InherentTyOutsideRelevant {
+    #[primary_span]
+    pub span: Span,
+    #[help(hir_analysis_span_help)]
+    pub help_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_ty_outside_new, code = "E0116")]
+#[note]
+pub struct InherentTyOutsideNew {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_ty_outside_primitive, code = "E0390")]
+#[help]
+pub struct InherentTyOutsidePrimitive {
+    #[primary_span]
+    pub span: Span,
+    #[help(hir_analysis_span_help)]
+    pub help_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_primitive_ty, code = "E0390")]
+#[help]
+pub struct InherentPrimitiveTy<'a> {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub note: Option<InherentPrimitiveTyNote<'a>>,
+}
+
+#[derive(Subdiagnostic)]
+#[note(hir_analysis_inherent_primitive_ty_note)]
+pub struct InherentPrimitiveTyNote<'a> {
+    pub subty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_dyn, code = "E0785")]
+#[note]
+pub struct InherentDyn {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_inherent_nominal, code = "E0118")]
+#[note]
+pub struct InherentNominal {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}