about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-12 07:40:32 +0000
committerbors <bors@rust-lang.org>2023-01-12 07:40:32 +0000
commit2b8590ef3bd1221830ec8a4131ea9d02b1636746 (patch)
tree7c99d064572f9d620f1e5d51db183bad0b785991 /compiler
parent4887cb18dc2ef5b1bf3fc50ce6c267fde085032b (diff)
parente8ef83e4c060ec66a8dbb3d729af67ffd34f6a92 (diff)
Auto merge of #106757 - matthiaskrgr:rollup-9j8830g, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #106167 (Fix invalid syntax and incomplete suggestion in impl Trait parameter type suggestions for E0311)
 - #106309 (Prefer non-`[type error]` candidates during selection)
 - #106532 (Allow codegen to unsize `dyn*` to `dyn`)
 - #106596 (Hide more of long types in E0271)
 - #106638 (std tests: use __OsLocalKeyInner from realstd)
 - #106676 (Test that we cannot use trait impl methods arguments as defining uses)
 - #106702 (Conserve cause of `ImplDerivedObligation` in E0599)
 - #106732 (rustc_llvm: replace llvm::makeArrayRef with ArrayRef constructors.)
 - #106733 (Revert "warn newer available version of the x tool")
 - #106748 (Clean up `OnUnimplementedFormatString::verify`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs73
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs94
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp11
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp14
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs18
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs29
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs61
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs24
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs3
14 files changed, 250 insertions, 108 deletions
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index d318c15d342..f7312f6fcda 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -153,9 +153,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         (
             &ty::Dynamic(ref data_a, _, src_dyn_kind),
             &ty::Dynamic(ref data_b, _, target_dyn_kind),
-        ) => {
-            assert_eq!(src_dyn_kind, target_dyn_kind);
-
+        ) if src_dyn_kind == target_dyn_kind => {
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
             if data_a.principal_def_id() == data_b.principal_def_id() {
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 5d8383170f0..63067deb7b0 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1556,7 +1556,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
                     // Convert the bounds into obligations.
                     let impl_obligations = traits::predicates_for_generics(
-                        |_, _| cause.clone(),
+                        |_idx, span| {
+                            let misc = traits::ObligationCause::misc(span, self.body_id);
+                            let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate {
+                                trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs),
+                                constness: ty::BoundConstness::NotConst,
+                                polarity: ty::ImplPolarity::Positive,
+                            });
+                            misc.derived_cause(parent_trait_pred, |derived| {
+                                traits::ImplDerivedObligation(Box::new(
+                                    traits::ImplDerivedObligationCause {
+                                        derived,
+                                        impl_def_id,
+                                        span,
+                                    },
+                                ))
+                            })
+                        },
                         self.param_env,
                         impl_bounds,
                     );
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 62e80659486..8166eb82990 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -101,6 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
     }
 
+    #[instrument(level = "debug", skip(self))]
     pub fn report_method_error(
         &self,
         span: Span,
@@ -586,22 +587,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // Find all the requirements that come from a local `impl` block.
             let mut skip_list: FxHashSet<_> = Default::default();
-            let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
-            for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates
+            let mut spanned_predicates = FxHashMap::default();
+            for (p, parent_p, impl_def_id, cause) in unsatisfied_predicates
                 .iter()
                 .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
                 .filter_map(|(p, parent, c)| match c.code() {
-                    ObligationCauseCode::ImplDerivedObligation(data) => {
-                        Some((&data.derived, p, parent, data.impl_def_id, data))
+                    ObligationCauseCode::ImplDerivedObligation(data)
+                        if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) =>
+                    {
+                        Some((p, parent, data.impl_def_id, data))
                     }
                     _ => None,
                 })
             {
-                let parent_trait_ref = data.parent_trait_pred;
-                let path = parent_trait_ref.print_modifiers_and_trait_path();
-                let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
-                let unsatisfied_msg = "unsatisfied trait bound introduced here";
-                let derive_msg = "unsatisfied trait bound introduced in this `derive` macro";
                 match self.tcx.hir().get_if_local(impl_def_id) {
                     // Unmet obligation comes from a `derive` macro, point at it once to
                     // avoid multiple span labels pointing at the same place.
@@ -617,10 +615,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ) =>
                     {
                         let span = self_ty.span.ctxt().outer_expn_data().call_site;
-                        let mut spans: MultiSpan = span.into();
-                        spans.push_span_label(span, derive_msg);
-                        let entry = spanned_predicates.entry(spans);
-                        entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
+                        let entry = spanned_predicates.entry(span);
+                        let entry = entry.or_insert_with(|| {
+                            (FxHashSet::default(), FxHashSet::default(), Vec::new())
+                        });
+                        entry.0.insert(span);
+                        entry.1.insert((
+                            span,
+                            "unsatisfied trait bound introduced in this `derive` macro",
+                        ));
+                        entry.2.push(p);
+                        skip_list.insert(p);
                     }
 
                     // Unmet obligation coming from an `impl`.
@@ -647,8 +652,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 };
                                 err.span_suggestion_verbose(
                                     sp,
-                                    "consider relaxing the type parameter's implicit \
-                                     `Sized` bound",
+                                    "consider relaxing the type parameter's implicit `Sized` bound",
                                     sugg,
                                     Applicability::MachineApplicable,
                                 );
@@ -659,25 +663,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             let _ = format_pred(*pred);
                         }
                         skip_list.insert(p);
