about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-02-19 19:10:01 +0000
committerMichael Goulet <michael@errs.io>2025-02-24 19:34:54 +0000
commit96d966b07aabbf0438489b848b8f039f88bb518e (patch)
treebb58368257607f249ec5e30ff9e44a33d8210afc /compiler/rustc_hir_analysis/src
parentb6899ab9216d63762ba7f97c8a457dc9047e0a2b (diff)
downloadrust-96d966b07aabbf0438489b848b8f039f88bb518e.tar.gz
rust-96d966b07aabbf0438489b848b8f039f88bb518e.zip
Consolidate and rework CoercePointee and DispatchFromDyn errors
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs67
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs70
2 files changed, 40 insertions, 97 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 5d70d537505..dc9a5a3db5d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -240,16 +240,17 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
         (&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
         (&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
             if def_a != def_b {
-                let source_path = tcx.def_path_str(def_a.did());
-                let target_path = tcx.def_path_str(def_b.did());
-
-                return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion {
-                    span,
-                    trait_name: "DispatchFromDyn",
-                    note: true,
-                    source_path,
-                    target_path,
-                }));
+                if def_a != def_b {
+                    let source_path = tcx.def_path_str(def_a.did());
+                    let target_path = tcx.def_path_str(def_b.did());
+                    return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
+                        span,
+                        trait_name: "DispatchFromDyn",
+                        note: true,
+                        source_path,
+                        target_path,
+                    }));
+                }
             }
 
             if def_a.repr().c() || def_a.repr().packed() {
@@ -301,43 +302,33 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
 
                         None
                     } else {
-                        Some((i, ty_a, ty_b))
+                        Some((i, ty_a, ty_b, tcx.def_span(field.did)))
                     }
                 })
                 .collect::<Vec<_>>();
             res?;
 
             if coerced_fields.is_empty() {
-                return Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
+                return Err(tcx.dcx().emit_err(errors::CoerceNoField {
                     span,
                     trait_name: "DispatchFromDyn",
                     note: true,
                 }));
             } else if coerced_fields.len() > 1 {
-                return Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
+                return Err(tcx.dcx().emit_err(errors::CoerceMulti {
                     span,
-                    coercions_note: true,
+                    trait_name: "DispatchFromDyn",
                     number: coerced_fields.len(),
-                    coercions: coerced_fields
-                        .iter()
-                        .map(|&(i, ty_a, ty_b)| {
-                            format!("`{}` (`{}` to `{}`)", fields[i].name, ty_a, ty_b,)
-                        })
-                        .collect::<Vec<_>>()
-                        .join(", "),
+                    fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
                 }));
             } else {
                 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
-                for (_, ty_a, ty_b) in coerced_fields {
+                for (_, ty_a, ty_b, _) in coerced_fields {
                     ocx.register_obligation(Obligation::new(
                         tcx,
                         cause.clone(),
                         param_env,
-                        ty::TraitRef::new(
-                            tcx,
-                            dispatch_from_dyn_trait,
-                            [ty_a, ty_b],
-                        ),
+                        ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]),
                     ));
                 }
                 let errors = ocx.select_all_or_error();
@@ -353,7 +344,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
         }
         _ => Err(tcx
             .dcx()
-            .emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })),
+            .emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "DispatchFromDyn" })),
     }
 }
 
