From 7d2cad68d2ac83bb2d5d62227be0ef0c358f5991 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 7 Apr 2022 13:52:59 +0000 Subject: [PATCH] Deduplicate the error printing code for hidden type mismatches --- .../src/region_infer/opaque_types.rs | 13 +++--------- compiler/rustc_middle/src/ty/mod.rs | 20 +++++++++++++++++++ compiler/rustc_typeck/src/collect/type_of.rs | 16 +-------------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 980b2657829..fa07c4fa949 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -128,17 +128,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let Some(prev) = result.get_mut(&opaque_type_key.def_id) { if prev.ty != ty { if !ty.references_error() { - let mut err = infcx.tcx.sess.struct_span_err( - concrete_type.span, - "concrete type differs from previous defining opaque type use", + prev.report_mismatch( + &OpaqueHiddenType { ty, span: concrete_type.span }, + infcx.tcx, ); - err.span_label(prev.span, format!("expected `{}`, got `{}`", prev.ty, ty)); - if prev.span == concrete_type.span { - err.span_label(prev.span, "this expression supplies two conflicting concrete types for the same opaque type"); - } else { - err.span_note(prev.span, "previous use here"); - } - err.emit(); } prev.ty = infcx.tcx.ty_error(); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 45a215354d0..6e3dc92a233 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1112,6 +1112,26 @@ pub struct OpaqueHiddenType<'tcx> { pub ty: Ty<'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", + ); + } else { + err.span_note(self.span, "previous use here"); + } + err.emit(); + } +} + rustc_index::newtype_index! { /// "Universes" are used during type- and trait-checking in the /// presence of `for<..>` binders to control what sets of names are diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 737f9e7b9e1..785538ab0df 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -601,21 +601,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { if let Some(prev) = self.found { if concrete_type.ty != prev.ty && !(concrete_type, prev).references_error() { - // Found different concrete types for the opaque type. - let mut err = self.tcx.sess.struct_span_err( - concrete_type.span, - "concrete type differs from previous defining opaque type use", - ); - err.span_label( - concrete_type.span, - format!("expected `{}`, got `{}`", prev.ty, concrete_type.ty), - ); - if prev.span == concrete_type.span { - err.span_label(prev.span, "this expression supplies two conflicting concrete types for the same opaque type"); - } else { - err.span_note(prev.span, "previous use here"); - } - err.emit(); + prev.report_mismatch(&concrete_type, self.tcx); } } else { self.found = Some(concrete_type);