-                        let mut spans = if cause.span != *item_span {
-                            let mut spans: MultiSpan = cause.span.into();
-                            spans.push_span_label(cause.span, unsatisfied_msg);
-                            spans
+                        let entry = spanned_predicates.entry(self_ty.span);
+                        let entry = entry.or_insert_with(|| {
+                            (FxHashSet::default(), FxHashSet::default(), Vec::new())
+                        });
+                        entry.2.push(p);
+                        if cause.span != *item_span {
+                            entry.0.insert(cause.span);
+                            entry.1.insert((cause.span, "unsatisfied trait bound introduced here"));
                         } else {
-                            let mut spans = Vec::with_capacity(2);
                             if let Some(trait_ref) = of_trait {
-                                spans.push(trait_ref.path.span);
+                                entry.0.insert(trait_ref.path.span);
                             }
-                            spans.push(self_ty.span);
-                            spans.into()
+                            entry.0.insert(self_ty.span);
                         };
                         if let Some(trait_ref) = of_trait {
-                            spans.push_span_label(trait_ref.path.span, "");
+                            entry.1.insert((trait_ref.path.span, ""));
                         }
-                        spans.push_span_label(self_ty.span, "");
-
-                        let entry = spanned_predicates.entry(spans);
-                        entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
+                        entry.1.insert((self_ty.span, ""));
                     }
                     Some(Node::Item(hir::Item {
                         kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..),
@@ -694,11 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
-            spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
-            for (span, (_path, _self_ty, preds)) in spanned_predicates {
-                let mut preds: Vec<_> = preds
-                    .into_iter()
-                    .filter_map(|pred| format_pred(*pred))
+            spanned_predicates.sort_by_key(|(span, _)| *span);
+            for (_, (primary_spans, span_labels, predicates)) in spanned_predicates {
+                let mut preds: Vec<_> = predicates
+                    .iter()
+                    .filter_map(|pred| format_pred(**pred))
                     .map(|(p, _)| format!("`{}`", p))
                     .collect();
                 preds.sort();
@@ -708,6 +711,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 } else {
                     format!("the following trait bounds were not satisfied:\n{}", preds.join("\n"),)
                 };
+                let mut span: MultiSpan = primary_spans.into_iter().collect::<Vec<_>>().into();
+                for (sp, label) in span_labels {
+                    span.push_span_label(sp, label);
+                }
                 err.span_note(span, &msg);
                 unsatisfied_bounds = true;
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 66db1a2f928..9747f360eca 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2144,18 +2144,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         // suggest adding an explicit lifetime bound to it.
         let generics = self.tcx.generics_of(generic_param_scope);
         // type_param_span is (span, has_bounds)
+        let mut is_synthetic = false;
+        let mut ast_generics = None;
         let type_param_span = match bound_kind {
             GenericKind::Param(ref param) => {
                 // Account for the case where `param` corresponds to `Self`,
                 // which doesn't have the expected type argument.
                 if !(generics.has_self && param.index == 0) {
                     let type_param = generics.type_param(param, self.tcx);
+                    is_synthetic = type_param.kind.is_synthetic();
                     type_param.def_id.as_local().map(|def_id| {
                         // Get the `hir::Param` to verify whether it already has any bounds.
                         // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                         // instead we suggest `T: 'a + 'b` in that case.
                         let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
-                        let ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
+                        ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
                         let bounds =
                             ast_generics.and_then(|g| g.bounds_span_for_suggestions(def_id));
                         // `sp` only covers `T`, change it so that it covers
@@ -2187,11 +2190,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 .unwrap_or("'lt".to_string())
         };
 
-        let add_lt_sugg = generics
-            .params
-            .first()
-            .and_then(|param| param.def_id.as_local())
-            .map(|def_id| (self.tcx.def_span(def_id).shrink_to_lo(), format!("{}, ", new_lt)));
+        let mut add_lt_suggs: Vec<Option<_>> = vec![];
+        if is_synthetic {
+            if let Some(ast_generics) = ast_generics {
+                let named_lifetime_param_exist = ast_generics.params.iter().any(|p| {
+                    matches!(
+                        p.kind,
+                        hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
+                    )
+                });
+                if named_lifetime_param_exist && let [param, ..] = ast_generics.params
+                {
+                    add_lt_suggs.push(Some((
+                        self.tcx.def_span(param.def_id).shrink_to_lo(),
+                        format!("{new_lt}, "),
+                    )));
+                } else {
+                    add_lt_suggs
+                        .push(Some((ast_generics.span.shrink_to_hi(), format!("<{new_lt}>"))));
+                }
+            }
+        } else {
+            if let [param, ..] = &generics.params[..] && let Some(def_id) = param.def_id.as_local()
+            {
+                add_lt_suggs
+                    .push(Some((self.tcx.def_span(def_id).shrink_to_lo(), format!("{new_lt}, "))));
+            }
+        }
+
+        if let Some(ast_generics) = ast_generics {
+            for p in ast_generics.params {
+                if p.is_elided_lifetime() {
+                    if self
+                        .tcx
+                        .sess
+                        .source_map()
+                        .span_to_prev_source(p.span.shrink_to_hi())
+                        .ok()
+                        .map_or(false, |s| *s.as_bytes().last().unwrap() == b'&')
+                    {
+                        add_lt_suggs
+                            .push(Some(
+                                (
+                                    p.span.shrink_to_hi(),
+                                    if let Ok(snip) = self.tcx.sess.source_map().span_to_next_source(p.span)
+                                        && snip.starts_with(' ')
+                                    {
+                                        format!("{new_lt}")
+                                    } else {
+                                        format!("{new_lt} ")
+                                    }
+                                )
+                            ));
+                    } else {
+                        add_lt_suggs.push(Some((p.span.shrink_to_hi(), format!("<{new_lt}>"))));
+                    }
+                }
+            }
+        }
 
         let labeled_user_string = match bound_kind {
             GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
@@ -2215,20 +2271,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             );
         }
 
-        fn binding_suggestion<S: fmt::Display>(
+        fn binding_suggestion<'tcx, S: fmt::Display>(
             err: &mut Diagnostic,
             type_param_span: Option<(Span, bool)>,
-            bound_kind: GenericKind<'_>,
+            bound_kind: GenericKind<'tcx>,
             sub: S,
-            add_lt_sugg: Option<(Span, String)>,
+            add_lt_suggs: Vec<Option<(Span, String)>>,
         ) {
             let msg = "consider adding an explicit lifetime bound";
             if let Some((sp, has_lifetimes)) = type_param_span {
                 let suggestion =
                     if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
                 let mut suggestions = vec![(sp, suggestion)];
-                if let Some(add_lt_sugg) = add_lt_sugg {
-                    suggestions.push(add_lt_sugg);
+                for add_lt_sugg in add_lt_suggs {
+                    if let Some(add_lt_sugg) = add_lt_sugg {
+                        suggestions.push(add_lt_sugg);
+                    }
                 }
                 err.multipart_suggestion_verbose(
                     format!("{msg}..."),
@@ -2252,9 +2310,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     };
                     let mut sugg =
                         vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
-                    if let Some(lt) = add_lt_sugg.clone() {
-                        sugg.push(lt);
-                        sugg.rotate_right(1);
+                    for add_lt_sugg in add_lt_suggs.clone() {
+                        if let Some(lt) = add_lt_sugg {
+                            sugg.push(lt);
+                            sugg.rotate_right(1);
+                        }
                     }
                     // `MaybeIncorrect` due to issue #41966.
                     err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
@@ -2358,7 +2418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 // for the bound is not suitable for suggestions when `-Zverbose` is set because it
                 // uses `Debug` output, so we handle it specially here so that suggestions are
                 // always correct.
-                binding_suggestion(&mut err, type_param_span, bound_kind, name, None);
+                binding_suggestion(&mut err, type_param_span, bound_kind, name, vec![]);
                 err
             }
 
@@ -2371,7 +2431,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     "{} may not live long enough",
                     labeled_user_string
                 );
-                binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None);
+                binding_suggestion(&mut err, type_param_span, bound_kind, "'static", vec![]);
                 err
             }
 
@@ -2410,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                                 type_param_span,
                                 bound_kind,
                                 new_lt,
-                                add_lt_sugg,
+                                add_lt_suggs,
                             );
                         }
                     }
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 7da6ab71309..03e6d2149e9 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -28,8 +28,8 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
   for (size_t i = 0; i < FilenamesLen; i++) {
     FilenameRefs.push_back(std::string(Filenames[i]));
   }
-  auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter(
-    makeArrayRef(FilenameRefs));
+  auto FilenamesWriter =
+      coverage::CoverageFilenamesSectionWriter(ArrayRef<std::string>(FilenameRefs));
   RawRustStringOstream OS(BufferOut);
   FilenamesWriter.write(OS);
 }
@@ -45,15 +45,16 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
   // Convert from FFI representation to LLVM representation.
   SmallVector<coverage::CounterMappingRegion, 0> MappingRegions;
   MappingRegions.reserve(NumMappingRegions);
-  for (const auto &Region : makeArrayRef(RustMappingRegions, NumMappingRegions)) {
+  for (const auto &Region : ArrayRef<LLVMRustCounterMappingRegion>(
+           RustMappingRegions, NumMappingRegions)) {
     MappingRegions.emplace_back(
         Region.Count, Region.FalseCount, Region.FileID, Region.ExpandedFileID,
         Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
         Region.Kind);
   }
   auto CoverageMappingWriter = coverage::CoverageMappingWriter(
-      makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
-      makeArrayRef(Expressions, NumExpressions),
+      ArrayRef<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
+      ArrayRef<coverage::CounterExpression>(Expressions, NumExpressions),
       MappingRegions);
   RawRustStringOstream OS(BufferOut);
   CoverageMappingWriter.write(OS);
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 279b6991854..8f94e8a4ab2 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -257,7 +257,7 @@ template<typename T> static inline void AddAttributes(T *t, unsigned Index,
   PALNew = PAL.addAttributes(t->getContext(), Index, B);
 #else
   AttrBuilder B(t->getContext());
-  for (LLVMAttributeRef Attr : makeArrayRef(Attrs, AttrsLen))
+  for (LLVMAttributeRef Attr : ArrayRef<LLVMAttributeRef>(Attrs, AttrsLen))
     B.addAttribute(unwrap(Attr));
   PALNew = PAL.addAttributesAtIndex(t->getContext(), Index, B);
 #endif
@@ -1064,7 +1064,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
     const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) {
   return wrap(Builder->createEnumerator(StringRef(Name, NameLen),
-      APSInt(APInt(SizeInBits, makeArrayRef(Value, 2)), IsUnsigned)));
+      APSInt(APInt(SizeInBits, ArrayRef<uint64_t>(Value, 2)), IsUnsigned)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
@@ -1477,7 +1477,7 @@ extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
                                                            LLVMValueRef *Inputs,
                                                            unsigned NumInputs) {
-  return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
+  return new OperandBundleDef(Name, ArrayRef<Value*>(unwrap(Inputs), NumInputs));
 }
 
 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
@@ -1491,8 +1491,8 @@ extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVM
   Value *Callee = unwrap(Fn);
   FunctionType *FTy = unwrap<FunctionType>(Ty);
   return wrap(unwrap(B)->CreateCall(
-      FTy, Callee, makeArrayRef(unwrap(Args), NumArgs),
-      makeArrayRef(*OpBundles, NumOpBundles)));
+      FTy, Callee, ArrayRef<Value*>(unwrap(Args), NumArgs),
+      ArrayRef<OperandBundleDef>(*OpBundles, NumOpBundles)));
 }
 
 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
