about summary refs log tree commit diff
path: root/compiler/rustc_infer/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-07-08 21:03:08 -0400
committerMichael Goulet <michael@errs.io>2024-07-15 20:16:12 -0400
commite86fbcfd7048dba4eb9b6461069f476d273a3b64 (patch)
tree8ff912a62e04b9e496bc862fe62ecd7431c0b05d /compiler/rustc_infer/src
parent24d2ac0b56fcbde13d827745f66e73efb1e17156 (diff)
downloadrust-e86fbcfd7048dba4eb9b6461069f476d273a3b64.tar.gz
rust-e86fbcfd7048dba4eb9b6461069f476d273a3b64.zip
Move rustc_infer::infer::error_reporting to rustc_infer::error_reporting::infer
Diffstat (limited to 'compiler/rustc_infer/src')
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/mod.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/mod.rs)45
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/different_lifetimes.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs)11
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/find_anon_type.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs)0
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mod.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs)6
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs)8
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_error.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_relation.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs)9
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/static_impl_trait.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/util.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs)6
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/note.rs421
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/note_and_explain.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs)0
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/region.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/region.rs)2
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/sub_relations.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs)0
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/suggest.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/suggest.rs)2
-rw-r--r--compiler/rustc_infer/src/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs7
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/need_type_info.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs)2
-rw-r--r--compiler/rustc_infer/src/lib.rs1
22 files changed, 479 insertions, 65 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/error_reporting/infer/mod.rs
index bb1285ee813..ddd5818203c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/mod.rs
@@ -45,17 +45,11 @@
 //! ported to this system, and which relies on string concatenation at the
 //! time of error detection.
 
-use super::{InferCtxt, TypeTrace, ValuePairs};
-
-use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
-use crate::infer;
-use crate::infer::ExpectedFound;
-use crate::traits::{
-    IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
-    PredicateObligation,
-};
+use std::borrow::Cow;
+use std::ops::{ControlFlow, Deref};
+use std::path::PathBuf;
+use std::{cmp, fmt, iter};
 
