about summary refs log tree commit diff
diff options
context:
space:
mode:
author111 <mic215@ucsd.edu>2022-08-31 20:16:02 +0800
committer111 <mic215@ucsd.edu>2022-09-01 23:35:38 +0800
commit00cd965046f6f3e9fcf937bf1f6fec4d7f8d50ca (patch)
tree86f84210a301c191ef2e3fe1714d4c3627323635
parent3e834a7a6295127fe2a5dd8605c7903ad7e5918d (diff)
downloadrust-00cd965046f6f3e9fcf937bf1f6fec4d7f8d50ca.tar.gz
rust-00cd965046f6f3e9fcf937bf1f6fec4d7f8d50ca.zip
Migrate OpaqueHiddenType mismatch
-rw-r--r--compiler/rustc_error_messages/locales/en-US/middle.ftl10
-rw-r--r--compiler/rustc_middle/src/error.rs26
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs24
3 files changed, 47 insertions, 13 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl
index f2864ec4922..bc1aebd9dbe 100644
--- a/compiler/rustc_error_messages/locales/en-US/middle.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl
@@ -1,3 +1,13 @@
 middle_drop_check_overflow =
     overflow while adding drop-check rules for {$ty}
     .note = {$note}
+
+middle_opaque_hidden_type_mismatch =
+    concrete type differs from previous defining opaque type use
+    .label = expected `{$self_ty}`, got `{$other_ty}`
+
+middle_conflict_types =
+    this expression supplies two conflicting concrete types for the same opaque type
+
+middle_previous_use_here =
+    previous use here
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index d81eb524169..27588440aac 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -12,3 +12,29 @@ pub struct DropCheckOverflow<'tcx> {
     pub ty: Ty<'tcx>,
     pub note: String,
 }
+
+#[derive(SessionDiagnostic)]
+#[diag(middle::opaque_hidden_type_mismatch)]
+pub struct OpaqueHiddenTypeMismatch<'tcx> {
+    pub self_ty: Ty<'tcx>,
+    pub other_ty: Ty<'tcx>,
+    #[primary_span]
+    #[label]
+    pub other_span: Span,
+    #[subdiagnostic]
+    pub sub: TypeMismatchReason,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum TypeMismatchReason {
+    #[label(middle::conflict_types)]
+    ConflictType {
+        #[primary_span]
+        span: Span,
+    },
+    #[note(middle::previous_use_here)]
+    PreviousUse {
+        #[primary_span]
+        span: Span,
+    },
+}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ed04e766033..5c38d761411 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -15,6 +15,7 @@ pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
 pub use self::IntVarValue::*;
 pub use self::Variance::*;
+use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
 use crate::metadata::ModChild;
 use crate::middle::privacy::AccessLevels;
 use crate::mir::{Body, GeneratorLayout};
@@ -1184,20 +1185,17 @@ pub struct OpaqueHiddenType<'tcx> {
 impl<'tcx> OpaqueHiddenType<'tcx> {
     pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
         // Found different concrete types for the opaque type.
-        let mut err = tcx.sess.struct_span_err(
-            other.span,
-            "concrete type differs from previous defining opaque type use",
-        );
-        err.span_label(other.span, format!("expected `{}`, got `{}`", self.ty, other.ty));
-        if self.span == other.span {
-            err.span_label(
-                self.span,
-                "this expression supplies two conflicting concrete types for the same opaque type",
-            );
+        let sub_diag = if self.span == other.span {
+            TypeMismatchReason::ConflictType { span: self.span }
         } else {
-            err.span_note(self.span, "previous use here");
-        }
-        err.emit();
+            TypeMismatchReason::PreviousUse { span: self.span }
+        };
+        tcx.sess.emit_err(OpaqueHiddenTypeMismatch {
+            self_ty: self.ty,
+            other_ty: other.ty,
+            other_span: other.span,
+            sub: sub_diag,
+        });
     }
 }