@@ -1537,8 +1537,8 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
   Value *Callee = unwrap(Fn);
   FunctionType *FTy = unwrap<FunctionType>(Ty);
   return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
-                                      makeArrayRef(unwrap(Args), NumArgs),
-                                      makeArrayRef(*OpBundles, NumOpBundles),
+                                      ArrayRef<Value*>(unwrap(Args), NumArgs),
+                                      ArrayRef<OperandBundleDef>(*OpBundles, NumOpBundles),
                                       Name));
 }
 
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index cd147d7e558..b9c5a4e0d0d 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -89,7 +89,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
                 Err(TypeError::Sorts(relate::expected_found(self, a, b)))
             }
 
-            (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()),
+            (&ty::Error(guar), _) | (_, &ty::Error(guar)) => {
+                Ok(self.tcx().ty_error_with_guaranteed(guar))
+            }
 
             _ => relate::super_relate_tys(self, a, b),
         }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index c49e75d68ad..a91e8de5f21 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -283,6 +283,8 @@ pub trait PrettyPrinter<'tcx>:
     /// This is typically the case for all non-`'_` regions.
     fn should_print_region(&self, region: ty::Region<'tcx>) -> bool;
 
+    fn reset_type_limit(&mut self) {}
+
     // Defaults (should not be overridden):
 
     /// If possible, this returns a global path resolving to `def_id` that is visible
@@ -1981,6 +1983,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         self.0.ty_infer_name_resolver.as_ref().and_then(|func| func(id))
     }
 