-use crate::infer::relate::{self, RelateResult, TypeRelation};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::{
     pluralize, Applicability, Diag, DiagCtxtHandle, DiagStyledString, IntoDiagArg, StringPart,
@@ -68,6 +62,7 @@ use rustc_hir::{self as hir};
 use rustc_macros::extension;
 use rustc_middle::bug;
 use rustc_middle::dep_graph::DepContext;
+use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::error::TypeErrorToStringExt;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
 use rustc_middle::ty::{
@@ -76,18 +71,21 @@ use rustc_middle::ty::{
 };
 use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
 use rustc_target::spec::abi;
-use std::borrow::Cow;
-use std::ops::{ControlFlow, Deref};
-use std::path::PathBuf;
-use std::{cmp, fmt, iter};
+
+use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
+use crate::infer;
+use crate::infer::relate::{self, RelateResult, TypeRelation};
+use crate::infer::{InferCtxt, TypeTrace, ValuePairs};
+use crate::traits::{
+    IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
+    PredicateObligation,
+};
 
 mod note_and_explain;
 mod suggest;
 
-pub(crate) mod need_type_info;
-pub mod sub_relations;
-pub use need_type_info::TypeAnnotationNeeded;
 pub mod region;
+pub mod sub_relations;
 
 pub mod nice_region_error;
 
@@ -1242,7 +1240,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             Some(values) => {
                 let values = self.resolve_vars_if_possible(values);
                 let (is_simple_error, exp_found) = match values {
-                    ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
+                    ValuePairs::Terms(ExpectedFound { expected, found }) => {
                         match (expected.unpack(), found.unpack()) {
                             (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
                                 let is_simple_err = expected.is_simple_text(self.tcx)
@@ -1254,7 +1252,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
                                 (
                                     is_simple_err,
-                                    Mismatch::Variable(infer::ExpectedFound { expected, found }),
+                                    Mismatch::Variable(ExpectedFound { expected, found }),
                                 )
                             }
                             (ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
@@ -1263,13 +1261,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             _ => (false, Mismatch::Fixed("type")),
                         }
                     }
-                    ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
+                    ValuePairs::PolySigs(ExpectedFound { expected, found }) => {
                         OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
                             .report(diag);
                         (false, Mismatch::Fixed("signature"))
                     }
                     ValuePairs::TraitRefs(_) => (false, Mismatch::Fixed("trait")),
-                    ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
+                    ValuePairs::Aliases(ExpectedFound { expected, .. }) => {
                         (false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
                     }
                     ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
@@ -1303,9 +1301,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
         if let Some((sp, msg)) = secondary_span {
             if swap_secondary_and_primary {
-                let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
-                    expected,
-                    ..
+                let terr = if let Some(infer::ValuePairs::Terms(ExpectedFound {
+                    expected, ..
                 })) = values
                 {
                     Cow::from(format!("expected this to be `{expected}`"))
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/different_lifetimes.rs
index cbeec591960..74dcde03639 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/different_lifetimes.rs
@@ -1,21 +1,20 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where both the regions are anonymous.
 
+use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
+use crate::error_reporting::infer::nice_region_error::util::AnonymousParamInfo;
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::AddLifetimeParamsSuggestion;
 use crate::errors::LifetimeMismatch;
 use crate::errors::LifetimeMismatchLabels;
-use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
-use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::SubregionOrigin;
-use crate::infer::TyCtxt;
 
 use rustc_errors::Subdiagnostic;
 use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::Ty;
-use rustc_middle::ty::Region;
+use rustc_middle::ty::{Region, TyCtxt};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when both the concerned regions are anonymous.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/find_anon_type.rs
index b91b755d683..b91b755d683 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/find_anon_type.rs
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs
index 7996b4bf65b..550cc455e01 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs
@@ -1,12 +1,12 @@
 //! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate
 //! to hold.
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
 use crate::errors::{
     DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag, MismatchedStaticLifetime,
 };
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::ObligationCauseCode;
 use rustc_data_structures::fx::FxIndexSet;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mod.rs
index cffdfa88752..ced4c384f02 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mod.rs
@@ -1,6 +1,6 @@
-use crate::infer::error_reporting::TypeErrCtxt;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError::*;
+use crate::error_reporting::infer::TypeErrCtxt;
+use crate::infer::RegionResolutionError;
+use crate::infer::RegionResolutionError::*;
 use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::{self, TyCtxt};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs
index 85624c9ca73..d1802d2f5ee 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs
@@ -1,11 +1,9 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where one region is named and the other is anonymous.
 
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::{
-    errors::ExplicitLifetimeRequired,
-    infer::error_reporting::nice_region_error::find_anon_type::find_anon_type,
-};
+use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
+use crate::errors::ExplicitLifetimeRequired;
 use rustc_errors::Diag;
 use rustc_middle::ty;
 use rustc_span::symbol::kw;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_error.rs
index 80b7e3b4fa5..476ac3f1720 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_error.rs
@@ -1,9 +1,9 @@
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{
     ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
     TraitPlaceholderMismatch, TyOrSig,
 };
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::ValuePairs;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCause, ObligationCauseCode};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
index a3f306802de..e9f17a3e3e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
@@ -1,9 +1,6 @@
-use crate::{
-    errors::PlaceholderRelationLfNotSatisfied,
-    infer::{
-        error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin,
-    },
-};
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
+use crate::errors::PlaceholderRelationLfNotSatisfied;
+use crate::infer::{RegionResolutionError, SubregionOrigin};
 use rustc_data_structures::intern::Interned;
 use rustc_errors::Diag;
 use rustc_middle::ty::{self, RePlaceholder, Region};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index 9973646aecd..ce157ff3dc8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -1,11 +1,11 @@
 //! Error Reporting for static impl Traits.
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{
     ButCallingIntroduces, ButNeedsToSatisfy, DynTraitConstraintSuggestion, MoreTargeted,
     ReqIntroducedLocations,
 };
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
 use rustc_data_structures::fx::FxIndexSet;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
index 7f3e23716f9..c58c7e13551 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
@@ -1,8 +1,8 @@
 //! Error Reporting for `impl` items that do not match the obligations from their `trait`.
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff};
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::{Subtype, ValuePairs};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/util.rs
index 83145e4f7b2..30fa98c5526 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/util.rs
@@ -1,13 +1,13 @@
 //! Helper functions corresponding to lifetime errors due to
 //! anonymous regions.
 
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::TyCtxt;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
-use rustc_middle::ty::{self, Binder, Region, Ty, TypeFoldable};
+use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
+
 /// Information about the anonymous region we are searching for.
 #[derive(Debug)]
 pub struct AnonymousParamInfo<'tcx> {
diff --git a/compiler/rustc_infer/src/error_reporting/infer/note.rs b/compiler/rustc_infer/src/error_reporting/infer/note.rs
new file mode 100644
index 00000000000..aeb3049c2ae
--- /dev/null
+++ b/compiler/rustc_infer/src/error_reporting/infer/note.rs
@@ -0,0 +1,421 @@
+use crate::error_reporting::infer::{note_and_explain_region, TypeErrCtxt};
+use crate::errors::{
+    note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
+    RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
+};
+use crate::fluent_generated as fluent;
+use crate::infer::{self, SubregionOrigin};
+use rustc_errors::{Diag, Subdiagnostic};
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::traits::ObligationCauseCode;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::{self, IsSuggestable, Region, Ty};
+use rustc_span::symbol::kw;
+
+use super::ObligationCauseAsDiagArg;
+
+impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
+    pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
+        match *origin {
+            infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
+                span: trace.cause.span,
+                requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
+                expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
+            }
+            .add_to_diag(err),
+            infer::Reborrow(span) => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err)
+            }
+            infer::RelateObjectBound(span) => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
+                    .add_to_diag(err);
+            }
+            infer::ReferenceOutlivesReferent(ty, span) => {
+                RegionOriginNote::WithName {
+                    span,
+                    msg: fluent::infer_reference_outlives_referent,
+                    name: &self.ty_to_string(ty),
+                    continues: false,
+                }
+                .add_to_diag(err);
+            }
+            infer::RelateParamBound(span, ty, opt_span) => {
+                RegionOriginNote::WithName {
+                    span,
+                    msg: fluent::infer_relate_param_bound,
+                    name: &self.ty_to_string(ty),
+                    continues: opt_span.is_some(),
+                }
+                .add_to_diag(err);
+                if let Some(span) = opt_span {
+                    RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 }
+                        .add_to_diag(err);
+                }
+            }
+            infer::RelateRegionParamBound(span) => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
+                    .add_to_diag(err);
+            }
+            infer::CompareImplItemObligation { span, .. } => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation }
+                    .add_to_diag(err);
+            }
+            infer::CheckAssociatedTypeBounds { ref parent, .. } => {
+                self.note_region_origin(err, parent);
+            }
+            infer::AscribeUserTypeProvePredicate(span) => {
+                RegionOriginNote::Plain {
+                    span,
+                    msg: fluent::infer_ascribe_user_type_prove_predicate,
+                }
+                .add_to_diag(err);
+            }
+        }
+    }
+
+    pub(super) fn report_concrete_failure(
+        &self,
+        generic_param_scope: LocalDefId,
+        origin: SubregionOrigin<'tcx>,
+        sub: Region<'tcx>,
+        sup: Region<'tcx>,
+    ) -> Diag<'a> {
+        let mut err = match origin {
+            infer::Subtype(box trace) => {
+                let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
+                let mut err = self.report_and_explain_type_error(trace, terr);
+                match (*sub, *sup) {
+                    (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
+                    (ty::RePlaceholder(_), _) => {
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "",
+                            sup,
+                            " doesn't meet the lifetime requirements",
+                            None,
+                        );
+                    }
+                    (_, ty::RePlaceholder(_)) => {
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "the required lifetime does not necessarily outlive ",
+                            sub,
+                            "",
+                            None,
+                        );
+                    }
+                    _ => {
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "",
+                            sup,
+                            "...",
+                            None,
+                        );
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "...does not necessarily outlive ",
+                            sub,
+                            "",
+                            None,
+                        );
+                    }
+                }
+                err
+            }
+            infer::Reborrow(span) => {
+                let reference_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::RefValidFor,
+                    note_and_explain::SuffixKind::Continues,
+                );
+                let content_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::ContentValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(OutlivesContent {
+                    span,
+                    notes: reference_valid.into_iter().chain(content_valid).collect(),
+                })
+            }
+            infer::RelateObjectBound(span) => {
+                let object_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::TypeObjValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let pointer_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::SourcePointerValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(OutlivesBound {
+                    span,
+                    notes: object_valid.into_iter().chain(pointer_valid).collect(),
+                })
+            }
+            infer::RelateParamBound(span, ty, opt_span) => {
+                let prefix = match *sub {
+                    ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
+                    _ => note_and_explain::PrefixKind::TypeOutlive,
+                };
+                let suffix = if opt_span.is_some() {
+                    note_and_explain::SuffixKind::ReqByBinding
+                } else {
+                    note_and_explain::SuffixKind::Empty
+                };
+                let note = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    opt_span,
+                    prefix,
+                    suffix,
+                );
+                self.dcx().create_err(FulfillReqLifetime {
+                    span,
+                    ty: self.resolve_vars_if_possible(ty),
+                    note,
+                })
+            }
+            infer::RelateRegionParamBound(span) => {
+                let param_instantiated = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::LfParamInstantiatedWith,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let param_must_outlive = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::LfParamMustOutlive,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(LfBoundNotSatisfied {
+                    span,
+                    notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
+                })
+            }
+            infer::ReferenceOutlivesReferent(ty, span) => {
+                let pointer_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::PointerValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let data_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::DataValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(RefLongerThanData {
+                    span,
+                    ty: self.resolve_vars_if_possible(ty),
+                    notes: pointer_valid.into_iter().chain(data_valid).collect(),
+                })
+            }
+            infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
+                let mut err = self.infcx.report_extra_impl_obligation(
+                    span,
+                    impl_item_def_id,
+                    trait_item_def_id,
+                    &format!("`{sup}: {sub}`"),
+                );
+                // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
+                if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id)
+                    && generics.where_clause_span.contains(span)
+                {
+                    self.suggest_copy_trait_method_bounds(
+                        trait_item_def_id,
+                        impl_item_def_id,
+                        &mut err,
+                    );
+                }
+                err
+            }
+            infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
+                let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
+
+                // Don't mention the item name if it's an RPITIT, since that'll just confuse
+                // folks.
+                if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
+                    let trait_item_span = self.tcx.def_span(trait_item_def_id);
+                    let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
+                    err.span_label(
+                        trait_item_span,
+                        format!("definition of `{item_name}` from trait"),
+                    );
+                }
+
+                self.suggest_copy_trait_method_bounds(
+                    trait_item_def_id,
+                    impl_item_def_id,
+                    &mut err,
+                );
+                err
+            }
+            infer::AscribeUserTypeProvePredicate(span) => {
+                let instantiated = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::LfInstantiatedWith,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let must_outlive = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::LfMustOutlive,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(LfBoundNotSatisfied {
+                    span,
+                    notes: instantiated.into_iter().chain(must_outlive).collect(),
+                })
+            }
+        };
+        if sub.is_error() || sup.is_error() {
+            err.downgrade_to_delayed_bug();
+        }
+        err
+    }
+
+    pub fn suggest_copy_trait_method_bounds(
+        &self,
+        trait_item_def_id: DefId,
+        impl_item_def_id: LocalDefId,
+        err: &mut Diag<'_>,
+    ) {
+        // FIXME(compiler-errors): Right now this is only being used for region
+        // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
+        // but right now it's not really very smart when it comes to implicit `Sized`
+        // predicates and bounds on the trait itself.
+
+        let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
+        else {
+            return;
+        };
+        let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
+            return;
+        };
+        let trait_args = trait_ref
+            .instantiate_identity()
+            // Replace the explicit self type with `Self` for better suggestion rendering
+            .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
+            .args;
+        let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
+            .rebase_onto(self.tcx, impl_def_id, trait_args);
+
+        let Ok(trait_predicates) =
+            self.tcx
+                .explicit_predicates_of(trait_item_def_id)
+                .instantiate_own(self.tcx, trait_item_args)
+                .map(|(pred, _)| {
+                    if pred.is_suggestable(self.tcx, false) {
+                        Ok(pred.to_string())
+                    } else {
+                        Err(())
+                    }
+                })
+                .collect::<Result<Vec<_>, ()>>()
+        else {
+            return;
+        };
+
+        let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else {
+            return;
+        };
+
+        let suggestion = if trait_predicates.is_empty() {
+            WhereClauseSuggestions::Remove { span: generics.where_clause_span }
+        } else {
+            let space = if generics.where_clause_span.is_empty() { " " } else { "" };
+            WhereClauseSuggestions::CopyPredicates {
+                span: generics.where_clause_span,
+                space,
+                trait_predicates: trait_predicates.join(", "),
+            }
+        };
+        err.subdiagnostic(suggestion);
+    }
+
+    pub(super) fn report_placeholder_failure(
+        &self,
+        generic_param_scope: LocalDefId,
+        placeholder_origin: SubregionOrigin<'tcx>,
+        sub: Region<'tcx>,
+        sup: Region<'tcx>,
+    ) -> Diag<'a> {
+        // I can't think how to do better than this right now. -nikomatsakis
+        debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
+        match placeholder_origin {
+            infer::Subtype(box ref trace)
+                if matches!(
+                    &trace.cause.code().peel_derives(),
+                    ObligationCauseCode::WhereClause(..)
+                        | ObligationCauseCode::WhereClauseInExpr(..)
+                ) =>
+            {
+                // Hack to get around the borrow checker because trace.cause has an `Rc`.
+                if let ObligationCauseCode::WhereClause(_, span)
+                | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
+                    &trace.cause.code().peel_derives()
+                    && !span.is_dummy()
+                {
+                    let span = *span;
+                    self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
+                        .with_span_note(span, "the lifetime requirement is introduced here")
+                } else {
+                    unreachable!(
+                        "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
+                    )
+                }
+            }
+            infer::Subtype(box trace) => {
+                let terr = TypeError::RegionsPlaceholderMismatch;
+                return self.report_and_explain_type_error(trace, terr);
+            }
+            _ => {
+                return self.report_concrete_failure(
+                    generic_param_scope,
+                    placeholder_origin,
+                    sub,
+                    sup,
+                );
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/error_reporting/infer/note_and_explain.rs
index d5e7de897d0..d5e7de897d0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/note_and_explain.rs
diff --git a/compiler/rustc_infer/src/infer/error_reporting/region.rs b/compiler/rustc_infer/src/error_reporting/infer/region.rs
index 191cb23184d..093d2d3d743 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/region.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/region.rs
@@ -18,12 +18,12 @@ use rustc_type_ir::Upcast as _;
 
 use super::nice_region_error::find_anon_type;
 use super::{nice_region_error, ObligationCauseAsDiagArg};
+use crate::error_reporting::infer::{ObligationCauseExt as _, TypeErrCtxt};
 use crate::errors::{
     self, note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound,
     OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
 };
 use crate::fluent_generated as fluent;
-use crate::infer::error_reporting::{ObligationCauseExt as _, TypeErrCtxt};
 use crate::infer::region_constraints::GenericKind;
 use crate::infer::{self, InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin};
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs b/compiler/rustc_infer/src/error_reporting/infer/sub_relations.rs
index ef26a8ff7b8..ef26a8ff7b8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/sub_relations.rs
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/error_reporting/infer/suggest.rs
index 13b145296a7..4d11ab9fac6 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/suggest.rs
@@ -1,4 +1,4 @@
-use crate::infer::error_reporting::hir::Path;
+use crate::error_reporting::infer::hir::Path;
 use core::ops::ControlFlow;
 use hir::def::CtorKind;
 use hir::intravisit::{walk_expr, walk_stmt, Visitor};
diff --git a/compiler/rustc_infer/src/error_reporting/mod.rs b/compiler/rustc_infer/src/error_reporting/mod.rs
new file mode 100644
index 00000000000..132485ec661
--- /dev/null
+++ b/compiler/rustc_infer/src/error_reporting/mod.rs
@@ -0,0 +1 @@
+pub mod infer;
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index ce1b0f86d03..f849a1a7322 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -15,11 +15,10 @@ use rustc_span::symbol::kw;
 use rustc_span::Symbol;
 use rustc_span::{symbol::Ident, BytePos, Span};
 
+use crate::error_reporting::infer::nice_region_error::placeholder_error::Highlighted;
+use crate::error_reporting::infer::ObligationCauseAsDiagArg;
 use crate::fluent_generated as fluent;
-use crate::infer::error_reporting::{
-    need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
-    ObligationCauseAsDiagArg,
-};
+use crate::infer::need_type_info::UnderspecifiedArgKind;
 
 use std::path::PathBuf;
 
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index 4fbeb0ec102..d71b7f3c264 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -1,5 +1,5 @@
+use crate::error_reporting::infer::nice_region_error::find_anon_type;
 use crate::fluent_generated as fluent;
-use crate::infer::error_reporting::nice_region_error::find_anon_type;
 use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::bug;
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index a0be545d46f..cfef1f13015 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -11,9 +11,9 @@ pub use BoundRegionConversionTime::*;
 pub use RegionVariableOrigin::*;
 pub use SubregionOrigin::*;
 
+use crate::error_reporting::infer::TypeErrCtxt;
 use crate::infer::relate::RelateResult;
 use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
-use error_reporting::TypeErrCtxt;
 use free_regions::RegionRelations;
 use lexical_region_resolve::LexicalRegionResolutions;
 use opaque_types::OpaqueTypeStorage;
@@ -54,7 +54,6 @@ use type_variable::TypeVariableOrigin;
 pub mod at;
 pub mod canonical;
 mod context;
-pub mod error_reporting;
 pub mod free_regions;
 mod freshen;
 mod lexical_region_resolve;
@@ -66,6 +65,8 @@ pub mod relate;
 pub mod resolve;
 pub(crate) mod snapshot;
 pub mod type_variable;
+// FIXME(error_reporting): Where should we put this?
+pub mod need_type_info;
 
 #[must_use]
 #[derive(Debug)]
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/need_type_info.rs
index 084aebc296f..4f3dcd9043f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/need_type_info.rs
@@ -1,8 +1,8 @@
+use crate::error_reporting::infer::TypeErrCtxt;
 use crate::errors::{
     AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
     SourceKindMultiSuggestion, SourceKindSubdiag,
 };
-use crate::infer::error_reporting::TypeErrCtxt;
 use crate::infer::InferCtxt;
 use rustc_errors::{codes::*, Diag, IntoDiagArg};
 use rustc_hir as hir;
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index b65ac859667..02ebf933f53 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -34,6 +34,7 @@
 #[macro_use]
 extern crate tracing;
 
+pub mod error_reporting;
 mod errors;
 pub mod infer;
 pub mod traits;