@@ -419,7 +410,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
             if def_a != def_b {
                 let source_path = tcx.def_path_str(def_a.did());
                 let target_path = tcx.def_path_str(def_b.did());
-                return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame {
+                return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
                     span,
                     trait_name: "CoerceUnsized",
                     note: true,
@@ -501,12 +492,12 @@ pub(crate) fn coerce_unsized_info<'tcx>(
 
                     // Collect up all fields that were significantly changed
                     // i.e., those that contain T in coerce_unsized T -> U
-                    Some((i, a, b))
+                    Some((i, a, b, tcx.def_span(f.did)))
                 })
                 .collect::<Vec<_>>();
 
             if diff_fields.is_empty() {
-                return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField {
+                return Err(tcx.dcx().emit_err(errors::CoerceNoField {
                     span,
                     trait_name: "CoerceUnsized",
                     note: true,
@@ -519,19 +510,15 @@ pub(crate) fn coerce_unsized_info<'tcx>(
                     tcx.def_span(impl_did)
                 };
 
-                return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti {
+                return Err(tcx.dcx().emit_err(errors::CoerceMulti {
                     span,
-                    coercions_note: true,
+                    trait_name: "CoerceUnsized",
                     number: diff_fields.len(),
-                    coercions: diff_fields
-                        .iter()
-                        .map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b))
-                        .collect::<Vec<_>>()
-                        .join(", "),
+                    fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
                 }));
             }
 
-            let (i, a, b) = diff_fields[0];
+            let (i, a, b, _) = diff_fields[0];
             let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
             (a, b, coerce_unsized_trait, Some(kind))
         }
@@ -539,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
         _ => {
             return Err(tcx
                 .dcx()
-                .emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }));
+                .emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "CoerceUnsized" }));
         }
     };
 
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 1a0b0edb257..a74d9b95e0e 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1165,18 +1165,6 @@ pub(crate) struct InherentTyOutside {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
-pub(crate) struct DispatchFromDynCoercion<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub trait_name: &'a str,
-    #[note(hir_analysis_coercion_between_struct_same_note)]
-    pub note: bool,
-    pub source_path: String,
-    pub target_path: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
 pub(crate) struct DispatchFromDynRepr {
     #[primary_span]
@@ -1293,41 +1281,40 @@ pub(crate) struct DispatchFromDynZST<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
-pub(crate) struct DispatchFromDynSingle<'a> {
+#[diag(hir_analysis_coerce_zero, code = E0374)]
+pub(crate) struct CoerceNoField {
     #[primary_span]
     pub span: Span,
-    pub trait_name: &'a str,
+    pub trait_name: &'static str,
     #[note(hir_analysis_coercion_between_struct_single_note)]
     pub note: bool,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
-#[note]
-pub(crate) struct DispatchFromDynMulti {
+#[diag(hir_analysis_coerce_multi, code = E0375)]
+pub(crate) struct CoerceMulti {
+    pub trait_name: &'static str,
     #[primary_span]
     pub span: Span,
-    #[note(hir_analysis_coercions_note)]
-    pub coercions_note: bool,
     pub number: usize,
-    pub coercions: String,
+    #[note]
+    pub fields: MultiSpan,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = E0376)]
-pub(crate) struct DispatchFromDynStruct<'a> {
+#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
+pub(crate) struct CoerceUnsizedNonStruct {
     #[primary_span]
     pub span: Span,
-    pub trait_name: &'a str,
+    pub trait_name: &'static str,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0377)]
-pub(crate) struct DispatchFromDynSame<'a> {
+pub(crate) struct CoerceSameStruct {
     #[primary_span]
     pub span: Span,
-    pub trait_name: &'a str,
+    pub trait_name: &'static str,
     #[note(hir_analysis_coercion_between_struct_same_note)]
     pub note: bool,
     pub source_path: String,
@@ -1335,37 +1322,6 @@ pub(crate) struct DispatchFromDynSame<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = E0374)]
-pub(crate) struct CoerceUnsizedOneField<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub trait_name: &'a str,
-    #[note(hir_analysis_coercion_between_struct_single_note)]
-    pub note: bool,
-}
-
-#[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
-#[note]
-pub(crate) struct CoerceUnsizedMulti {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[note(hir_analysis_coercions_note)]
-    pub coercions_note: bool,
-    pub number: usize,
-    pub coercions: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
-pub(crate) struct CoerceUnsizedMay<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub trait_name: &'a str,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
 pub(crate) struct TraitCannotImplForTy {
     #[primary_span]