+    fn reset_type_limit(&mut self) {
+        self.printed_type_count = 0;
+    }
+
     fn const_infer_name(&self, id: ty::ConstVid<'tcx>) -> Option<Symbol> {
         self.0.const_infer_name_resolver.as_ref().and_then(|func| func(id))
     }
@@ -2722,11 +2728,15 @@ define_print_and_forward_display! {
     }
 
     ty::SubtypePredicate<'tcx> {
-        p!(print(self.a), " <: ", print(self.b))
+        p!(print(self.a), " <: ");
+        cx.reset_type_limit();
+        p!(print(self.b))
     }
 
     ty::CoercePredicate<'tcx> {
-        p!(print(self.a), " -> ", print(self.b))
+        p!(print(self.a), " -> ");
+        cx.reset_type_limit();
+        p!(print(self.b))
     }
 
     ty::TraitPredicate<'tcx> {
@@ -2738,7 +2748,9 @@ define_print_and_forward_display! {
     }
 
     ty::ProjectionPredicate<'tcx> {
-        p!(print(self.projection_ty), " == ", print(self.term))
+        p!(print(self.projection_ty), " == ");
+        cx.reset_type_limit();
+        p!(print(self.term))
     }
 
     ty::Term<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 4d34ca3d66b..65fd8d9753d 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -414,7 +414,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             bug!("bound types encountered in super_relate_tys")
         }
 
-        (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(tcx.ty_error()),
+        (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error_with_guaranteed(guar)),
 
         (&ty::Never, _)
         | (&ty::Char, _)
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 5f06c4d8282..20bede22c34 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1724,7 +1724,19 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 .and_then(|(predicate, _, normalized_term, expected_term)| {
                     self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term)
                 })
-                .unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
+                .unwrap_or_else(|| {
+                    with_forced_trimmed_paths!(format!(
+                        "type mismatch resolving `{}`",
+                        self.resolve_vars_if_possible(predicate)
+                            .print(FmtPrinter::new_with_limit(
+                                self.tcx,
+                                Namespace::TypeNS,
+                                rustc_session::Limit(10),
+                            ))
+                            .unwrap()
+                            .into_buffer()
+                    ))
+                });
             let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
 
             let secondary_span = match predicate.kind().skip_binder() {
@@ -1755,7 +1767,20 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 kind: hir::ImplItemKind::Type(ty),
                                 ..
                             }),
-                        ) => Some((ty.span, format!("type mismatch resolving `{}`", predicate))),
+                        ) => Some((
+                            ty.span,
+                            with_forced_trimmed_paths!(format!(
+                                "type mismatch resolving `{}`",
+                                self.resolve_vars_if_possible(predicate)
+                                    .print(FmtPrinter::new_with_limit(
+                                        self.tcx,
+                                        Namespace::TypeNS,
+                                        rustc_session::Limit(5),
+                                    ))
+                                    .unwrap()
+                                    .into_buffer()
+                            )),
+                        )),
                         _ => None,
                     }),
                 _ => None,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index b0a730c8ad1..e599996230f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -37,6 +37,21 @@ pub trait TypeErrCtxtExt<'tcx> {
     ) -> OnUnimplementedNote;
 }
 
+/// The symbols which are always allowed in a format string
+static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
+    kw::SelfUpper,
+    sym::ItemContext,
+    sym::from_method,
+    sym::from_desugaring,
+    sym::direct,
+    sym::cause,
+    sym::integral,
+    sym::integer_,
+    sym::float,
+    sym::_Self,
+    sym::crate_local,
+];
+
 impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     fn impl_similar_to(
         &self,
@@ -543,38 +558,26 @@ impl<'tcx> OnUnimplementedFormatString {
                 Piece::NextArgument(a) => match a.position {
                     Position::ArgumentNamed(s) => {
                         match Symbol::intern(s) {
-                            // `{Self}` is allowed
-                            kw::SelfUpper => (),
                             // `{ThisTraitsName}` is allowed
                             s if s == trait_name => (),
-                            // `{from_method}` is allowed
-                            sym::from_method => (),
-                            // `{from_desugaring}` is allowed
-                            sym::from_desugaring => (),
-                            // `{ItemContext}` is allowed
-                            sym::ItemContext => (),
-                            // `{integral}` and `{integer}` and `{float}` are allowed
-                            sym::integral | sym::integer_ | sym::float => (),
+                            s if ALLOWED_FORMAT_SYMBOLS.contains(&s) => (),
                             // So is `{A}` if A is a type parameter
-                            s => match generics.params.iter().find(|param| param.name == s) {
-                                Some(_) => (),
-                                None => {
-                                    let reported = struct_span_err!(
-                                        tcx.sess,
-                                        span,
-                                        E0230,
-                                        "there is no parameter `{}` on {}",
-                                        s,
-                                        if trait_def_id == item_def_id {
-                                            format!("trait `{}`", trait_name)
-                                        } else {
-                                            "impl".to_string()
-                                        }
-                                    )
-                                    .emit();
-                                    result = Err(reported);
-                                }
-                            },
+                            s if generics.params.iter().any(|param| param.name == s) => (),
+                            s => {
+                                result = Err(struct_span_err!(
+                                    tcx.sess,
+                                    span,
+                                    E0230,
+                                    "there is no parameter `{}` on {}",
+                                    s,
+                                    if trait_def_id == item_def_id {
+                                        format!("trait `{}`", trait_name)
+                                    } else {
+                                        "impl".to_string()
+                                    }
+                                )
+                                .emit());
+                            }
                         }
                     }
                     // `{:1}` and `{}` are not to be used
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 53769742c47..f59a6aa9810 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2622,11 +2622,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
-                err.note(&format!(
-                    "required for the cast from `{}` to the object type `{}`",
-                    self.ty_to_string(concrete_ty),
-                    self.ty_to_string(object_ty)
-                ));
+                let (concrete_ty, concrete_file) =
+                    self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty));
+                let (object_ty, object_file) =
+                    self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty));
+                err.note(&with_forced_trimmed_paths!(format!(
+                    "required for the cast from `{concrete_ty}` to the object type `{object_ty}`",
+                )));
+                if let Some(file) = concrete_file {
+                    err.note(&format!(
+                        "the full name for the casted type has been written to '{}'",
+                        file.display(),
+                    ));
+                }
+                if let Some(file) = object_file {
+                    err.note(&format!(
+                        "the full name for the object type has been written to '{}'",
+                        file.display(),
+                    ));
+                }
             }
             ObligationCauseCode::Coercion { source: _, target } => {
                 err.note(&format!("required by cast to type `{}`", self.ty_to_string(target)));
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c54d901e9b1..170c1673dbd 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -174,7 +174,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             .param_env
             .caller_bounds()
             .iter()
-            .filter_map(|o| o.to_opt_poly_trait_pred());
+            .filter_map(|p| p.to_opt_poly_trait_pred())
+            .filter(|p| !p.references_error());
 
         // Micro-optimization: filter out predicates relating to different traits.
         let matching_bounds =
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3f14491f803..2615e262282 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2377,6 +2377,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
 
         let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
+        if impl_trait_ref.references_error() {
+            return Err(());
+        }
 
         debug!(?impl_trait_ref);