From c005e760f518254af6c47b36ddb16b8fe8aecb6a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 16 Aug 2022 06:27:22 +0000 Subject: [PATCH 01/16] Rework point-at-arg --- .../src/infer/error_reporting/mod.rs | 10 +- .../mismatched_static_lifetime.rs | 3 +- .../nice_region_error/placeholder_error.rs | 5 +- .../nice_region_error/static_impl_trait.rs | 2 +- .../src/infer/error_reporting/note.rs | 4 +- .../src/infer/outlives/obligations.rs | 3 +- compiler/rustc_middle/src/traits/mod.rs | 4 + .../src/traits/error_reporting/mod.rs | 25 +- .../error_reporting/on_unimplemented.rs | 4 +- .../src/traits/error_reporting/suggestions.rs | 10 +- .../rustc_trait_selection/src/traits/mod.rs | 14 +- .../rustc_trait_selection/src/traits/util.rs | 25 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- .../rustc_typeck/src/check/compare_method.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 70 ++-- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 318 ++++++++---------- .../rustc_typeck/src/check/method/confirm.rs | 14 +- compiler/rustc_typeck/src/check/method/mod.rs | 7 +- .../rustc_typeck/src/check/method/probe.rs | 7 +- .../anonymous-higher-ranked-lifetime.stderr | 110 +++--- .../associated-types-eq-3.stderr | 4 +- .../associated-types-path-2.stderr | 10 +- .../issue-67252-unnamed-future.stderr | 10 +- src/test/ui/async-await/issue-68112.stderr | 14 +- src/test/ui/async-await/issue-72442.stderr | 6 +- .../issue-65436-raw-ptr-not-send.stderr | 10 +- .../async-await/pin-needed-to-poll-2.stderr | 6 +- ...ault-trait-impl-constituent-types-2.stderr | 4 +- ...ypeck-default-trait-impl-precedence.stderr | 4 +- src/test/ui/binop/issue-77910-1.stderr | 6 +- src/test/ui/box/into-boxed-slice-fail.stderr | 12 +- .../expect-infer-var-appearing-twice.stderr | 15 +- .../closure-origin-array-diagnostics.stderr | 2 +- .../closure-origin-tuple-diagnostics.stderr | 2 +- src/test/ui/closures/closure-move-sync.stderr | 26 +- .../ui/closures/closure-wrong-kind.stderr | 2 +- .../defaults/trait_objects_fail.stderr | 8 +- .../abstract-const-as-cast-3.stderr | 16 +- ...e-21659-show-relevant-trait-impls-1.stderr | 6 +- ...e-21659-show-relevant-trait-impls-2.stderr | 6 +- src/test/ui/dst/dst-rvalue.stderr | 12 +- src/test/ui/error-codes/E0277-2.stderr | 4 +- src/test/ui/error-codes/E0283.stderr | 21 +- .../ui/extern/extern-types-unsized.stderr | 12 +- .../feature-gate-unsized_fn_params.stderr | 4 +- src/test/ui/fmt/send-sync.stderr | 14 +- .../drop-tracking-parent-expression.stderr | 12 +- src/test/ui/generator/drop-yield-twice.stderr | 12 +- ...erator-yielding-or-returning-itself.stderr | 26 +- src/test/ui/generator/issue-68112.rs | 1 + src/test/ui/generator/issue-68112.stderr | 10 +- src/test/ui/generator/not-send-sync.stderr | 30 +- src/test/ui/generator/partial-drop.stderr | 39 ++- .../print/generator-print-verbose-1.stderr | 10 +- .../print/generator-print-verbose-2.stderr | 30 +- .../bugs/issue-88460.stderr | 6 +- .../issue-62529-3.stderr | 6 +- src/test/ui/inference/issue-71732.stderr | 6 +- src/test/ui/inference/issue-72690.stderr | 36 +- src/test/ui/inference/issue-86162-1.stderr | 2 +- .../interior-mutability.stderr | 10 +- src/test/ui/issues/issue-17651.stderr | 6 +- src/test/ui/issues/issue-20162.stderr | 6 +- src/test/ui/issues/issue-21763.stderr | 4 +- src/test/ui/issues/issue-31173.rs | 2 +- src/test/ui/issues/issue-31173.stderr | 30 +- src/test/ui/issues/issue-33941.stderr | 6 +- src/test/ui/issues/issue-34334.stderr | 6 +- src/test/ui/issues/issue-34349.stderr | 2 +- src/test/ui/issues/issue-59488.rs | 1 + src/test/ui/issues/issue-59488.stderr | 21 +- src/test/ui/issues/issue-60218.stderr | 5 +- ...e-66923-show-error-for-correct-call.stderr | 12 +- src/test/ui/issues/issue-69455.stderr | 7 +- src/test/ui/issues/issue-69683.stderr | 30 +- ...70724-add_type_neq_err_label-unwrap.stderr | 6 +- src/test/ui/iterators/collect-into-array.rs | 1 + .../ui/iterators/collect-into-array.stderr | 6 +- src/test/ui/iterators/collect-into-slice.rs | 5 + .../ui/iterators/collect-into-slice.stderr | 23 +- src/test/ui/iterators/issue-28098.stderr | 34 +- .../ui/kindck/kindck-nonsendable-1.stderr | 10 +- src/test/ui/kindck/kindck-send-object.stderr | 8 +- src/test/ui/kindck/kindck-send-object1.stderr | 8 +- src/test/ui/kindck/kindck-send-object2.stderr | 8 +- src/test/ui/kindck/kindck-send-owned.stderr | 4 +- .../branches.stderr | 6 +- .../recursion4.stderr | 12 +- ...od-ambig-one-trait-unknown-int-type.stderr | 4 +- src/test/ui/mismatched_types/E0631.stderr | 20 +- .../mismatched_types/closure-arg-count.stderr | 20 +- .../closure-arg-type-mismatch.stderr | 30 +- .../ui/mismatched_types/issue-36053-2.stderr | 10 +- .../method-help-unsatisfied-bound.stderr | 6 +- .../defaulted-never-note.fallback.stderr | 6 +- .../ui/never_type/defaulted-never-note.rs | 1 + ...diverging-fallback-no-leak.fallback.stderr | 6 +- .../feature-gate-never_type_fallback.stderr | 9 +- src/test/ui/no-send-res-ports.stderr | 17 +- src/test/ui/not-clone-closure.stderr | 6 +- src/test/ui/not-panic/not-panic-safe-2.stderr | 8 +- src/test/ui/not-panic/not-panic-safe-3.stderr | 8 +- src/test/ui/not-panic/not-panic-safe-4.stderr | 8 +- src/test/ui/not-panic/not-panic-safe-5.stderr | 4 +- src/test/ui/not-panic/not-panic-safe-6.stderr | 8 +- .../ui/on-unimplemented/multiple-impls.stderr | 35 +- src/test/ui/on-unimplemented/on-impl.stderr | 11 +- ...invalid-syntax-in-enum-discriminant.stderr | 4 +- .../move-ref-patterns-closure-captures.stderr | 6 +- .../const-default-method-bodies.stderr | 10 +- .../cross-crate.gatednc.stderr | 10 +- .../cross-crate.stocknc.stderr | 10 +- ...-method-body-is-const-same-trait-ck.stderr | 10 +- src/test/ui/str/str-idx.stderr | 24 +- src/test/ui/str/str-mut-idx.stderr | 24 +- ...-trait-object-literal-bound-regions.stderr | 6 +- .../issue-71394-no-from-impl.stderr | 6 +- .../suggestions/issue-84973-blacklist.stderr | 6 +- src/test/ui/suggestions/issue-84973.stderr | 11 +- .../mut-borrow-needed-by-trait.stderr | 21 +- .../suggest-borrow-to-dyn-object.stderr | 4 +- .../ui/suggestions/suggest-change-mut.stderr | 16 +- .../check-trait-object-bounds-1.stderr | 4 +- .../check-trait-object-bounds-2.stderr | 4 +- .../check-trait-object-bounds-4.stderr | 4 +- .../ui/traits/bad-method-typaram-kind.stderr | 4 +- .../bound/assoc-fn-bound-root-obligation.rs | 1 - .../assoc-fn-bound-root-obligation.stderr | 6 +- ...s-by-name-in-suggestion-issue-96292.stderr | 4 +- .../repeated-supertrait-ambig.stderr | 24 +- src/test/ui/traits/issue-71136.stderr | 8 +- src/test/ui/traits/issue-77982.stderr | 19 +- src/test/ui/traits/issue-97576.stderr | 6 +- .../multidispatch-convert-ambig-dest.stderr | 10 +- ...t-non-existing-fully-qualified-path.stderr | 4 +- .../enforce-supertrait-projection.stderr | 6 +- .../suggest-deferences/issue-39029.fixed | 2 +- .../suggest-deferences/issue-39029.stderr | 12 +- ...ully-qualified-path-with-adjustment.stderr | 36 +- ...y-qualified-path-without-adjustment.stderr | 44 ++- .../ui/traits/suggest-where-clause.stderr | 4 +- src/test/ui/transmutability/references.stderr | 4 +- ...ck-default-trait-impl-negation-sync.stderr | 8 +- .../ui/ufcs/ufcs-qpath-self-mismatch.stderr | 6 +- .../non-tupled-arg-mismatch.stderr | 6 +- ...-infer-fn-once-move-from-projection.stderr | 2 +- .../ui/unsized-locals/unsized-exprs.stderr | 4 +- src/test/ui/unsized/issue-30355.stderr | 4 +- src/test/ui/unsized/issue-71659.stderr | 6 +- src/test/ui/unsized/issue-75707.stderr | 4 +- src/test/ui/unsized/unsized-fn-param.stderr | 16 +- src/test/ui/unsized/unsized-struct.stderr | 4 +- src/test/ui/unsized/unsized3.stderr | 10 +- .../where-clause-method-substituion.stderr | 4 +- .../where-clauses-method-unsatisfied.stderr | 6 +- 155 files changed, 1269 insertions(+), 782 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8fb5f159136be..59ea1f3f9de45 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -740,12 +740,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.help("...or use `match` instead of `let...else`"); } _ => { - if let ObligationCauseCode::BindingObligation(_, binding_span) = - cause.code().peel_derives() + if let ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) + = cause.code().peel_derives() + && let TypeError::RegionsPlaceholderMismatch = terr { - if matches!(terr, TypeError::RegionsPlaceholderMismatch) { - err.span_note(*binding_span, "the lifetime requirement is introduced here"); - } + err.span_note(*span, "the lifetime requirement is introduced here"); } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 893ca3cf79d70..c20b96cae2e4f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -35,7 +35,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { return None; }; - let ObligationCauseCode::BindingObligation(_def_id, binding_span) = *parent.code() else { + let (ObligationCauseCode::BindingObligation(_, binding_span) | ObligationCauseCode::ExprBindingObligation(_, binding_span, ..)) + = *parent.code() else { return None; }; let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type"); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 998699158ff48..d4db0751212f7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -211,7 +211,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { ); let mut err = self.tcx().sess.struct_span_err(span, &msg); - let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = *cause.code() { + let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) + | ObligationCauseCode::ExprItemObligation(def_id, ..) = + *cause.code() + { err.span_label(span, "doesn't satisfy where-clause"); err.span_label( self.tcx().def_span(def_id), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9886c572a8aaf..f804569b0747e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -232,7 +232,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), _ => cause.code(), } - && let (&ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code) + && let (&ObligationCauseCode::ItemObligation(item_def_id) | &ObligationCauseCode::ExprItemObligation(item_def_id, ..), None) = (code, override_error_code) { // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` // lifetime as above, but called using a fully-qualified path to the method: diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 8dabdfd55c7e8..8c465b0876002 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -390,10 +390,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if matches!( &trace.cause.code().peel_derives(), ObligationCauseCode::BindingObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) ) => { // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::BindingObligation(_, span) = + if let ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) = &trace.cause.code().peel_derives() { let span = *span; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index ad052f58ca854..dded0a0a6b1b4 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -97,7 +97,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { cause.span, sup_type, match cause.code().peel_derives() { - ObligationCauseCode::BindingObligation(_, span) => Some(*span), + ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) => Some(*span), _ => None, }, ) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 72b848c3ee2dd..e91878c62fd6c 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -238,9 +238,13 @@ pub enum ObligationCauseCode<'tcx> { /// also implement all supertraits of `X`. ItemObligation(DefId), + ExprItemObligation(DefId, rustc_hir::HirId, usize), + /// Like `ItemObligation`, but with extra detail on the source of the obligation. BindingObligation(DefId, Span), + ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), + /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), 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 1a39a1680384d..ab445afe6d6ea 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1564,6 +1564,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { obligation.cause.code().peel_derives(), ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::BindingObligation(_, _) + | ObligationCauseCode::ExprItemObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) | ObligationCauseCode::ObjectCastObligation(..) | ObligationCauseCode::OpaqueType ); @@ -2091,13 +2093,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { } } - if let ObligationCauseCode::ItemObligation(def_id) = *obligation.cause.code() { + if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); - } else if let ( - Ok(ref snippet), - &ObligationCauseCode::BindingObligation(def_id, _), - ) = - (self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code()) + } else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span) + && let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..) + = *obligation.cause.code() { let generics = self.tcx.generics_of(def_id); if generics.params.iter().any(|p| p.name != kw::SelfUpper) @@ -2520,15 +2520,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ) { - let ( - ty::PredicateKind::Trait(pred), - &ObligationCauseCode::BindingObligation(item_def_id, span), - ) = ( - obligation.predicate.kind().skip_binder(), - obligation.cause.code().peel_derives(), - ) else { - return; - }; + let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; }; + let (ObligationCauseCode::BindingObligation(item_def_id, span) + | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..)) + = *obligation.cause.code().peel_derives() else { return; }; debug!(?pred, ?item_def_id, ?span); let (Some(node), true) = ( 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 e6907637c57b6..6b03555bc6985 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 @@ -143,7 +143,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } if let ObligationCauseCode::ItemObligation(item) - | ObligationCauseCode::BindingObligation(item, _) = *obligation.cause.code() + | ObligationCauseCode::BindingObligation(item, _) + | ObligationCauseCode::ExprItemObligation(item, ..) + | ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code() { // FIXME: maybe also have some way of handling methods // from other traits? That would require name resolution, 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 0d279069694a9..418eae9b0e8d7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1022,7 +1022,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code { try_borrowing(cause.derived.parent_trait_pred, &[]) } else if let ObligationCauseCode::BindingObligation(_, _) - | ObligationCauseCode::ItemObligation(..) = code + | ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) = code { try_borrowing(poly_trait_pred, &never_suggest_borrow) } else { @@ -2244,11 +2246,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { region, object_ty, )); } - ObligationCauseCode::ItemObligation(_item_def_id) => { + ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) => { // We hold the `DefId` of the item introducing the obligation, but displaying it // doesn't add user usable information. It always point at an associated item. } - ObligationCauseCode::BindingObligation(item_def_id, span) => { + ObligationCauseCode::BindingObligation(item_def_id, span) + | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => { let item_name = tcx.def_path_str(item_def_id); let mut multispan = MultiSpan::from(span); if let Some(ident) = tcx.opt_item_ident(item_def_id) { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index b6d6df1eec6a1..85ff6e23711ca 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -117,11 +117,21 @@ pub enum TraitQueryMode { /// Creates predicate obligations from the generic bounds. pub fn predicates_for_generics<'tcx>( - cause: ObligationCause<'tcx>, + cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>, ) -> impl Iterator> { - util::predicates_for_generics(cause, 0, param_env, generic_bounds) + let generic_bounds = generic_bounds; + debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); + + std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map( + move |(idx, (predicate, span))| Obligation { + cause: cause(idx, span), + recursion_depth: 0, + param_env: param_env, + predicate, + }, + ) } /// Determines whether the type `ty` is known to meet `bound` and diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index d25006016629c..0f5dff01c6625 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -11,8 +11,6 @@ use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::{self, util::*}; -use std::iter; - /////////////////////////////////////////////////////////////////////////// // `TraitAliasExpander` iterator /////////////////////////////////////////////////////////////////////////// @@ -210,7 +208,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( let Normalized { value: predicates, obligations: normalization_obligations2 } = super::normalize(selcx, param_env, ObligationCause::dummy(), predicates); let impl_obligations = - predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates); + super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates); let impl_obligations = impl_obligations .chain(normalization_obligations1.into_iter()) @@ -219,27 +217,6 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( (subject, impl_obligations) } -pub fn predicates_for_generics<'tcx>( - cause: ObligationCause<'tcx>, - recursion_depth: usize, - param_env: ty::ParamEnv<'tcx>, - generic_bounds: ty::InstantiatedPredicates<'tcx>, -) -> impl Iterator> { - debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - - iter::zip(generic_bounds.predicates, generic_bounds.spans).map(move |(predicate, span)| { - let cause = match *cause.code() { - traits::ItemObligation(def_id) if !span.is_dummy() => traits::ObligationCause::new( - cause.span, - cause.body_id, - traits::BindingObligation(def_id, span), - ), - _ => cause.clone(), - }; - Obligation { cause, recursion_depth, param_env, predicate } - }) -} - pub fn predicate_for_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 7a5e67ff74b32..4bd179d239131 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -711,7 +711,7 @@ impl<'tcx> WfPredicates<'tcx> { iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) .map(|((mut pred, span), origin_def_id)| { let code = if span.is_dummy() { - traits::MiscObligation + traits::ItemObligation(origin_def_id) } else { traits::BindingObligation(origin_def_id, span) }; diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index ec8d22e81d1c0..64846953aac75 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1463,7 +1463,7 @@ pub fn check_type_bounds<'tcx>( ); let mk_cause = |span: Span| { let code = if span.is_dummy() { - traits::MiscObligation + traits::ItemObligation(trait_ty.def_id) } else { traits::BindingObligation(trait_ty.def_id, span) }; diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 1d9d04ceec0d7..20d25d508d224 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -607,9 +607,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(in super::super) fn select_all_obligations_or_error(&self) { - let errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self); + let mut errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self); if !errors.is_empty() { + self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); self.report_fulfillment_errors(&errors, self.inh.body_id, false); } } @@ -623,6 +624,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self); if !result.is_empty() { mutate_fulfillment_errors(&mut result); + self.adjust_fulfillment_errors_for_expr_obligation(&mut result); self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred); } } @@ -820,23 +822,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = item_ty.subst(self.tcx, substs); self.write_resolution(hir_id, Ok((def_kind, def_id))); - self.add_required_obligations_with_code( - span, - def_id, - &substs, - match lang_item { - hir::LangItem::IntoFutureIntoFuture => { - ObligationCauseCode::AwaitableExpr(expr_hir_id) - } - hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => { - ObligationCauseCode::ForLoopIterator - } - hir::LangItem::TryTraitFromOutput - | hir::LangItem::TryTraitFromResidual - | hir::LangItem::TryTraitBranch => ObligationCauseCode::QuestionMark, - _ => traits::ItemObligation(def_id), - }, - ); + + let code = match lang_item { + hir::LangItem::IntoFutureIntoFuture => { + Some(ObligationCauseCode::AwaitableExpr(expr_hir_id)) + } + hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => { + Some(ObligationCauseCode::ForLoopIterator) + } + hir::LangItem::TryTraitFromOutput + | hir::LangItem::TryTraitFromResidual + | hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark), + _ => None, + }; + if let Some(code) = code { + self.add_required_obligations_with_code(span, def_id, substs, move |_, _| code.clone()); + } else { + self.add_required_obligations_for_hir(span, def_id, substs, hir_id); + } + (Res::Def(def_kind, def_id), ty) } @@ -1348,7 +1352,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // First, store the "user substs" for later. self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty); - self.add_required_obligations(span, def_id, &substs); + self.add_required_obligations_for_hir(span, def_id, &substs, hir_id); // Substitute the values for the type parameters into the type of // the referenced item. @@ -1385,32 +1389,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Add all the obligations that are required, substituting and normalized appropriately. - pub(crate) fn add_required_obligations( + pub(crate) fn add_required_obligations_for_hir( &self, span: Span, def_id: DefId, - substs: &SubstsRef<'tcx>, + substs: SubstsRef<'tcx>, + hir_id: hir::HirId, ) { - self.add_required_obligations_with_code( - span, - def_id, - substs, - traits::ItemObligation(def_id), - ) + self.add_required_obligations_with_code(span, def_id, substs, |idx, span| { + if span.is_dummy() { + ObligationCauseCode::ExprItemObligation(def_id, hir_id, idx) + } else { + ObligationCauseCode::ExprBindingObligation(def_id, span, hir_id, idx) + } + }) } - #[tracing::instrument(level = "debug", skip(self, span, def_id, substs))] + #[tracing::instrument(level = "debug", skip(self, code, span, def_id, substs))] fn add_required_obligations_with_code( &self, span: Span, def_id: DefId, - substs: &SubstsRef<'tcx>, - code: ObligationCauseCode<'tcx>, + substs: SubstsRef<'tcx>, + code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>, ) { let (bounds, _) = self.instantiate_bounds(span, def_id, &substs); for obligation in traits::predicates_for_generics( - traits::ObligationCause::new(span, self.body_id, code), + |idx, predicate_span| { + traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span)) + }, self.param_env, bounds, ) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index aab60de80ef14..1d59840bf0ae9 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -247,17 +247,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Cause selection errors caused by resolving a single argument to point at the // argument and not the call. This lets us customize the span pointed to in the // fulfillment error to be more accurate. - let coerced_ty = - self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| { - self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr); - self.point_at_arg_instead_of_call_if_possible( - errors, - call_expr, - call_span, - provided_args, - &expected_input_tys, - ); - }); + let coerced_ty = self.resolve_vars_with_obligations(coerced_ty); let coerce_error = self .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None) @@ -312,16 +302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // an "opportunistic" trait resolution of any trait bounds on // the call. This helps coercions. if check_closures { - self.select_obligations_where_possible(false, |errors| { - self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr); - self.point_at_arg_instead_of_call_if_possible( - errors, - call_expr, - call_span, - &provided_args, - &expected_input_tys, - ); - }) + self.select_obligations_where_possible(false, |_| {}) } // Check each argument, to satisfy the input it was provided for @@ -1183,7 +1164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_user_type_annotation_from_substs(hir_id, did, substs, None); // Check bounds on type arguments used in the path. - self.add_required_obligations(path_span, did, substs); + self.add_required_obligations_for_hir(path_span, did, substs, hir_id); Some((variant, ty)) } else { @@ -1626,179 +1607,174 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// can be not easily comparable with predicate type (because of coercion). If the types match /// for either checked or coerced type, and there's only *one* argument that does, we point at /// the corresponding argument's expression span instead of the `fn` call path span. - fn point_at_arg_instead_of_call_if_possible( + pub(super) fn adjust_fulfillment_errors_for_expr_obligation( &self, errors: &mut Vec>, - expr: &'tcx hir::Expr<'tcx>, - call_sp: Span, - args: &'tcx [hir::Expr<'tcx>], - expected_tys: &[Ty<'tcx>], ) { - // We *do not* do this for desugared call spans to keep good diagnostics when involving - // the `?` operator. - if call_sp.desugaring_kind().is_some() { - return; + for error in errors { + self.adjust_fulfillment_error_for_expr_obligation(error); } + } - 'outer: for error in errors { - // Only if the cause is somewhere inside the expression we want try to point at arg. - // Otherwise, it means that the cause is somewhere else and we should not change - // anything because we can break the correct span. - if !call_sp.contains(error.obligation.cause.span) { - continue; - } + fn adjust_fulfillment_error_for_expr_obligation( + &self, + error: &mut traits::FulfillmentError<'tcx>, + ) { + let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx)) + = *error.obligation.cause.code().peel_derives() else { return; }; + let Some(unsubstituted_pred) = + self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) else { return; }; + + let generics = self.tcx.generics_of(def_id); + let predicate_substs = match unsubstituted_pred.kind().skip_binder() { + ty::PredicateKind::Trait(pred) => pred.trait_ref.substs, + ty::PredicateKind::Projection(pred) => pred.projection_ty.substs, + _ => ty::List::empty(), + }; + let param_to_point_at = predicate_substs.types().find_map(|ty| { + ty.walk().find_map(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + // Look for a param ty that is local to this method/fn + // and not inherited from an impl, for example. + && self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id + { + Some(arg) + } else { + None + } + }) + }); - // Peel derived obligation, because it's the type that originally - // started this inference chain that matters, not the one we wound - // up with at the end. - fn unpeel_to_top<'a, 'tcx>( - mut code: &'a ObligationCauseCode<'tcx>, - ) -> &'a ObligationCauseCode<'tcx> { - let mut result_code = code; - loop { - let parent = match code { - ObligationCauseCode::ImplDerivedObligation(c) => &c.derived.parent_code, - ObligationCauseCode::BuiltinDerivedObligation(c) - | ObligationCauseCode::DerivedObligation(c) => &c.parent_code, - _ => break result_code, - }; - (result_code, code) = (code, parent); + let fallback_param_to_point_at = predicate_substs.types().find_map(|ty| { + ty.walk().find_map(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + && self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id + { + Some(arg) + } else { + None } - } - let self_: ty::subst::GenericArg<'_> = - match unpeel_to_top(error.obligation.cause.code()) { - ObligationCauseCode::BuiltinDerivedObligation(code) - | ObligationCauseCode::DerivedObligation(code) => { - code.parent_trait_pred.self_ty().skip_binder().into() + }) + }); + + let hir = self.tcx.hir(); + match hir.get(hir_id) { + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(hir::QPath::Resolved(_, path)), hir_id, .. }) => { + if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(callee, args), hir_id: call_hir_id, .. }) + = hir.get(hir.get_parent_node(*hir_id)) + && callee.hir_id == *hir_id + { + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_args_if_possible(error, def_id, param_to_point_at, *call_hir_id, callee.span, args) { + return; } - ObligationCauseCode::ImplDerivedObligation(code) => { - code.derived.parent_trait_pred.self_ty().skip_binder().into() + + if let Some(fallback_param_to_point_at) = fallback_param_to_point_at + && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, *call_hir_id, callee.span, args) + { + return; } - _ => match error.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(predicate) => predicate.self_ty().into(), - ty::PredicateKind::Projection(predicate) => { - predicate.projection_ty.self_ty().into() - } - _ => continue, - }, - }; - let self_ = self.resolve_vars_if_possible(self_); - let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_); - - let typeck_results = self.typeck_results.borrow(); - - for (idx, arg) in args.iter().enumerate() { - // Don't adjust the span if we already have a more precise span - // within one of the args. - if arg.span.contains(error.obligation.cause.span) { - let references_arg = - typeck_results.expr_ty_opt(arg).map_or(false, &ty_matches_self) - || expected_tys.get(idx).copied().map_or(false, &ty_matches_self); - if references_arg && !arg.span.from_expansion() { - error.obligation.cause.map_code(|parent_code| { - ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id: args[idx].hir_id, - call_hir_id: expr.hir_id, - parent_code, - } - }) + + if let Some(param_to_point_at) = param_to_point_at + && let Some(segment) = path.segments.last() + && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) + { + return; } - continue 'outer; } } + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(segment, args, ..), .. }) => { + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_args_if_possible(error, def_id, param_to_point_at, hir_id, segment.ident.span, args) + { + return; + } - // Collect the argument position for all arguments that could have caused this - // `FulfillmentError`. - let mut referenced_in: Vec<_> = std::iter::zip(expected_tys, args) - .enumerate() - .flat_map(|(idx, (expected_ty, arg))| { - if let Some(arg_ty) = typeck_results.expr_ty_opt(arg) { - vec![(idx, arg_ty), (idx, *expected_ty)] - } else { - vec![] - } - }) - .filter_map(|(i, ty)| { - let ty = self.resolve_vars_if_possible(ty); - // We walk the argument type because the argument's type could have - // been `Option`, but the `FulfillmentError` references `T`. - if ty_matches_self(ty) { Some(i) } else { None } - }) - .collect(); - - // Both checked and coerced types could have matched, thus we need to remove - // duplicates. - - // We sort primitive type usize here and can use unstable sort - referenced_in.sort_unstable(); - referenced_in.dedup(); - - if let &[idx] = &referenced_in[..] { - // Do not point at the inside of a macro. - // That would often result in poor error messages. - if args[idx].span.from_expansion() { - continue; + if let Some(fallback_param_to_point_at) = fallback_param_to_point_at + && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, hir_id, segment.ident.span, args) + { + return; } - // We make sure that only *one* argument matches the obligation failure - // and we assign the obligation's span to its expression's. - error.obligation.cause.span = args[idx].span; - error.obligation.cause.map_code(|parent_code| { - ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id: args[idx].hir_id, - call_hir_id: expr.hir_id, - parent_code, - } - }); - } else if error.obligation.cause.span == call_sp { - // Make function calls point at the callee, not the whole thing. - if let hir::ExprKind::Call(callee, _) = expr.kind { - error.obligation.cause.span = callee.span; + + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) + { + return; } } + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(..), .. }) => { + // fixme + } + _ => {} } } - /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the - /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s - /// were caused by them. If they were, we point at the corresponding type argument's span - /// instead of the `fn` call path span. - fn point_at_type_arg_instead_of_call_if_possible( + fn point_at_args_if_possible( &self, - errors: &mut Vec>, - call_expr: &'tcx hir::Expr<'tcx>, - ) { - if let hir::ExprKind::Call(path, _) = &call_expr.kind { - if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind { - for error in errors { - let self_ty = match error.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(predicate) => predicate.self_ty(), - ty::PredicateKind::Projection(predicate) => { - predicate.projection_ty.self_ty() - } - _ => continue, - }; - // If any of the type arguments in this path segment caused the - // `FulfillmentError`, point at its span (#61860). - for arg in path - .segments - .iter() - .filter_map(|seg| seg.args.as_ref()) - .flat_map(|a| a.args.iter()) - { - if let hir::GenericArg::Type(hir_ty) = &arg - && let Some(ty) = - self.typeck_results.borrow().node_type_opt(hir_ty.hir_id) - && self.resolve_vars_if_possible(ty) == self_ty - { - error.obligation.cause.span = hir_ty.span; - break; - } - } + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param_to_point_at: ty::GenericArg<'tcx>, + call_hir_id: hir::HirId, + callee_span: Span, + args: &[hir::Expr<'tcx>], + ) -> bool { + let sig = self.tcx.fn_sig(def_id).skip_binder(); + let args_referencing_param: Vec<_> = sig + .inputs() + .iter() + .enumerate() + .filter(|(_, ty)| ty.walk().any(|arg| arg == param_to_point_at)) + .collect(); + if let [(idx, _)] = args_referencing_param.as_slice() + && let Some(arg) = args.get(*idx) + { + error.obligation.cause.span = arg.span; + error.obligation.cause.map_code(|parent_code| { + ObligationCauseCode::FunctionArgumentObligation { + arg_hir_id: arg.hir_id, + call_hir_id, + parent_code, } - } + }); + true + } else if args_referencing_param.len() > 0 { + // If more than one argument applies, then point to the callee + // We have chance to fix this up further in `point_at_generics_if_possible` + error.obligation.cause.span = callee_span; + false + } else { + false } } + fn point_at_generics_if_possible( + &self, + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param_to_point_at: ty::GenericArg<'tcx>, + segment: &hir::PathSegment<'tcx>, + ) -> bool { + let own_substs = self + .tcx + .generics_of(def_id) + .own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id)); + let Some((index, _)) = own_substs + .iter() + .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_))) + .enumerate() + .find(|(_, arg)| **arg == param_to_point_at) else { return false }; + let Some(arg) = segment + .args() + .args + .iter() + .filter(|arg| matches!(arg, hir::GenericArg::Type(_))) + .nth(index) else { return false; }; + error.obligation.cause.span = arg.span(); + true + } + fn label_fn_like( &self, err: &mut Diagnostic, diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 2c89b63ae84f8..59fd5c315ae63 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -491,7 +491,19 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // so we just call `predicates_for_generics` directly to avoid redoing work. // `self.add_required_obligations(self.span, def_id, &all_substs);` for obligation in traits::predicates_for_generics( - traits::ObligationCause::new(self.span, self.body_id, traits::ItemObligation(def_id)), + |idx, span| { + let code = if span.is_dummy() { + ObligationCauseCode::ExprItemObligation(def_id, self.call_expr.hir_id, idx) + } else { + ObligationCauseCode::ExprBindingObligation( + def_id, + span, + self.call_expr.hir_id, + idx, + ) + }; + traits::ObligationCause::new(self.span, self.body_id, code) + }, self.param_env, method_predicates, ) { diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 0e678c41f8b40..de26a9e56e2d6 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -534,7 +534,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { traits::ObligationCause::misc(span, self.body_id) }; - obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds)); + let predicates_cause = cause.clone(); + obligations.extend(traits::predicates_for_generics( + move |_, _| predicates_cause.clone(), + self.param_env, + bounds, + )); // Also add an obligation for the method type being well-formed. let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig)); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index efe15fec7cbfa..d9870060a40bb 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1514,8 +1514,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds); // Convert the bounds into obligations. - let impl_obligations = - traits::predicates_for_generics(cause, self.param_env, impl_bounds); + let impl_obligations = traits::predicates_for_generics( + move |_, _| cause.clone(), + self.param_env, + impl_bounds, + ); let candidate_obligations = impl_obligations .chain(norm_obligations.into_iter()) diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index 1a0a5fdf4eb23..d6deefe693f1f 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -1,10 +1,12 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:2:8 | LL | f1(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r, 's> fn(&'r (), &'s ()) -> _` found closure signature `fn((), ()) -> _` @@ -15,12 +17,14 @@ LL | fn f1(_: F) where F: Fn(&(), &()) {} | ^^^^^^^^^^^^ required by this bound in `f1` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:3:8 | LL | f2(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'a, 'r> fn(&'a (), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -31,12 +35,14 @@ LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f2` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:4:8 | LL | f3(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r> fn(&(), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -47,12 +53,14 @@ LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^ required by this bound in `f3` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:5:8 | LL | f4(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r, 's> fn(&'s (), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -63,12 +71,14 @@ LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f4` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:6:8 | LL | f5(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r> fn(&'r (), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -79,12 +89,14 @@ LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f5` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:7:8 | LL | g1(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _` found closure signature `fn((), ()) -> _` @@ -95,12 +107,14 @@ LL | fn g1(_: F) where F: Fn(&(), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g1` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:8:8 | LL | g2(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r> fn(&'r (), for<'r> fn(&'r ())) -> _` found closure signature `fn((), ()) -> _` @@ -111,12 +125,14 @@ LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} | ^^^^^^^^^^^^^^^^ required by this bound in `g2` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:9:8 | LL | g3(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _` found closure signature `fn((), ()) -> _` @@ -127,12 +143,14 @@ LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g3` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:10:8 | LL | g4(|_: (), _: ()| {}); - | ^^ -------------- found signature defined here - | | - | expected due to this + | -- --------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` found closure signature `fn((), ()) -> _` @@ -143,12 +161,14 @@ LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g4` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:11:8 | LL | h1(|_: (), _: (), _: (), _: ()| {}); - | ^^ ---------------------------- found signature defined here - | | - | expected due to this + | -- ----------------------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r, 's> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>, &'s (), for<'r, 's> fn(&'r (), &'s ())) -> _` found closure signature `fn((), (), (), ()) -> _` @@ -159,12 +179,14 @@ LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h1` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:8 | LL | h2(|_: (), _: (), _: (), _: ()| {}); - | ^^ ---------------------------- found signature defined here - | | - | expected due to this + | -- ----------------------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'t0, 'r> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _` found closure signature `fn((), (), (), ()) -> _` diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index 19750fe1f333f..fbe1a1ee8bcd7 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -36,9 +36,7 @@ error[E0271]: type mismatch resolving `::A == Bar` --> $DIR/associated-types-eq-3.rs:40:9 | LL | baz(&a); - | --- ^^ type mismatch resolving `::A == Bar` - | | - | required by a bound introduced by this call + | ^^ type mismatch resolving `::A == Bar` | note: expected this to be `Bar` --> $DIR/associated-types-eq-3.rs:12:14 diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 66f1ab726922d..7e3cccae3eae5 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -33,19 +33,15 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied --> $DIR/associated-types-path-2.rs:29:14 | LL | f1(2u32, 4u32); - | -- ^^^^ the trait `Foo` is not implemented for `u32` - | | - | required by a bound introduced by this call + | ^^^^ the trait `Foo` is not implemented for `u32` | = help: the trait `Foo` is implemented for `i32` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:35:8 + --> $DIR/associated-types-path-2.rs:35:5 | LL | f1(2u32, 4i32); - | -- ^^^^ the trait `Foo` is not implemented for `u32` - | | - | required by a bound introduced by this call + | ^^ the trait `Foo` is not implemented for `u32` | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr index 01c0d3225ba0b..af99b608ca14d 100644 --- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr +++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr @@ -1,8 +1,12 @@ error: future cannot be sent between threads safely - --> $DIR/issue-67252-unnamed-future.rs:18:5 + --> $DIR/issue-67252-unnamed-future.rs:18:11 | -LL | spawn(async { - | ^^^^^ future created by async block is not `Send` +LL | spawn(async { + | ___________^ +LL | | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send` +LL | | AFuture.await; +LL | | }); + | |_____^ future created by async block is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `*mut ()` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr index 9c85eb8768497..c3553e3e0c1c2 100644 --- a/src/test/ui/async-await/issue-68112.stderr +++ b/src/test/ui/async-await/issue-68112.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-68112.rs:34:5 + --> $DIR/issue-68112.rs:34:18 | LL | require_send(send_fut); - | ^^^^^^^^^^^^ future created by async block is not `Send` + | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: future is not `Send` as it awaits another future which is not `Send` @@ -17,10 +17,10 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error: future cannot be sent between threads safely - --> $DIR/issue-68112.rs:43:5 + --> $DIR/issue-68112.rs:43:18 | LL | require_send(send_fut); - | ^^^^^^^^^^^^ future created by async block is not `Send` + | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: future is not `Send` as it awaits another future which is not `Send` @@ -35,10 +35,12 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/issue-68112.rs:60:5 + --> $DIR/issue-68112.rs:60:18 | LL | require_send(send_fut); - | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` = note: required for `Arc>` to implement `Send` diff --git a/src/test/ui/async-await/issue-72442.stderr b/src/test/ui/async-await/issue-72442.stderr index 919abf646037d..49fc81d3babc6 100644 --- a/src/test/ui/async-await/issue-72442.stderr +++ b/src/test/ui/async-await/issue-72442.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `Option<&str>: AsRef` is not satisfied - --> $DIR/issue-72442.rs:12:36 + --> $DIR/issue-72442.rs:12:25 | LL | let mut f = File::open(path.to_str())?; - | ---------- ^^^^^^^^^^^^^ the trait `AsRef` is not implemented for `Option<&str>` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^ the trait `AsRef` is not implemented for `Option<&str>` | note: required by a bound in `File::open` --> $SRC_DIR/std/src/fs.rs:LL:COL diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr index b230930012914..99e960f5d0f26 100644 --- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -1,8 +1,12 @@ error: future cannot be sent between threads safely - --> $DIR/issue-65436-raw-ptr-not-send.rs:12:5 + --> $DIR/issue-65436-raw-ptr-not-send.rs:12:17 | -LL | assert_send(async { - | ^^^^^^^^^^^ future created by async block is not `Send` +LL | assert_send(async { + | _________________^ +LL | | +LL | | bar(Foo(std::ptr::null())).await; +LL | | }) + | |_____^ future created by async block is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `*const u8` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/pin-needed-to-poll-2.stderr b/src/test/ui/async-await/pin-needed-to-poll-2.stderr index 83d1a02c876b1..3aea93a60ff2d 100644 --- a/src/test/ui/async-await/pin-needed-to-poll-2.stderr +++ b/src/test/ui/async-await/pin-needed-to-poll-2.stderr @@ -1,10 +1,8 @@ error[E0277]: `PhantomPinned` cannot be unpinned - --> $DIR/pin-needed-to-poll-2.rs:43:18 + --> $DIR/pin-needed-to-poll-2.rs:43:9 | LL | Pin::new(&mut self.sleep).poll(cx) - | -------- ^^^^^^^^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned` - | | - | required by a bound introduced by this call + | ^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned` | = note: consider using `Box::pin` note: required because it appears within the type `Sleep` diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr index 7d6bf58f51696..0c4970a72591f 100644 --- a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)` - --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5 + --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:18 | LL | is_mytrait::<(MyS2, MyS)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2` + | ^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2` | = note: required because it appears within the type `(MyS2, MyS)` note: required by a bound in `is_mytrait` diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr index 5645e15850274..ce7095664c11a 100644 --- a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied - --> $DIR/typeck-default-trait-impl-precedence.rs:19:5 + --> $DIR/typeck-default-trait-impl-precedence.rs:19:20 | LL | is_defaulted::<&'static u32>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32` + | ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32` | = help: the trait `Signed` is implemented for `i32` note: required for `&'static u32` to implement `Defaulted` diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr index 68303b842088e..7ff5752fc3585 100644 --- a/src/test/ui/binop/issue-77910-1.stderr +++ b/src/test/ui/binop/issue-77910-1.stderr @@ -19,8 +19,12 @@ LL | assert_eq!(foo, y); | ^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}` - = help: use parentheses to call the function: `foo(s)` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use parentheses to call the function + --> $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | $crate::panicking::assert_failed(kind, &*left_val(s), &*right_val, $crate::option::Option::None); + | +++ error: aborting due to 2 previous errors diff --git a/src/test/ui/box/into-boxed-slice-fail.stderr b/src/test/ui/box/into-boxed-slice-fail.stderr index de654fdc1a4b5..5e73d8737ea9d 100644 --- a/src/test/ui/box/into-boxed-slice-fail.stderr +++ b/src/test/ui/box/into-boxed-slice-fail.stderr @@ -1,10 +1,8 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/into-boxed-slice-fail.rs:7:35 + --> $DIR/into-boxed-slice-fail.rs:7:13 | LL | let _ = Box::into_boxed_slice(boxed_slice); - | --------------------- ^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` note: required by a bound in `Box::::into_boxed_slice` @@ -23,12 +21,10 @@ LL | let _ = Box::into_boxed_slice(boxed_slice); = note: slice and array elements must have `Sized` type error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time - --> $DIR/into-boxed-slice-fail.rs:11:35 + --> $DIR/into-boxed-slice-fail.rs:11:13 | LL | let _ = Box::into_boxed_slice(boxed_trait); - | --------------------- ^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn Debug` note: required by a bound in `Box::::into_boxed_slice` diff --git a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr index 8dccf929b2bd1..b013798c8247c 100644 --- a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr +++ b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr @@ -1,10 +1,15 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/expect-infer-var-appearing-twice.rs:14:5 + --> $DIR/expect-infer-var-appearing-twice.rs:14:18 | -LL | with_closure(|x: u32, y: i32| { - | ^^^^^^^^^^^^ ---------------- found signature defined here - | | - | expected due to this +LL | with_closure(|x: u32, y: i32| { + | ------------ ^--------------- + | | | + | _____|____________found signature defined here + | | | + | | required by a bound introduced by this call +LL | | +LL | | }); + | |_____^ expected due to this | = note: expected closure signature `fn(_, _) -> _` found closure signature `fn(u32, i32) -> _` diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr index bcde35983fc4c..b5f06e38f6d93 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr @@ -7,7 +7,7 @@ LL | let [_, _s] = s; | - closure is `FnOnce` because it moves the variable `s` out of its environment LL | }; LL | expect_fn(c); - | --------- the requirement to implement `Fn` derives from here + | - the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr index df33c4f1fd6d4..66cd847db50ca 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr @@ -7,7 +7,7 @@ LL | let s = s.1; | --- closure is `FnOnce` because it moves the variable `s.1` out of its environment LL | }; LL | expect_fn(c); - | --------- the requirement to implement `Fn` derives from here + | - the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr index 3e9b1c292dc18..7b9f59fcc67d0 100644 --- a/src/test/ui/closures/closure-move-sync.stderr +++ b/src/test/ui/closures/closure-move-sync.stderr @@ -1,8 +1,14 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely - --> $DIR/closure-move-sync.rs:6:13 + --> $DIR/closure-move-sync.rs:6:27 | -LL | let t = thread::spawn(|| { - | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely +LL | let t = thread::spawn(|| { + | _____________-------------_^ + | | | + | | required by a bound introduced by this call +LL | | recv.recv().unwrap(); +LL | | +LL | | }); + | |_____^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>` = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send` @@ -16,12 +22,18 @@ note: required by a bound in `spawn` | LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` +help: consider dereferencing here + | +LL | let t = thread::spawn(*|| { + | + error[E0277]: `Sender<()>` cannot be shared between threads safely - --> $DIR/closure-move-sync.rs:18:5 + --> $DIR/closure-move-sync.rs:18:19 | LL | thread::spawn(|| tx.send(()).unwrap()); - | ^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `Sender<()>` = note: required for `&Sender<()>` to implement `Send` @@ -35,6 +47,10 @@ note: required by a bound in `spawn` | LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` +help: consider dereferencing here + | +LL | thread::spawn(*|| tx.send(()).unwrap()); + | + error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/closure-wrong-kind.stderr b/src/test/ui/closures/closure-wrong-kind.stderr index 35caf71a5e8c7..421be56d9173e 100644 --- a/src/test/ui/closures/closure-wrong-kind.stderr +++ b/src/test/ui/closures/closure-wrong-kind.stderr @@ -6,7 +6,7 @@ LL | let closure = |_| foo(x); | | | this closure implements `FnOnce`, not `Fn` LL | bar(closure); - | --- the requirement to implement `Fn` derives from here + | ------- the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr index a9c185e5fcbd1..0e8334d033820 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr @@ -2,9 +2,7 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied --> $DIR/trait_objects_fail.rs:26:9 | LL | foo(&10_u32); - | --- ^^^^^^^ the trait `Trait` is not implemented for `u32` - | | - | required by a bound introduced by this call + | ^^^^^^^ the trait `Trait` is not implemented for `u32` | = help: the trait `Trait<2>` is implemented for `u32` = note: required for the cast from `u32` to the object type `dyn Trait` @@ -13,9 +11,7 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 | LL | bar(&true); - | --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool` - | | - | required by a bound introduced by this call + | ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | = help: the trait `Traitor<2, 3>` is implemented for `bool` = note: required for the cast from `bool` to the object type `dyn Traitor<_>` diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr index a5f7bc0b26cbd..615dc875f67a3 100644 --- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr @@ -1,8 +1,8 @@ error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:17:5 + --> $DIR/abstract-const-as-cast-3.rs:17:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait` @@ -26,10 +26,10 @@ LL | assert_impl::>(); found type `{ O as u128 }` error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:20:5 + --> $DIR/abstract-const-as-cast-3.rs:20:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait` @@ -71,10 +71,10 @@ LL | assert_impl::>(); found type `14` error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:35:5 + --> $DIR/abstract-const-as-cast-3.rs:35:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait` @@ -98,10 +98,10 @@ LL | assert_impl::>(); found type `{ O as u128 }` error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:38:5 + --> $DIR/abstract-const-as-cast-3.rs:38:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait` diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr index 26764bc0ee5cc..f2f8d84ad3bb0 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Bar: Foo` is not satisfied - --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:8 + --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:5 | LL | f1.foo(1usize); - | ^^^ the trait `Foo` is not implemented for `Bar` + | ^^ --- required by a bound introduced by this call + | | + | the trait `Foo` is not implemented for `Bar` | = help: the following other types implement trait `Foo`: > diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index bb175367e1f9e..b0c41e2fae1ac 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Bar: Foo` is not satisfied - --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:8 + --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:5 | LL | f1.foo(1usize); - | ^^^ the trait `Foo` is not implemented for `Bar` + | ^^ --- required by a bound introduced by this call + | | + | the trait `Foo` is not implemented for `Bar` | = help: the following other types implement trait `Foo`: > diff --git a/src/test/ui/dst/dst-rvalue.stderr b/src/test/ui/dst/dst-rvalue.stderr index 727f4d843033f..5fafdb0620305 100644 --- a/src/test/ui/dst/dst-rvalue.stderr +++ b/src/test/ui/dst/dst-rvalue.stderr @@ -1,10 +1,8 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/dst-rvalue.rs:4:33 + --> $DIR/dst-rvalue.rs:4:24 | LL | let _x: Box = Box::new(*"hello world"); - | -------- ^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` note: required by a bound in `Box::::new` @@ -14,12 +12,10 @@ LL | impl Box { | ^ required by this bound in `Box::::new` error[E0277]: the size for values of type `[isize]` cannot be known at compilation time - --> $DIR/dst-rvalue.rs:8:37 + --> $DIR/dst-rvalue.rs:8:28 | LL | let _x: Box<[isize]> = Box::new(*array); - | -------- ^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[isize]` note: required by a bound in `Box::::new` diff --git a/src/test/ui/error-codes/E0277-2.stderr b/src/test/ui/error-codes/E0277-2.stderr index ca2cb88424076..a2abf37931a4f 100644 --- a/src/test/ui/error-codes/E0277-2.stderr +++ b/src/test/ui/error-codes/E0277-2.stderr @@ -1,8 +1,8 @@ error[E0277]: `*const u8` cannot be sent between threads safely - --> $DIR/E0277-2.rs:16:5 + --> $DIR/E0277-2.rs:16:15 | LL | is_send::(); - | ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely + | ^^^ `*const u8` cannot be sent between threads safely | = help: within `Foo`, the trait `Send` is not implemented for `*const u8` note: required because it appears within the type `Baz` diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index 90a28874ead8c..162d4922d0089 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -12,12 +12,25 @@ help: use a fully-qualified path to a specific available implementation (2 found LL | let cont: u32 = <::Impl as Generator>::create(); | ++++++++++ + -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/E0283.rs:35:24 | LL | let bar = foo_impl.into() * 1u32; | ^^^^ | +help: try using a fully qualified path to specify the expected types + | +LL | let bar = >::into(foo_impl) * 1u32; + | ++++++++++++++++++++++++ ~ + +error[E0283]: type annotations needed + --> $DIR/E0283.rs:35:24 + | +LL | let bar = foo_impl.into() * 1u32; + | -------- ^^^^ + | | + | type must be known at this point + | note: multiple `impl`s satisfying `Impl: Into<_>` found --> $DIR/E0283.rs:17:1 | @@ -31,7 +44,7 @@ help: try using a fully qualified path to specify the expected types LL | let bar = >::into(foo_impl) * 1u32; | ++++++++++++++++++++++++ ~ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0283, E0790. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0282, E0283, E0790. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr index 8d6713261d5ec..a79caced111bb 100644 --- a/src/test/ui/extern/extern-types-unsized.stderr +++ b/src/test/ui/extern/extern-types-unsized.stderr @@ -16,10 +16,10 @@ LL | fn assert_sized() {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:25:5 + --> $DIR/extern-types-unsized.rs:25:20 | LL | assert_sized::(); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: within `Foo`, the trait `Sized` is not implemented for `A` note: required because it appears within the type `Foo` @@ -38,10 +38,10 @@ LL | fn assert_sized() {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:28:5 + --> $DIR/extern-types-unsized.rs:28:20 | LL | assert_sized::>(); - | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^ doesn't have a size known at compile-time | = help: within `Bar`, the trait `Sized` is not implemented for `A` note: required because it appears within the type `Bar` @@ -60,10 +60,10 @@ LL | fn assert_sized() {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:31:5 + --> $DIR/extern-types-unsized.rs:31:20 | LL | assert_sized::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Bar>`, the trait `Sized` is not implemented for `A` note: required because it appears within the type `Bar` diff --git a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr index 0557340f792fd..b7757740d9e34 100644 --- a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr +++ b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr @@ -15,9 +15,7 @@ error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known --> $DIR/feature-gate-unsized_fn_params.rs:24:9 | LL | foo(*x); - | --- ^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` = help: unsized fn params are gated as an unstable feature diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 726d3e35b10e9..62bcf3175e21b 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -1,8 +1,10 @@ error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely - --> $DIR/send-sync.rs:8:5 + --> $DIR/send-sync.rs:8:10 | LL | send(format_args!("{:?}", c)); - | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque` = note: required because it appears within the type `&core::fmt::Opaque` @@ -15,12 +17,15 @@ note: required by a bound in `send` | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` + = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely - --> $DIR/send-sync.rs:9:5 + --> $DIR/send-sync.rs:9:10 | LL | sync(format_args!("{:?}", c)); - | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque` = note: required because it appears within the type `&core::fmt::Opaque` @@ -33,6 +38,7 @@ note: required by a bound in `sync` | LL | fn sync(_: T) {} | ^^^^ required by this bound in `sync` + = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/drop-tracking-parent-expression.stderr b/src/test/ui/generator/drop-tracking-parent-expression.stderr index 522a300b3ed79..fbf5d6e07256b 100644 --- a/src/test/ui/generator/drop-tracking-parent-expression.stderr +++ b/src/test/ui/generator/drop-tracking-parent-expression.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:24:13 + --> $DIR/drop-tracking-parent-expression.rs:24:25 | LL | assert_send(g); - | ^^^^^^^^^^^ generator is not `Send` + | ^ generator is not `Send` ... LL | / type_combinations!( LL | | // OK @@ -41,10 +41,10 @@ LL | fn assert_send(_thing: T) {} = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:24:13 + --> $DIR/drop-tracking-parent-expression.rs:24:25 | LL | assert_send(g); - | ^^^^^^^^^^^ generator is not `Send` + | ^ generator is not `Send` ... LL | / type_combinations!( LL | | // OK @@ -83,10 +83,10 @@ LL | fn assert_send(_thing: T) {} = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:24:13 + --> $DIR/drop-tracking-parent-expression.rs:24:25 | LL | assert_send(g); - | ^^^^^^^^^^^ generator is not `Send` + | ^ generator is not `Send` ... LL | / type_combinations!( LL | | // OK diff --git a/src/test/ui/generator/drop-yield-twice.stderr b/src/test/ui/generator/drop-yield-twice.stderr index 5bc6ea5600fc5..0808a2c85ee1d 100644 --- a/src/test/ui/generator/drop-yield-twice.stderr +++ b/src/test/ui/generator/drop-yield-twice.stderr @@ -1,8 +1,14 @@ error: generator cannot be sent between threads safely - --> $DIR/drop-yield-twice.rs:7:5 + --> $DIR/drop-yield-twice.rs:7:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | let guard = Foo(42); +LL | | yield; +LL | | drop(guard); +LL | | yield; +LL | | }) + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield diff --git a/src/test/ui/generator/generator-yielding-or-returning-itself.stderr b/src/test/ui/generator/generator-yielding-or-returning-itself.stderr index 2a39a08ee39b2..8f5d2429a2892 100644 --- a/src/test/ui/generator/generator-yielding-or-returning-itself.stderr +++ b/src/test/ui/generator/generator-yielding-or-returning-itself.stderr @@ -1,8 +1,15 @@ error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36]` - --> $DIR/generator-yielding-or-returning-itself.rs:15:5 + --> $DIR/generator-yielding-or-returning-itself.rs:15:34 | -LL | want_cyclic_generator_return(|| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size +LL | want_cyclic_generator_return(|| { + | _____----------------------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | if false { yield None.unwrap(); } +LL | | None.unwrap() +LL | | }) + | |_____^ cyclic type of infinite size | = note: closures cannot capture themselves or take themselves as argument; this error may be the result of a recent compiler bug-fix, @@ -17,10 +24,17 @@ LL | where T: Generator | ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return` error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35]` - --> $DIR/generator-yielding-or-returning-itself.rs:28:5 + --> $DIR/generator-yielding-or-returning-itself.rs:28:33 | -LL | want_cyclic_generator_yield(|| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size +LL | want_cyclic_generator_yield(|| { + | _____---------------------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | if false { yield None.unwrap(); } +LL | | None.unwrap() +LL | | }) + | |_____^ cyclic type of infinite size | = note: closures cannot capture themselves or take themselves as argument; this error may be the result of a recent compiler bug-fix, diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs index 03b21c5ebd3ee..21026f45cb823 100644 --- a/src/test/ui/generator/issue-68112.rs +++ b/src/test/ui/generator/issue-68112.rs @@ -64,6 +64,7 @@ fn test2() { //~^ ERROR `RefCell` cannot be shared between threads safely //~| NOTE `RefCell` cannot be shared between threads safely //~| NOTE required for + //~| NOTE required by a bound introduced by this call //~| NOTE captures the following types } diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr index b56f445872bc4..eb99d42c92068 100644 --- a/src/test/ui/generator/issue-68112.stderr +++ b/src/test/ui/generator/issue-68112.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/issue-68112.rs:40:5 + --> $DIR/issue-68112.rs:40:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ generator is not `Send` + | ^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: generator is not `Send` as this value is used across a yield @@ -23,10 +23,12 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/issue-68112.rs:63:5 + --> $DIR/issue-68112.rs:63:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` = note: required for `Arc>` to implement `Send` diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index b54b0f570c962..97dbaf73ade6b 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -1,8 +1,15 @@ error[E0277]: `Cell` cannot be shared between threads safely - --> $DIR/not-send-sync.rs:16:5 + --> $DIR/not-send-sync.rs:16:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ `Cell` cannot be shared between threads safely +LL | assert_send(|| { + | _____-----------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | drop(&a); +LL | | yield; +LL | | }); + | |_____^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` = note: required for `&Cell` to implement `Send` @@ -16,12 +23,21 @@ note: required by a bound in `assert_send` | LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` +help: consider dereferencing here + | +LL | assert_send(*|| { + | + error: generator cannot be shared between threads safely - --> $DIR/not-send-sync.rs:9:5 - | -LL | assert_sync(|| { - | ^^^^^^^^^^^ generator is not `Sync` + --> $DIR/not-send-sync.rs:9:17 + | +LL | assert_sync(|| { + | _________________^ +LL | | +LL | | let a = Cell::new(2); +LL | | yield; +LL | | }); + | |_____^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell` note: generator is not `Sync` as this value is used across a yield diff --git a/src/test/ui/generator/partial-drop.stderr b/src/test/ui/generator/partial-drop.stderr index 1004fc64da93a..9baafe54e84d4 100644 --- a/src/test/ui/generator/partial-drop.stderr +++ b/src/test/ui/generator/partial-drop.stderr @@ -1,8 +1,15 @@ error: generator cannot be sent between threads safely - --> $DIR/partial-drop.rs:14:5 + --> $DIR/partial-drop.rs:14:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | +LL | | // FIXME: it would be nice to make this work. +LL | | let guard = Bar { foo: Foo, x: 42 }; +LL | | drop(guard.foo); +LL | | yield; +LL | | }); + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:14:17: 14:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield @@ -22,10 +29,17 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be sent between threads safely - --> $DIR/partial-drop.rs:22:5 + --> $DIR/partial-drop.rs:22:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | +LL | | // FIXME: it would be nice to make this work. +LL | | let guard = Bar { foo: Foo, x: 42 }; +... | +LL | | yield; +LL | | }); + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:22:17: 22:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield @@ -45,10 +59,17 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be sent between threads safely - --> $DIR/partial-drop.rs:32:5 + --> $DIR/partial-drop.rs:32:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | +LL | | // FIXME: it would be nice to make this work. +LL | | let guard = Bar { foo: Foo, x: 42 }; +... | +LL | | yield; +LL | | }); + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:32:17: 32:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr index bbde8ea7892cc..3a83021dd9950 100644 --- a/src/test/ui/generator/print/generator-print-verbose-1.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/generator-print-verbose-1.rs:37:5 + --> $DIR/generator-print-verbose-1.rs:37:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ generator is not `Send` + | ^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: generator is not `Send` as this value is used across a yield @@ -21,10 +21,12 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/generator-print-verbose-1.rs:56:5 + --> $DIR/generator-print-verbose-1.rs:56:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` = note: required for `Arc>` to implement `Send` diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr index 92ca51b4e7267..14e0581897813 100644 --- a/src/test/ui/generator/print/generator-print-verbose-2.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr @@ -1,8 +1,15 @@ error[E0277]: `Cell` cannot be shared between threads safely - --> $DIR/generator-print-verbose-2.rs:19:5 + --> $DIR/generator-print-verbose-2.rs:19:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ `Cell` cannot be shared between threads safely +LL | assert_send(|| { + | _____-----------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | drop(&a); +LL | | yield; +LL | | }); + | |_____^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` = note: required for `&'_#4r Cell` to implement `Send` @@ -16,12 +23,21 @@ note: required by a bound in `assert_send` | LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` +help: consider dereferencing here + | +LL | assert_send(*|| { + | + error: generator cannot be shared between threads safely - --> $DIR/generator-print-verbose-2.rs:12:5 - | -LL | assert_sync(|| { - | ^^^^^^^^^^^ generator is not `Sync` + --> $DIR/generator-print-verbose-2.rs:12:17 + | +LL | assert_sync(|| { + | _________________^ +LL | | +LL | | let a = Cell::new(2); +LL | | yield; +LL | | }); + | |_____^ generator is not `Sync` | = help: within `[main::{closure#0} upvar_tys=() {Cell, ()}]`, the trait `Sync` is not implemented for `Cell` note: generator is not `Sync` as this value is used across a yield diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr index 98c304cc90b53..8193f491e69ed 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied - --> $DIR/issue-88460.rs:30:5 + --> $DIR/issue-88460.rs:30:10 | LL | test(Foo); - | ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` + | ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` + | | + | required by a bound introduced by this call | = help: the trait `Marker` is implemented for `()` note: required by a bound in `test` diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr index 066bf431a83d7..b30dd36d2ad6a 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr @@ -1,8 +1,10 @@ error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` - --> $DIR/issue-62529-3.rs:25:9 + --> $DIR/issue-62529-3.rs:25:14 | LL | call(f, ()); - | ^^^^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` + | ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` + | | + | required by a bound introduced by this call | = note: expected a closure with arguments `((),)` found a closure with arguments `(<_ as ATC<'a>>::Type,)` diff --git a/src/test/ui/inference/issue-71732.stderr b/src/test/ui/inference/issue-71732.stderr index 04673a375cf01..79bee33280d2e 100644 --- a/src/test/ui/inference/issue-71732.stderr +++ b/src/test/ui/inference/issue-71732.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-71732.rs:18:10 | LL | .get(&"key".into()) - | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get` + | ^^^ ------------- type must be known at this point + | | + | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: - impl Borrow for String; @@ -13,7 +15,7 @@ note: required by a bound in `HashMap::::get` | LL | K: Borrow, | ^^^^^^^^^ required by this bound in `HashMap::::get` -help: consider specifying the type argument in the function call +help: consider specifying the generic argument | LL | .get::(&"key".into()) | +++++ diff --git a/src/test/ui/inference/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr index d4eeda07366a8..3504b294ab25e 100644 --- a/src/test/ui/inference/issue-72690.stderr +++ b/src/test/ui/inference/issue-72690.stderr @@ -12,7 +12,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:7:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -39,7 +41,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:12:26 | LL | |x| String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -55,7 +59,9 @@ error[E0283]: type annotations needed for `&T` --> $DIR/issue-72690.rs:17:9 | LL | let _ = "x".as_ref(); - | ^ ------ type must be known at this point + | ^ --- ------ required by a bound introduced by this call + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -81,7 +87,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:21:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -107,7 +115,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:28:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -133,7 +143,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:37:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -159,7 +171,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:46:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -185,7 +199,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:53:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -211,7 +227,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:62:22 | LL | String::from("x".as_ref()); - | ^^^^^^ + | --- ^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr index e395e65fad066..4f621b82dc579 100644 --- a/src/test/ui/inference/issue-86162-1.stderr +++ b/src/test/ui/inference/issue-86162-1.stderr @@ -4,7 +4,7 @@ error[E0283]: type annotations needed LL | foo(gen()); //<- Do not suggest `foo::()`! | --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` | | - | type must be known at this point + | required by a bound introduced by this call | = note: cannot satisfy `_: Clone` note: required by a bound in `foo` diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index 7955fecda0670..ee476e7aa384c 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -1,8 +1,10 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/interior-mutability.rs:5:5 + --> $DIR/interior-mutability.rs:5:18 | LL | catch_unwind(|| { x.set(23); }); - | ^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | | + | required by a bound introduced by this call | = help: within `Cell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` @@ -17,6 +19,10 @@ note: required by a bound in `catch_unwind` | LL | pub fn catch_unwind R + UnwindSafe, R>(f: F) -> Result { | ^^^^^^^^^^ required by this bound in `catch_unwind` +help: consider dereferencing here + | +LL | catch_unwind(*|| { x.set(23); }); + | + error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17651.stderr b/src/test/ui/issues/issue-17651.stderr index efaaeeda2fab6..792b8294b4413 100644 --- a/src/test/ui/issues/issue-17651.stderr +++ b/src/test/ui/issues/issue-17651.stderr @@ -1,10 +1,8 @@ error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time - --> $DIR/issue-17651.rs:5:18 + --> $DIR/issue-17651.rs:5:9 | LL | (|| Box::new(*(&[0][..])))(); - | -------- ^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[{integer}]` note: required by a bound in `Box::::new` diff --git a/src/test/ui/issues/issue-20162.stderr b/src/test/ui/issues/issue-20162.stderr index d70bf6e1d921c..3f9b3be985179 100644 --- a/src/test/ui/issues/issue-20162.stderr +++ b/src/test/ui/issues/issue-20162.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `X: Ord` is not satisfied - --> $DIR/issue-20162.rs:5:7 + --> $DIR/issue-20162.rs:5:5 | LL | b.sort(); - | ^^^^ the trait `Ord` is not implemented for `X` + | ^ ---- required by a bound introduced by this call + | | + | the trait `Ord` is not implemented for `X` | note: required by a bound in `slice::::sort` --> $SRC_DIR/alloc/src/slice.rs:LL:COL diff --git a/src/test/ui/issues/issue-21763.stderr b/src/test/ui/issues/issue-21763.stderr index 790681589248a..72c65029746ad 100644 --- a/src/test/ui/issues/issue-21763.stderr +++ b/src/test/ui/issues/issue-21763.stderr @@ -1,8 +1,8 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/issue-21763.rs:9:5 + --> $DIR/issue-21763.rs:9:11 | LL | foo::, Rc<()>>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely | = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` = note: required because it appears within the type `(Rc<()>, Rc<()>)` diff --git a/src/test/ui/issues/issue-31173.rs b/src/test/ui/issues/issue-31173.rs index 472a95d4636bc..04efa27189b74 100644 --- a/src/test/ui/issues/issue-31173.rs +++ b/src/test/ui/issues/issue-31173.rs @@ -4,12 +4,12 @@ pub fn get_tok(it: &mut IntoIter) { let mut found_e = false; let temp: Vec = it + //~^ ERROR to be an iterator that yields `&_`, but it yields `u8` .take_while(|&x| { found_e = true; false }) .cloned() - //~^ ERROR to be an iterator that yields `&_`, but it yields `u8` .collect(); //~ ERROR the method } diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr index 0b8222088b879..e3334eef3ad7f 100644 --- a/src/test/ui/issues/issue-31173.stderr +++ b/src/test/ui/issues/issue-31173.stderr @@ -1,8 +1,16 @@ -error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter, [closure@$DIR/issue-31173.rs:7:21: 7:25]>` to be an iterator that yields `&_`, but it yields `u8` - --> $DIR/issue-31173.rs:11:10 - | -LL | .cloned() - | ^^^^^^ expected reference, found `u8` +error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter, [closure@$DIR/issue-31173.rs:8:21: 8:25]>` to be an iterator that yields `&_`, but it yields `u8` + --> $DIR/issue-31173.rs:6:25 + | +LL | let temp: Vec = it + | _________________________^ +LL | | +LL | | .take_while(|&x| { +LL | | found_e = true; +LL | | false +LL | | }) + | |__________^ expected reference, found `u8` +LL | .cloned() + | ------ required by a bound introduced by this call | = note: expected reference `&_` found type `u8` @@ -12,11 +20,11 @@ note: required by a bound in `cloned` LL | Self: Sized + Iterator, | ^^^^^^^^^^^^ required by this bound in `cloned` -error[E0599]: the method `collect` exists for struct `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>`, but its trait bounds were not satisfied +error[E0599]: the method `collect` exists for struct `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>`, but its trait bounds were not satisfied --> $DIR/issue-31173.rs:13:10 | LL | .collect(); - | ^^^^^^^ method cannot be called on `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds + | ^^^^^^^ method cannot be called on `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>` due to unsatisfied trait bounds | ::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL | @@ -29,10 +37,10 @@ LL | pub struct Cloned { | -------------------- doesn't satisfy `_: Iterator` | = note: the following trait bounds were not satisfied: - `, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_` - which is required by `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - which is required by `&mut Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` + `, [closure@$DIR/issue-31173.rs:8:21: 8:25]> as Iterator>::Item = &_` + which is required by `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator` + `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator` + which is required by `&mut Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-33941.stderr b/src/test/ui/issues/issue-33941.stderr index caba0ad52689e..691b8f88f4ed5 100644 --- a/src/test/ui/issues/issue-33941.stderr +++ b/src/test/ui/issues/issue-33941.stderr @@ -1,8 +1,10 @@ error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:6:36 + --> $DIR/issue-33941.rs:6:14 | LL | for _ in HashMap::new().iter().cloned() {} - | ^^^^^^ expected reference, found tuple + | ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call + | | + | expected reference, found tuple | = note: expected reference `&_` found tuple `(&_, &_)` diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index 48ae2df691c3d..72082f0cd1728 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -13,10 +13,12 @@ LL | let sr: Vec<(u32, _, _)> = vec![]; | + error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()` - --> $DIR/issue-34334.rs:5:87 + --> $DIR/issue-34334.rs:5:33 | LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); - | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` = help: the trait `FromIterator` is implemented for `Vec` diff --git a/src/test/ui/issues/issue-34349.stderr b/src/test/ui/issues/issue-34349.stderr index d0b51961b44a7..272feb1e3794f 100644 --- a/src/test/ui/issues/issue-34349.stderr +++ b/src/test/ui/issues/issue-34349.stderr @@ -7,7 +7,7 @@ LL | farewell.push_str("!!!"); | -------- closure is `FnMut` because it mutates the variable `farewell` here ... LL | apply(diary); - | ----- the requirement to implement `Fn` derives from here + | ----- the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-59488.rs b/src/test/ui/issues/issue-59488.rs index 922b593935aa8..384501e3e5dfd 100644 --- a/src/test/ui/issues/issue-59488.rs +++ b/src/test/ui/issues/issue-59488.rs @@ -30,4 +30,5 @@ fn main() { assert_eq!(Foo::Bar, i); //~^ ERROR binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}` [E0369] //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277] + //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277] } diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index 7ce3dedaa887b..bb6843a19586e 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -106,7 +106,26 @@ LL | assert_eq!(Foo::Bar, i); and 68 others = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 9 previous errors +error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` + --> $DIR/issue-59488.rs:30:5 + | +LL | assert_eq!(Foo::Bar, i); + | ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}` + = help: the following other types implement trait `Debug`: + extern "C" fn() -> Ret + extern "C" fn(A, B) -> Ret + extern "C" fn(A, B, ...) -> Ret + extern "C" fn(A, B, C) -> Ret + extern "C" fn(A, B, C, ...) -> Ret + extern "C" fn(A, B, C, D) -> Ret + extern "C" fn(A, B, C, D, ...) -> Ret + extern "C" fn(A, B, C, D, E) -> Ret + and 68 others + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 10 previous errors Some errors have detailed explanations: E0277, E0308, E0369. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-60218.stderr b/src/test/ui/issues/issue-60218.stderr index 870b25014471d..9105492c9ad94 100644 --- a/src/test/ui/issues/issue-60218.stderr +++ b/src/test/ui/issues/issue-60218.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `&u32: Foo` is not satisfied - --> $DIR/issue-60218.rs:18:27 + --> $DIR/issue-60218.rs:18:19 | LL | trigger_error(vec![], |x: &u32| x) - | ------------- ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32` + | ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32` | | | required by a bound introduced by this call | @@ -14,6 +14,7 @@ LL | pub fn trigger_error(iterable: I, functor: F) ... LL | for<'t> ::IntoIter, F> as Iterator>::Item: Foo, | ^^^ required by this bound in `trigger_error` + = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr index d6e39251632ba..2de1503765082 100644 --- a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` - --> $DIR/issue-66923-show-error-for-correct-call.rs:8:39 + --> $DIR/issue-66923-show-error-for-correct-call.rs:8:24 | LL | let x2: Vec = x1.into_iter().collect(); - | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` @@ -13,10 +15,12 @@ LL | fn collect>(self) -> B | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` - --> $DIR/issue-66923-show-error-for-correct-call.rs:12:29 + --> $DIR/issue-66923-show-error-for-correct-call.rs:12:14 | LL | let x3 = x1.into_iter().collect::>(); - | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` diff --git a/src/test/ui/issues/issue-69455.stderr b/src/test/ui/issues/issue-69455.stderr index b732df764e57f..3e40777c8d0aa 100644 --- a/src/test/ui/issues/issue-69455.stderr +++ b/src/test/ui/issues/issue-69455.stderr @@ -14,9 +14,10 @@ error[E0283]: type annotations needed --> $DIR/issue-69455.rs:29:41 | LL | println!("{}", 23u64.test(xs.iter().sum())); - | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` - | | - | type must be known at this point + | ----- ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | | | + | | required by a bound introduced by this call + | type must be known at this point | note: multiple `impl`s satisfying `u64: Test<_>` found --> $DIR/issue-69455.rs:11:1 diff --git a/src/test/ui/issues/issue-69683.stderr b/src/test/ui/issues/issue-69683.stderr index 193de1a35cf1a..6d9a1c6fbf9bd 100644 --- a/src/test/ui/issues/issue-69683.stderr +++ b/src/test/ui/issues/issue-69683.stderr @@ -14,7 +14,7 @@ error[E0283]: type annotations needed --> $DIR/issue-69683.rs:30:10 | LL | 0u16.foo(b); - | ^^^ + | ^^^ - type must be known at this point | note: multiple `impl`s satisfying `u8: Element<_>` found --> $DIR/issue-69683.rs:5:1 @@ -37,7 +37,33 @@ help: try using a fully qualified path to specify the expected types LL | >::foo(0u16, b); | +++++++++++++++++++++ ~ -error: aborting due to 2 previous errors +error[E0283]: type annotations needed + --> $DIR/issue-69683.rs:30:10 + | +LL | 0u16.foo(b); + | ---- ^^^ + | | + | type must be known at this point + | +note: multiple `impl`s satisfying `u8: Element<_>` found + --> $DIR/issue-69683.rs:5:1 + | +LL | impl Element<()> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl, S> Element<[S; 3]> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required for `u16` to implement `Foo<_>` + --> $DIR/issue-69683.rs:20:9 + | +LL | impl Foo for u16 + | ^^^^^^ ^^^ +help: try using a fully qualified path to specify the expected types + | +LL | >::foo(0u16, b); + | +++++++++++++++++++++ ~ + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0283, E0284. For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr index c6e6ea1e096af..b834920b0d041 100644 --- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr +++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr @@ -34,8 +34,12 @@ LL | assert_eq!(a, 0); | ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `fn() -> i32 {a}` - = help: use parentheses to call the function: `a()` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use parentheses to call the function + --> $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | $crate::panicking::assert_failed(kind, &*left_val(), &*right_val, $crate::option::Option::None); + | ++ error: aborting due to 3 previous errors diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs index a1144c8cb8c6a..7d35da825328e 100644 --- a/src/test/ui/iterators/collect-into-array.rs +++ b/src/test/ui/iterators/collect-into-array.rs @@ -4,4 +4,5 @@ fn main() { //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()` //~| NOTE required by a bound in `collect` + //~| NOTE required by a bound introduced by this call } diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr index 7be53a4873bcc..7fe9707e6d232 100644 --- a/src/test/ui/iterators/collect-into-array.stderr +++ b/src/test/ui/iterators/collect-into-array.stderr @@ -1,8 +1,10 @@ error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator - --> $DIR/collect-into-array.rs:3:39 + --> $DIR/collect-into-array.rs:3:31 | LL | let whatever: [u32; 10] = (0..10).collect(); - | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()` + | ^^^^^^^ ------- required by a bound introduced by this call + | | + | try collecting into a `Vec<{integer}>`, then using `.try_into()` | = help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]` note: required by a bound in `collect` diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs index aafa6bc8b9514..5eade075613fe 100644 --- a/src/test/ui/iterators/collect-into-slice.rs +++ b/src/test/ui/iterators/collect-into-slice.rs @@ -1,15 +1,20 @@ fn process_slice(data: &[i32]) { //~^ NOTE required by a bound in this + //~| NOTE required by a bound in this todo!() } fn main() { let some_generated_vec = (0..10).collect(); //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time + //~| ERROR the size for values of type `[i32]` cannot be known at compilation time //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| NOTE try explicitly collecting into a `Vec<{integer}>` //~| NOTE required by a bound in `collect` + //~| NOTE required by a bound in `collect` //~| NOTE all local variables must have a statically known size //~| NOTE doesn't have a size known at compile-time + //~| NOTE doesn't have a size known at compile-time + //~| NOTE required by a bound introduced by this call process_slice(&some_generated_vec); } diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr index 4842e65fe976b..bce40118bdfa0 100644 --- a/src/test/ui/iterators/collect-into-slice.stderr +++ b/src/test/ui/iterators/collect-into-slice.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/collect-into-slice.rs:7:9 + --> $DIR/collect-into-slice.rs:8:9 | LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -8,11 +8,26 @@ LL | let some_generated_vec = (0..10).collect(); = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/collect-into-slice.rs:8:38 + | +LL | let some_generated_vec = (0..10).collect(); + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | fn collect>(self) -> B + | ^ required by this bound in `collect` + error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size - --> $DIR/collect-into-slice.rs:7:38 + --> $DIR/collect-into-slice.rs:8:30 | LL | let some_generated_vec = (0..10).collect(); - | ^^^^^^^ try explicitly collecting into a `Vec<{integer}>` + | ^^^^^^^ ------- required by a bound introduced by this call + | | + | try explicitly collecting into a `Vec<{integer}>` | = help: the trait `FromIterator<{integer}>` is not implemented for `[i32]` note: required by a bound in `collect` @@ -21,6 +36,6 @@ note: required by a bound in `collect` LL | fn collect>(self) -> B | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/issue-28098.stderr b/src/test/ui/iterators/issue-28098.stderr index 53b610c172392..542807fb91ca3 100644 --- a/src/test/ui/iterators/issue-28098.stderr +++ b/src/test/ui/iterators/issue-28098.stderr @@ -8,6 +8,14 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` +error[E0277]: `()` is not an iterator + --> $DIR/issue-28098.rs:2:13 + | +LL | let _ = Iterator::next(&mut ()); + | ^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` + error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:5:14 | @@ -27,6 +35,14 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` +error[E0277]: `()` is not an iterator + --> $DIR/issue-28098.rs:8:13 + | +LL | let _ = Iterator::next(&mut ()); + | ^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` + error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:17:28 | @@ -37,6 +53,14 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` +error[E0277]: `()` is not an iterator + --> $DIR/issue-28098.rs:17:13 + | +LL | let _ = Iterator::next(&mut ()); + | ^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` + error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:20:28 | @@ -47,6 +71,14 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` +error[E0277]: `()` is not an iterator + --> $DIR/issue-28098.rs:20:13 + | +LL | let _ = Iterator::next(&mut ()); + | ^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` + error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:23:14 | @@ -56,6 +88,6 @@ LL | for _ in false {} = help: the trait `Iterator` is not implemented for `bool` = note: required for `bool` to implement `IntoIterator` -error: aborting due to 6 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr index eab003a110782..cc6e1f59c7789 100644 --- a/src/test/ui/kindck/kindck-nonsendable-1.stderr +++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr @@ -1,10 +1,12 @@ error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/kindck-nonsendable-1.rs:9:5 + --> $DIR/kindck-nonsendable-1.rs:9:9 | LL | bar(move|| foo(x)); - | ^^^ ------ within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]` - | | - | `Rc` cannot be sent between threads safely + | --- ------^^^^^^^ + | | | + | | `Rc` cannot be sent between threads safely + | | within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]` + | required by a bound introduced by this call | = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc` note: required because it's used within this closure diff --git a/src/test/ui/kindck/kindck-send-object.stderr b/src/test/ui/kindck/kindck-send-object.stderr index 47b7462a6a104..e9bbeeacd7013 100644 --- a/src/test/ui/kindck/kindck-send-object.stderr +++ b/src/test/ui/kindck/kindck-send-object.stderr @@ -1,8 +1,8 @@ error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely - --> $DIR/kindck-send-object.rs:12:5 + --> $DIR/kindck-send-object.rs:12:19 | LL | assert_send::<&'static (dyn Dummy + 'static)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` @@ -13,10 +13,10 @@ LL | fn assert_send() { } | ^^^^ required by this bound in `assert_send` error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object.rs:17:5 + --> $DIR/kindck-send-object.rs:17:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely + | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` = note: required for `Unique` to implement `Send` diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr index 24428266cc717..11f597fee91be 100644 --- a/src/test/ui/kindck/kindck-send-object1.stderr +++ b/src/test/ui/kindck/kindck-send-object1.stderr @@ -1,8 +1,8 @@ error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely - --> $DIR/kindck-send-object1.rs:10:5 + --> $DIR/kindck-send-object1.rs:10:19 | LL | assert_send::<&'a dyn Dummy>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` @@ -13,10 +13,10 @@ LL | fn assert_send() { } | ^^^^ required by this bound in `assert_send` error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely - --> $DIR/kindck-send-object1.rs:28:5 + --> $DIR/kindck-send-object1.rs:28:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` diff --git a/src/test/ui/kindck/kindck-send-object2.stderr b/src/test/ui/kindck/kindck-send-object2.stderr index 81ec65950d875..b8af33d0dc120 100644 --- a/src/test/ui/kindck/kindck-send-object2.stderr +++ b/src/test/ui/kindck/kindck-send-object2.stderr @@ -1,8 +1,8 @@ error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely - --> $DIR/kindck-send-object2.rs:7:5 + --> $DIR/kindck-send-object2.rs:7:19 | LL | assert_send::<&'static dyn Dummy>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` @@ -13,10 +13,10 @@ LL | fn assert_send() { } | ^^^^ required by this bound in `assert_send` error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object2.rs:12:5 + --> $DIR/kindck-send-object2.rs:12:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely + | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` = note: required for `Unique` to implement `Send` diff --git a/src/test/ui/kindck/kindck-send-owned.stderr b/src/test/ui/kindck/kindck-send-owned.stderr index 076c42959826d..b03f56465cea0 100644 --- a/src/test/ui/kindck/kindck-send-owned.stderr +++ b/src/test/ui/kindck/kindck-send-owned.stderr @@ -1,8 +1,8 @@ error[E0277]: `*mut u8` cannot be sent between threads safely - --> $DIR/kindck-send-owned.rs:12:5 + --> $DIR/kindck-send-owned.rs:12:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely + | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut u8` = note: required for `Unique<*mut u8>` to implement `Send` diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr index 6b87da0c040d5..33f82448dd2ac 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_` - --> $DIR/branches.rs:19:28 + --> $DIR/branches.rs:19:9 | LL | std::iter::empty().collect() - | ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Bar` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<_>` is not implemented for `Bar` note: required by a bound in `collect` diff --git a/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr b/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr index 42a1f782d299d..57978edf2bf05 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_` - --> $DIR/recursion4.rs:10:28 + --> $DIR/recursion4.rs:10:9 | LL | x = std::iter::empty().collect(); - | ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Foo` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<_>` is not implemented for `Foo` note: required by a bound in `collect` @@ -12,10 +14,12 @@ LL | fn collect>(self) -> B | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_` - --> $DIR/recursion4.rs:19:28 + --> $DIR/recursion4.rs:19:9 | LL | x = std::iter::empty().collect(); - | ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `impl Debug` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<_>` is not implemented for `impl Debug` note: required by a bound in `collect` diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index e0f8a5447b081..754735988e48e 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7 | LL | x.foo(); - | ^^^ + | - ^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Vec<_>: Foo` found --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1 diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 410ea4b0b3439..32ec9ecc474fb 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -1,10 +1,12 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/E0631.rs:7:5 + --> $DIR/E0631.rs:7:9 | LL | foo(|_: isize| {}); - | ^^^ ---------- found signature defined here - | | - | expected due to this + | --- ----------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `fn(usize) -> _` found closure signature `fn(isize) -> _` @@ -15,12 +17,14 @@ LL | fn foo(_: F) {} | ^^^^^^^^^ required by this bound in `foo` error[E0631]: type mismatch in closure arguments - --> $DIR/E0631.rs:8:5 + --> $DIR/E0631.rs:8:9 | LL | bar(|_: isize| {}); - | ^^^ ---------- found signature defined here - | | - | expected due to this + | --- ----------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `fn(usize) -> _` found closure signature `fn(isize) -> _` diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index a02ec81983883..c194e1dbc9a43 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -46,12 +46,14 @@ LL | [1, 2, 3].sort_by(|tuple, tuple2| panic!()); | ~~~~~~~~~~~~~~~ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:13:5 + --> $DIR/closure-arg-count.rs:13:7 | LL | f(|| panic!()); - | ^ -- takes 0 arguments - | | - | expected closure that takes 1 argument + | - --^^^^^^^^^ + | | | + | | expected closure that takes 1 argument + | | takes 0 arguments + | required by a bound introduced by this call | note: required by a bound in `f` --> $DIR/closure-arg-count.rs:3:9 @@ -64,12 +66,14 @@ LL | f(|_| panic!()); | ~~~ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:15:5 + --> $DIR/closure-arg-count.rs:15:9 | LL | f( move || panic!()); - | ^ ---------- takes 0 arguments - | | - | expected closure that takes 1 argument + | - ----------^^^^^^^^^ + | | | + | | expected closure that takes 1 argument + | | takes 0 arguments + | required by a bound introduced by this call | note: required by a bound in `f` --> $DIR/closure-arg-count.rs:3:9 diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 71469bfec2d39..0df71af3e70f7 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -1,10 +1,12 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/closure-arg-type-mismatch.rs:3:14 + --> $DIR/closure-arg-type-mismatch.rs:3:18 | LL | a.iter().map(|_: (u32, u32)| 45); - | ^^^ --------------- found signature defined here - | | - | expected due to this + | --- ---------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `fn((u32, u32)) -> _` @@ -15,12 +17,14 @@ LL | F: FnMut(Self::Item) -> B, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` error[E0631]: type mismatch in closure arguments - --> $DIR/closure-arg-type-mismatch.rs:4:14 + --> $DIR/closure-arg-type-mismatch.rs:4:18 | LL | a.iter().map(|_: &(u16, u16)| 45); - | ^^^ ---------------- found signature defined here - | | - | expected due to this + | --- ----------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `for<'r> fn(&'r (u16, u16)) -> _` @@ -31,12 +35,14 @@ LL | F: FnMut(Self::Item) -> B, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` error[E0631]: type mismatch in closure arguments - --> $DIR/closure-arg-type-mismatch.rs:5:14 + --> $DIR/closure-arg-type-mismatch.rs:5:18 | LL | a.iter().map(|_: (u16, u16)| 45); - | ^^^ --------------- found signature defined here - | | - | expected due to this + | --- ---------------^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `fn((u16, u16)) -> _` diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index b11ea97d160be..86348b5047528 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -1,10 +1,12 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/issue-36053-2.rs:7:32 + --> $DIR/issue-36053-2.rs:7:39 | LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); - | ^^^^^^ --------- found signature defined here - | | - | expected due to this + | ------ ---------^^^^^ + | | | + | | expected due to this + | | found signature defined here + | required by a bound introduced by this call | = note: expected closure signature `for<'r> fn(&'r &str) -> _` found closure signature `for<'r> fn(&'r str) -> _` diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr index c2515c40b1d77..36748fae13c94 100644 --- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -1,8 +1,10 @@ error[E0277]: `Foo` doesn't implement `Debug` - --> $DIR/method-help-unsatisfied-bound.rs:5:7 + --> $DIR/method-help-unsatisfied-bound.rs:5:5 | LL | a.unwrap(); - | ^^^^^^ `Foo` cannot be formatted using `{:?}` + | ^ ------ required by a bound introduced by this call + | | + | `Foo` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Foo` = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` diff --git a/src/test/ui/never_type/defaulted-never-note.fallback.stderr b/src/test/ui/never_type/defaulted-never-note.fallback.stderr index 4c8b492247352..283aca1b084ef 100644 --- a/src/test/ui/never_type/defaulted-never-note.fallback.stderr +++ b/src/test/ui/never_type/defaulted-never-note.fallback.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied - --> $DIR/defaulted-never-note.rs:30:5 + --> $DIR/defaulted-never-note.rs:30:9 | LL | foo(_x); - | ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` + | --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` + | | + | required by a bound introduced by this call | = help: the trait `ImplementedForUnitButNotNever` is implemented for `()` = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) diff --git a/src/test/ui/never_type/defaulted-never-note.rs b/src/test/ui/never_type/defaulted-never-note.rs index aefc739a0a0b0..d30ffcd3846e7 100644 --- a/src/test/ui/never_type/defaulted-never-note.rs +++ b/src/test/ui/never_type/defaulted-never-note.rs @@ -32,6 +32,7 @@ fn smeg() { //[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented //[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()` //[fallback]~| NOTE this error might have been caused + //[fallback]~| NOTE required by a bound introduced by this call //[fallback]~| HELP did you intend } diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr index dee2b1d704b86..3215c4669d5e3 100644 --- a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `!: Test` is not satisfied - --> $DIR/diverging-fallback-no-leak.rs:17:5 + --> $DIR/diverging-fallback-no-leak.rs:17:23 | LL | unconstrained_arg(return); - | ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!` + | ----------------- ^^^^^^ the trait `Test` is not implemented for `!` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `Test`: () diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 54abed383000d..6a4726a8cc9e0 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -1,14 +1,19 @@ error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/feature-gate-never_type_fallback.rs:10:5 + --> $DIR/feature-gate-never_type_fallback.rs:10:9 | LL | foo(panic!()) - | ^^^ the trait `T` is not implemented for `()` + | --- ^^^^^^^^ + | | | + | | the trait `T` is not implemented for `()` + | | this tail expression is of type `_` + | required by a bound introduced by this call | note: required by a bound in `foo` --> $DIR/feature-gate-never_type_fallback.rs:13:16 | LL | fn foo(_: impl T) {} | ^ required by this bound in `foo` + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr index 249c2fe2fa74e..c864b93dbbbe1 100644 --- a/src/test/ui/no-send-res-ports.stderr +++ b/src/test/ui/no-send-res-ports.stderr @@ -1,10 +1,17 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/no-send-res-ports.rs:25:5 + --> $DIR/no-send-res-ports.rs:25:19 | -LL | thread::spawn(move|| { - | ^^^^^^^^^^^^^ ------ within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]` - | | - | `Rc<()>` cannot be sent between threads safely +LL | thread::spawn(move|| { + | ------------- ^----- + | | | + | _____|_____________within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]` + | | | + | | required by a bound introduced by this call +LL | | +LL | | let y = x; +LL | | println!("{:?}", y); +LL | | }); + | |_____^ `Rc<()>` cannot be sent between threads safely | = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>` note: required because it appears within the type `Port<()>` diff --git a/src/test/ui/not-clone-closure.stderr b/src/test/ui/not-clone-closure.stderr index 37d94cf0ebd8c..f61ee661bb7ed 100644 --- a/src/test/ui/not-clone-closure.stderr +++ b/src/test/ui/not-clone-closure.stderr @@ -1,11 +1,13 @@ error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]` - --> $DIR/not-clone-closure.rs:11:23 + --> $DIR/not-clone-closure.rs:11:17 | LL | let hello = move || { | ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]` ... LL | let hello = hello.clone(); - | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S` + | ^^^^^ ----- required by a bound introduced by this call + | | + | within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S` | note: required because it's used within this closure --> $DIR/not-clone-closure.rs:7:17 diff --git a/src/test/ui/not-panic/not-panic-safe-2.stderr b/src/test/ui/not-panic/not-panic-safe-2.stderr index 43bb31afa6f54..3b0f83b3b9a47 100644 --- a/src/test/ui/not-panic/not-panic-safe-2.stderr +++ b/src/test/ui/not-panic/not-panic-safe-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-2.rs:10:5 + --> $DIR/not-panic-safe-2.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-2.rs:10:5 + --> $DIR/not-panic-safe-2.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/not-panic/not-panic-safe-3.stderr b/src/test/ui/not-panic/not-panic-safe-3.stderr index ef1d1baf58bfc..9e9a12764a4b6 100644 --- a/src/test/ui/not-panic/not-panic-safe-3.stderr +++ b/src/test/ui/not-panic/not-panic-safe-3.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-3.rs:10:5 + --> $DIR/not-panic-safe-3.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-3.rs:10:5 + --> $DIR/not-panic-safe-3.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/not-panic/not-panic-safe-4.stderr b/src/test/ui/not-panic/not-panic-safe-4.stderr index a398b44d339e7..fc1c594d0d422 100644 --- a/src/test/ui/not-panic/not-panic-safe-4.stderr +++ b/src/test/ui/not-panic/not-panic-safe-4.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-4.rs:9:5 + --> $DIR/not-panic-safe-4.rs:9:14 | LL | assert::<&RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-4.rs:9:5 + --> $DIR/not-panic-safe-4.rs:9:14 | LL | assert::<&RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/not-panic/not-panic-safe-5.stderr b/src/test/ui/not-panic/not-panic-safe-5.stderr index 9617d5dfde40d..cb78370b48a6c 100644 --- a/src/test/ui/not-panic/not-panic-safe-5.stderr +++ b/src/test/ui/not-panic/not-panic-safe-5.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-5.rs:9:5 + --> $DIR/not-panic-safe-5.rs:9:14 | LL | assert::<*const UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required for `*const UnsafeCell` to implement `UnwindSafe` diff --git a/src/test/ui/not-panic/not-panic-safe-6.stderr b/src/test/ui/not-panic/not-panic-safe-6.stderr index 09204d942d235..7986e341eb01f 100644 --- a/src/test/ui/not-panic/not-panic-safe-6.stderr +++ b/src/test/ui/not-panic/not-panic-safe-6.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-6.rs:9:5 + --> $DIR/not-panic-safe-6.rs:9:14 | LL | assert::<*mut RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-6.rs:9:5 + --> $DIR/not-panic-safe-6.rs:9:14 | LL | assert::<*mut RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index 6e3601d7bf4b5..ad0cebb37360a 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -11,6 +11,17 @@ LL | Index::index(&[] as &[i32], 2u32); <[i32] as Index>> <[i32] as Index>> +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/multiple-impls.rs:33:5 + | +LL | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ trait message + | + = help: the trait `Index` is not implemented for `[i32]` + = help: the following other types implement trait `Index`: + <[i32] as Index>> + <[i32] as Index>> + error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:35:18 | @@ -24,6 +35,17 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); <[i32] as Index>> <[i32] as Index>> +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:35:5 + | +LL | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index>` is not implemented for `[i32]` + = help: the following other types implement trait `Index`: + <[i32] as Index>> + <[i32] as Index>> + error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:37:18 | @@ -37,6 +59,17 @@ LL | Index::index(&[] as &[i32], Bar(2u32)); <[i32] as Index>> <[i32] as Index>> -error: aborting due to 3 previous errors +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:37:5 + | +LL | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + = help: the following other types implement trait `Index`: + <[i32] as Index>> + <[i32] as Index>> + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index 396c062cfe2ac..769a3d77a5726 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -9,6 +9,15 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` -error: aborting due to previous error +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/on-impl.rs:22:5 + | +LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index` is not implemented for `[i32]` + = help: the trait `Index` is implemented for `[i32]` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr index 85c9fe409dbe9..a00f37ed6069c 100644 --- a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr +++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -107,10 +107,10 @@ LL | V = [Vec::new; { [0].len() ].len() as isize, | closing delimiter possibly meant for this error[E0282]: type annotations needed - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:26 | LL | V = [Vec::new; { [].len() ].len() as isize, - | ^^^ cannot infer type for type parameter `T` + | ^^ cannot infer type for type parameter `T` error[E0282]: type annotations needed --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14 diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr index d96e863939c02..683162a5daec6 100644 --- a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr @@ -8,7 +8,7 @@ LL | drop::(_x1); | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment ... LL | accept_fn_mut(&c1); - | ------------- the requirement to implement `FnMut` derives from here + | --- the requirement to implement `FnMut` derives from here error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> $DIR/move-ref-patterns-closure-captures.rs:9:14 @@ -20,7 +20,7 @@ LL | drop::(_x1); | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment ... LL | accept_fn(&c1); - | --------- the requirement to implement `Fn` derives from here + | --- the requirement to implement `Fn` derives from here error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` --> $DIR/move-ref-patterns-closure-captures.rs:20:14 @@ -32,7 +32,7 @@ LL | drop::<&mut U>(_x2); | --- closure is `FnMut` because it mutates the variable `_x2` here ... LL | accept_fn(&c2); - | --------- the requirement to implement `Fn` derives from here + | --- the requirement to implement `Fn` derives from here error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index ec724cc9675f1..fddc8d37f2ff7 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied - --> $DIR/const-default-method-bodies.rs:24:18 + --> $DIR/const-default-method-bodies.rs:24:5 | LL | NonConstImpl.a(); - | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` + | ^^^^^^^^^^^^ - required by a bound introduced by this call + | | + | the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` | note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const` - --> $DIR/const-default-method-bodies.rs:24:18 + --> $DIR/const-default-method-bodies.rs:24:5 | LL | NonConstImpl.a(); - | ^ + | ^^^^^^^^^^^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | const fn test() where NonConstImpl: ~const ConstDefaultFn { diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index 174c62912fcee..d4fa44b4bfcb5 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^^^^^ ---- required by a bound introduced by this call + | | + | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const` - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ + | ^^^^^^^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait { diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr index 4619dd1138e1f..71ecd9b06945f 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^^^^^ ---- required by a bound introduced by this call + | | + | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const` - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ + | ^^^^^^^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait { diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index b229053eb50cf..85285ba849777 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9 | LL | ().a() - | ^ the trait `~const Tr` is not implemented for `()` + | ^^ - required by a bound introduced by this call + | | + | the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9 | LL | ().a() - | ^ + | ^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | pub trait Tr where (): ~const Tr { diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 019305def2932..6daa74657bd8e 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -28,6 +28,17 @@ note: required by a bound in `core::str::::get` LL | pub const fn get>(&self, i: I) -> Option<&I::Output> { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get` +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-idx.rs:4:15 + | +LL | let _ = s.get(4); + | ^^^ string indices are ranges of `usize` + | + = help: the trait `SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + for more information, see chapter 8 in The Book: + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-idx.rs:5:29 | @@ -46,6 +57,17 @@ note: required by a bound in `core::str::::get_unchecked` LL | pub const unsafe fn get_unchecked>(&self, i: I) -> &I::Output { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked` +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-idx.rs:5:15 + | +LL | let _ = s.get_unchecked(4); + | ^^^^^^^^^^^^^ string indices are ranges of `usize` + | + = help: the trait `SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + for more information, see chapter 8 in The Book: + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-idx.rs:6:19 | @@ -55,6 +77,6 @@ LL | let _: u8 = s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required for `str` to implement `Index` -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index b165c482590a2..d063088aded83 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -52,6 +52,17 @@ note: required by a bound in `core::str::::get_mut` LL | pub const fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_mut` +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-mut-idx.rs:9:7 + | +LL | s.get_mut(1); + | ^^^^^^^ string indices are ranges of `usize` + | + = help: the trait `SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + for more information, see chapter 8 in The Book: + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-mut-idx.rs:11:25 | @@ -70,6 +81,17 @@ note: required by a bound in `core::str::::get_unchecked_mut` LL | pub const unsafe fn get_unchecked_mut>( | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked_mut` +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-mut-idx.rs:11:7 + | +LL | s.get_unchecked_mut(1); + | ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize` + | + = help: the trait `SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + for more information, see chapter 8 in The Book: + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-mut-idx.rs:13:7 | @@ -79,6 +101,6 @@ LL | s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required for `str` to implement `Index` -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr index ba6af8f15fa89..864ab053520db 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `for<'b> &'b S: Trait` is not satisfied - --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:5 + --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:14 | LL | foo::(s); - | ^^^^^^^^ the trait `for<'b> Trait` is not implemented for `&'b S` + | -------- ^ the trait `for<'b> Trait` is not implemented for `&'b S` + | | + | required by a bound introduced by this call | = help: the trait `Trait` is implemented for `&'a mut S` = note: `for<'b> Trait` is implemented for `&'b mut S`, but not for `&'b S` diff --git a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr index a5e6f5b5ffcb0..684db23e1355f 100644 --- a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied - --> $DIR/issue-71394-no-from-impl.rs:3:25 + --> $DIR/issue-71394-no-from-impl.rs:3:20 | LL | let _: &[i8] = data.into(); - | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]` + | ^^^^ ---- required by a bound introduced by this call + | | + | the trait `From<&[u8]>` is not implemented for `&[i8]` | = help: the following other types implement trait `From`: <[T; LANES] as From>> diff --git a/src/test/ui/suggestions/issue-84973-blacklist.stderr b/src/test/ui/suggestions/issue-84973-blacklist.stderr index ae0d3efca4727..c20cc816484b4 100644 --- a/src/test/ui/suggestions/issue-84973-blacklist.stderr +++ b/src/test/ui/suggestions/issue-84973-blacklist.stderr @@ -31,10 +31,12 @@ LL | #[derive(Clone)] | error[E0277]: `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` cannot be unpinned - --> $DIR/issue-84973-blacklist.rs:17:5 + --> $DIR/issue-84973-blacklist.rs:17:13 | LL | f_unpin(static || { yield; }); - | ^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` + | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required by a bound in `f_unpin` diff --git a/src/test/ui/suggestions/issue-84973.stderr b/src/test/ui/suggestions/issue-84973.stderr index 24c989ec3e86d..ad8558599080b 100644 --- a/src/test/ui/suggestions/issue-84973.stderr +++ b/src/test/ui/suggestions/issue-84973.stderr @@ -1,11 +1,10 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied - --> $DIR/issue-84973.rs:6:24 + --> $DIR/issue-84973.rs:6:13 | LL | let o = Other::new(f); - | ---------- ^ expected an implementor of trait `SomeTrait` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^ the trait `SomeTrait` is not implemented for `Fancy` | + = help: the trait `SomeTrait` is implemented for `&'a Fancy` note: required by a bound in `Other::<'a, G>::new` --> $DIR/issue-84973.rs:25:8 | @@ -14,10 +13,6 @@ LL | G: SomeTrait, LL | { LL | pub fn new(g: G) -> Self { | --- required by a bound in this -help: consider borrowing here - | -LL | let o = Other::new(&f); - | + error: aborting due to previous error diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index d121932c842e3..420be973b724e 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:17:29 + --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | LL | let fp = BufWriter::new(fp); - | -------------- ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` | = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` note: required by a bound in `BufWriter::::new` @@ -13,6 +11,19 @@ note: required by a bound in `BufWriter::::new` LL | impl BufWriter { | ^^^^^ required by this bound in `BufWriter::::new` +error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied + --> $DIR/mut-borrow-needed-by-trait.rs:17:14 + | +LL | let fp = BufWriter::new(fp); + | ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` + | + = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` +note: required by a bound in `BufWriter` + --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL + | +LL | pub struct BufWriter { + | ^^^^^ required by this bound in `BufWriter` + error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | @@ -42,7 +53,7 @@ LL | pub struct BufWriter { which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr index 6b6e406130ec2..6ce9bfd9dcaa2 100644 --- a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr +++ b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr @@ -2,9 +2,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation --> $DIR/suggest-borrow-to-dyn-object.rs:12:11 | LL | check(s); - | ----- ^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^ doesn't have a size known at compile-time | = help: within `OsStr`, the trait `Sized` is not implemented for `[u8]` = note: required because it appears within the type `OsStr` diff --git a/src/test/ui/suggestions/suggest-change-mut.stderr b/src/test/ui/suggestions/suggest-change-mut.stderr index 889b11a741084..671596fe45520 100644 --- a/src/test/ui/suggestions/suggest-change-mut.stderr +++ b/src/test/ui/suggestions/suggest-change-mut.stderr @@ -1,29 +1,19 @@ error[E0277]: the trait bound `&T: std::io::Read` is not satisfied - --> $DIR/suggest-change-mut.rs:12:48 + --> $DIR/suggest-change-mut.rs:12:33 | LL | let mut stream_reader = BufReader::new(&stream); - | -------------- ^^^^^^^ the trait `std::io::Read` is not implemented for `&T` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^ the trait `std::io::Read` is not implemented for `&T` | + = note: `std::io::Read` is implemented for `&mut T`, but not for `&T` note: required by a bound in `BufReader::::new` --> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL | LL | impl BufReader { | ^^^^ required by this bound in `BufReader::::new` -help: consider removing the leading `&`-reference - | -LL - let mut stream_reader = BufReader::new(&stream); -LL + let mut stream_reader = BufReader::new(stream); - | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | fn issue_81421(mut stream: T) where &T: std::io::Read { | +++++++++++++++++++++++ -help: consider changing this borrow's mutability - | -LL | let mut stream_reader = BufReader::new(&mut stream); - | ~~~~ error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its trait bounds were not satisfied --> $DIR/suggest-change-mut.rs:16:23 diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr index bfbbe7fd25702..fa7a8a2a09335 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/check-trait-object-bounds-1.rs:12:5 + --> $DIR/check-trait-object-bounds-1.rs:12:9 | LL | f::>(); - | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `f` diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr index 46e8ce7887493..4084f69a6f04b 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr @@ -1,8 +1,8 @@ error[E0277]: expected a `FnOnce<(&i32,)>` closure, found `i32` - --> $DIR/check-trait-object-bounds-2.rs:13:5 + --> $DIR/check-trait-object-bounds-2.rs:13:9 | LL | f:: X<'x, F = i32>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32` | = help: the trait `for<'r> FnOnce<(&'r i32,)>` is not implemented for `i32` note: required by a bound in `f` diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr index 3ca36d5d2ff19..4891ee9c29f7e 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/check-trait-object-bounds-4.rs:15:5 + --> $DIR/check-trait-object-bounds-4.rs:15:9 | LL | f::>(); - | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `f` diff --git a/src/test/ui/traits/bad-method-typaram-kind.stderr b/src/test/ui/traits/bad-method-typaram-kind.stderr index 8befa4c5f738b..56acfbe80d03f 100644 --- a/src/test/ui/traits/bad-method-typaram-kind.stderr +++ b/src/test/ui/traits/bad-method-typaram-kind.stderr @@ -1,8 +1,8 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/bad-method-typaram-kind.rs:2:7 + --> $DIR/bad-method-typaram-kind.rs:2:13 | LL | 1.bar::(); - | ^^^ `T` cannot be sent between threads safely + | ^ `T` cannot be sent between threads safely | note: required by a bound in `Bar::bar` --> $DIR/bad-method-typaram-kind.rs:6:14 diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs index 5ba189aa82a41..f9a9347641143 100644 --- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs +++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs @@ -2,7 +2,6 @@ fn strip_lf(s: &str) -> &str { s.strip_suffix(b'\n').unwrap_or(s) //~^ ERROR expected a `FnMut<(char,)>` closure, found `u8` //~| NOTE expected an `FnMut<(char,)>` closure, found `u8` - //~| NOTE required by a bound introduced by this call //~| HELP the trait `FnMut<(char,)>` is not implemented for `u8` //~| HELP the following other types implement trait `Pattern<'a>`: //~| NOTE required for `u8` to implement `Pattern<'_>` diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr index 41120c09fb164..ce9ab2d811ae1 100644 --- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr +++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr @@ -1,10 +1,8 @@ error[E0277]: expected a `FnMut<(char,)>` closure, found `u8` - --> $DIR/assoc-fn-bound-root-obligation.rs:2:20 + --> $DIR/assoc-fn-bound-root-obligation.rs:2:7 | LL | s.strip_suffix(b'\n').unwrap_or(s) - | ------------ ^^^^^ expected an `FnMut<(char,)>` closure, found `u8` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^ expected an `FnMut<(char,)>` closure, found `u8` | = help: the trait `FnMut<(char,)>` is not implemented for `u8` = help: the following other types implement trait `Pattern<'a>`: diff --git a/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr index 57b2587ae5ccd..e8d90fb336e19 100644 --- a/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr +++ b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11 | LL | thing.method(42); - | ^^^^^^ + | ----- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:7:1 diff --git a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr index cab0ccdf710da..28c7c85d48416 100644 --- a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr +++ b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr @@ -1,18 +1,22 @@ error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:26:7 + --> $DIR/repeated-supertrait-ambig.rs:26:5 | LL | c.same_as(22) - | ^^^^^^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | ^ ------- required by a bound introduced by this call + | | + | the trait `CompareTo` is not implemented for `dyn CompareToInts` | = help: the following other types implement trait `CompareTo`: > > error[E0277]: the trait bound `C: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:30:7 + --> $DIR/repeated-supertrait-ambig.rs:30:5 | LL | c.same_as(22) - | ^^^^^^^ the trait `CompareTo` is not implemented for `C` + | ^ ------- required by a bound introduced by this call + | | + | the trait `CompareTo` is not implemented for `C` | help: consider further restricting this bound | @@ -30,10 +34,12 @@ LL | ::same_as(c, 22) > error[E0277]: the trait bound `C: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:38:5 + --> $DIR/repeated-supertrait-ambig.rs:38:24 | LL | CompareTo::same_as(c, 22) - | ^^^^^^^^^^^^^^^^^^ the trait `CompareTo` is not implemented for `C` + | ------------------ ^ the trait `CompareTo` is not implemented for `C` + | | + | required by a bound introduced by this call | help: consider further restricting this bound | @@ -41,10 +47,12 @@ LL | fn with_ufcs2>(c: &C) -> bool { | ++++++++++++++++ error[E0277]: the trait bound `i64: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:42:23 + --> $DIR/repeated-supertrait-ambig.rs:42:16 | LL | assert_eq!(22_i64.same_as(22), true); - | ^^^^^^^ the trait `CompareTo` is not implemented for `i64` + | ^^^^^^ ------- required by a bound introduced by this call + | | + | the trait `CompareTo` is not implemented for `i64` | = help: the following other types implement trait `CompareTo`: > diff --git a/src/test/ui/traits/issue-71136.stderr b/src/test/ui/traits/issue-71136.stderr index f541733929d36..a8a46ec11c800 100644 --- a/src/test/ui/traits/issue-71136.stderr +++ b/src/test/ui/traits/issue-71136.stderr @@ -1,18 +1,14 @@ -error[E0277]: the trait bound `Foo: Clone` is not satisfied +error[E0277]: the trait bound `Vec: Clone` is not satisfied --> $DIR/issue-71136.rs:5:5 | LL | #[derive(Clone)] | ----- in this derive macro expansion LL | struct FooHolster { LL | the_foos: Vec, - | ^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Foo` + | ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Clone` | = note: required for `Vec` to implement `Clone` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `Foo` with `#[derive(Clone)]` - | -LL | #[derive(Clone)] - | error: aborting due to previous error diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 2b832e27c5224..b990cef318bcc 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-77982.rs:8:10 | LL | opts.get(opt.as_ref()); - | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get` + | ^^^ ------------ type must be known at this point + | | + | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: - impl Borrow for String; @@ -13,7 +15,7 @@ note: required by a bound in `HashMap::::get` | LL | K: Borrow, | ^^^^^^^^^ required by this bound in `HashMap::::get` -help: consider specifying the type argument in the function call +help: consider specifying the generic argument | LL | opts.get::(opt.as_ref()); | +++++ @@ -22,8 +24,9 @@ error[E0283]: type annotations needed --> $DIR/issue-77982.rs:8:10 | LL | opts.get(opt.as_ref()); - | ^^^ ------ type must be known at this point - | | + | ^^^ --- ------ required by a bound introduced by this call + | | | + | | type must be known at this point | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: @@ -59,7 +62,9 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:36:9 | LL | let _ = ().foo(); - | ^ --- type must be known at this point + | ^ -- --- required by a bound introduced by this call + | | + | type must be known at this point | note: multiple `impl`s satisfying `(): Foo<'_, _>` found --> $DIR/issue-77982.rs:29:1 @@ -77,7 +82,9 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:40:9 | LL | let _ = (&()).bar(); - | ^ --- type must be known at this point + | ^ ----- --- required by a bound introduced by this call + | | + | type must be known at this point | note: multiple `impl`s satisfying `&(): Bar<'_, _>` found --> $DIR/issue-77982.rs:32:1 diff --git a/src/test/ui/traits/issue-97576.stderr b/src/test/ui/traits/issue-97576.stderr index 9062a0fab630a..146d38d076a3c 100644 --- a/src/test/ui/traits/issue-97576.stderr +++ b/src/test/ui/traits/issue-97576.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `String: From` is not satisfied - --> $DIR/issue-97576.rs:8:22 + --> $DIR/issue-97576.rs:8:18 | LL | bar: bar.into(), - | ^^^^ the trait `From` is not implemented for `String` + | ^^^ ---- required by a bound introduced by this call + | | + | the trait `From` is not implemented for `String` | = note: required for `impl ToString` to implement `Into` diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr index cbec359342148..83fb04646c53f 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/multidispatch-convert-ambig-dest.rs:26:5 | LL | test(22, std::default::Default::default()); - | ^^^^ cannot infer type of the type parameter `U` declared on the function `test` + | ^^^^ -- type must be known at this point + | | + | cannot infer type of the type parameter `U` declared on the function `test` | note: multiple `impl`s satisfying `i32: Convert<_>` found --> $DIR/multidispatch-convert-ambig-dest.rs:8:1 @@ -30,10 +32,10 @@ LL | fn test(_: T, _: U) | ---- required by a bound in this LL | where T : Convert | ^^^^^^^^^^ required by this bound in `test` -help: consider specifying the type arguments in the function call +help: consider specifying the generic arguments | -LL | test::(22, std::default::Default::default()); - | ++++++++ +LL | test::(22, std::default::Default::default()); + | ++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr index 53178328c56af..294af65347592 100644 --- a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr +++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:21:7 | LL | a.method(); - | ^^^^^^ + | - ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `B: I<_>` found --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1 diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr index cbf0938665447..9e221daabe545 100644 --- a/src/test/ui/traits/object/enforce-supertrait-projection.stderr +++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr @@ -1,12 +1,14 @@ error[E0271]: type mismatch resolving ` as SuperTrait>::A == B` - --> $DIR/enforce-supertrait-projection.rs:9:17 + --> $DIR/enforce-supertrait-projection.rs:9:42 | LL | fn transmute(x: A) -> B { | - - expected type parameter | | | found type parameter LL | foo::>(x) - | ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A` + | ------------------------------------ ^ expected type parameter `B`, found type parameter `A` + | | + | required by a bound introduced by this call | = note: expected type parameter `B` found type parameter `A` diff --git a/src/test/ui/traits/suggest-deferences/issue-39029.fixed b/src/test/ui/traits/suggest-deferences/issue-39029.fixed index a1abf668b8b6e..90d097105edc6 100644 --- a/src/test/ui/traits/suggest-deferences/issue-39029.fixed +++ b/src/test/ui/traits/suggest-deferences/issue-39029.fixed @@ -13,6 +13,6 @@ impl std::ops::Deref for NoToSocketAddrs { fn main() { let _works = TcpListener::bind("some string"); let bad = NoToSocketAddrs("bad".to_owned()); - let _errors = TcpListener::bind(&*bad); + let _errors = TcpListener::bind(&bad); //~^ ERROR the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied } diff --git a/src/test/ui/traits/suggest-deferences/issue-39029.stderr b/src/test/ui/traits/suggest-deferences/issue-39029.stderr index eb2b88059d485..1317a8445f513 100644 --- a/src/test/ui/traits/suggest-deferences/issue-39029.stderr +++ b/src/test/ui/traits/suggest-deferences/issue-39029.stderr @@ -1,11 +1,21 @@ error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied - --> $DIR/issue-39029.rs:16:37 + --> $DIR/issue-39029.rs:16:19 | LL | let _errors = TcpListener::bind(&bad); | ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs` | | | required by a bound introduced by this call | + = help: the following other types implement trait `ToSocketAddrs`: + &'a [std::net::SocketAddr] + &T + (&str, u16) + (IpAddr, u16) + (Ipv4Addr, u16) + (Ipv6Addr, u16) + (String, u16) + SocketAddrV4 + and 4 others = note: required for `&NoToSocketAddrs` to implement `ToSocketAddrs` note: required by a bound in `TcpListener::bind` --> $SRC_DIR/std/src/net/tcp.rs:LL:COL diff --git a/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr b/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr index 68b31a1ca34e3..07f7bfb7cb461 100644 --- a/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr +++ b/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:45:11 | LL | thing.method(); - | ^^^^^^ + | ----- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -32,7 +34,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:48:11 | LL | thing.mut_method(); - | ^^^^^^^^^^ + | ----- ^^^^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -51,7 +55,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:49:11 | LL | thing.by_self(); - | ^^^^^^^ + | ----- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:22:1 @@ -70,7 +76,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:52:14 | LL | deref_to.method(); - | ^^^^^^ + | -------- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -89,7 +97,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:53:14 | LL | deref_to.mut_method(); - | ^^^^^^^^^^ + | -------- ^^^^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -108,7 +118,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:54:14 | LL | deref_to.by_self(); - | ^^^^^^^ + | -------- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:22:1 @@ -127,7 +139,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:57:20 | LL | deref_deref_to.method(); - | ^^^^^^ + | -------------- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -146,7 +160,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:58:20 | LL | deref_deref_to.mut_method(); - | ^^^^^^^^^^ + | -------------- ^^^^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -165,7 +181,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:59:20 | LL | deref_deref_to.by_self(); - | ^^^^^^^ + | -------------- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:22:1 diff --git a/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr b/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr index 27518a54e7507..bcc25e103b112 100644 --- a/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr +++ b/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:45:15 | LL | ref_thing.method(); - | ^^^^^^ + | --------- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -32,7 +34,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:48:15 | LL | ref_thing.by_self(); - | ^^^^^^^ + | --------- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 @@ -51,7 +55,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:51:15 | LL | mut_thing.method(); - | ^^^^^^ + | --------- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -70,7 +76,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:52:15 | LL | mut_thing.mut_method(); - | ^^^^^^^^^^ + | --------- ^^^^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -89,7 +97,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:53:15 | LL | mut_thing.by_self(); - | ^^^^^^^ + | --------- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 @@ -108,7 +118,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:56:14 | LL | deref_to.method(); - | ^^^^^^ + | -------- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -127,7 +139,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:57:14 | LL | deref_to.mut_method(); - | ^^^^^^^^^^ + | -------- ^^^^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -146,7 +160,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:58:14 | LL | deref_to.by_self(); - | ^^^^^^^ + | -------- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 @@ -165,7 +181,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:61:20 | LL | deref_deref_to.method(); - | ^^^^^^ + | -------------- ^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -184,7 +202,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:62:20 | LL | deref_deref_to.mut_method(); - | ^^^^^^^^^^ + | -------------- ^^^^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -203,7 +223,9 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:63:20 | LL | deref_deref_to.by_self(); - | ^^^^^^^ + | -------------- ^^^^^^^ + | | + | type must be known at this point | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 diff --git a/src/test/ui/traits/suggest-where-clause.stderr b/src/test/ui/traits/suggest-where-clause.stderr index d4d9b4967478a..747e2477b9cf1 100644 --- a/src/test/ui/traits/suggest-where-clause.stderr +++ b/src/test/ui/traits/suggest-where-clause.stderr @@ -19,13 +19,13 @@ LL + fn check() { | error[E0277]: the size for values of type `U` cannot be known at compilation time - --> $DIR/suggest-where-clause.rs:10:5 + --> $DIR/suggest-where-clause.rs:10:20 | LL | fn check() { | - this type parameter needs to be `std::marker::Sized` ... LL | mem::size_of::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^ doesn't have a size known at compile-time | note: required because it appears within the type `Misc` --> $DIR/suggest-where-clause.rs:3:8 diff --git a/src/test/ui/transmutability/references.stderr b/src/test/ui/transmutability/references.stderr index b1359ea586583..17ffcf64177e3 100644 --- a/src/test/ui/transmutability/references.stderr +++ b/src/test/ui/transmutability/references.stderr @@ -1,8 +1,8 @@ error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. - --> $DIR/references.rs:19:37 + --> $DIR/references.rs:19:52 | LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. + | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. | = help: the trait `BikeshedIntrinsicFrom<&'static Unit, assert::Context, true, true, true, true>` is not implemented for `&'static Unit` note: required by a bound in `is_maybe_transmutable` diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr index 6bb5e1f54272b..b9fca1a1b54b8 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr @@ -12,10 +12,10 @@ LL | fn is_sync() {} | ^^^^ required by this bound in `is_sync` error[E0277]: `UnsafeCell` cannot be shared between threads safely - --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:5 + --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:15 | LL | is_sync::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `UnsafeCell` cannot be shared between threads safely | = help: within `MyTypeWUnsafe`, the trait `Sync` is not implemented for `UnsafeCell` note: required because it appears within the type `MyTypeWUnsafe` @@ -30,10 +30,10 @@ LL | fn is_sync() {} | ^^^^ required by this bound in `is_sync` error[E0277]: `Managed` cannot be shared between threads safely - --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:5 + --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:15 | LL | is_sync::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely | = help: within `MyTypeManaged`, the trait `Sync` is not implemented for `Managed` note: required because it appears within the type `MyTypeManaged` diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr index c6f9b3661a232..4f721f987aee8 100644 --- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -1,8 +1,10 @@ error[E0277]: cannot add `u32` to `i32` - --> $DIR/ufcs-qpath-self-mismatch.rs:4:5 + --> $DIR/ufcs-qpath-self-mismatch.rs:4:28 | LL | >::add(1, 2); - | ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32` + | ---------------------- ^ no implementation for `i32 + u32` + | | + | required by a bound introduced by this call | = help: the trait `Add` is not implemented for `i32` = help: the following other types implement trait `Add`: diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr index 9a24fb8c2beec..d8e9776bb0063 100644 --- a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr +++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr @@ -1,8 +1,10 @@ error[E0308]: mismatched types - --> $DIR/non-tupled-arg-mismatch.rs:6:5 + --> $DIR/non-tupled-arg-mismatch.rs:6:7 | LL | a(|_: usize| {}); - | ^ types differ + | - ^^^^^^^^^^^^^ types differ + | | + | required by a bound introduced by this call | = note: expected trait `Fn` found trait `Fn<(usize,)>` diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr index 85ff49d61a3ff..4ea1ee3c37a7e 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -6,7 +6,7 @@ LL | let c = || drop(y.0); | | | this closure implements `FnOnce`, not `Fn` LL | foo(c); - | --- the requirement to implement `Fn` derives from here + | - the requirement to implement `Fn` derives from here error: aborting due to previous error diff --git a/src/test/ui/unsized-locals/unsized-exprs.stderr b/src/test/ui/unsized-locals/unsized-exprs.stderr index 6960255d98797..a7f57e3fd1566 100644 --- a/src/test/ui/unsized-locals/unsized-exprs.stderr +++ b/src/test/ui/unsized-locals/unsized-exprs.stderr @@ -12,9 +12,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation --> $DIR/unsized-exprs.rs:24:22 | LL | udrop::>(A { 0: *foo() }); - | ---------------- ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `A<[u8]>` diff --git a/src/test/ui/unsized/issue-30355.stderr b/src/test/ui/unsized/issue-30355.stderr index d7af558eef42a..f5491552a45d2 100644 --- a/src/test/ui/unsized/issue-30355.stderr +++ b/src/test/ui/unsized/issue-30355.stderr @@ -2,9 +2,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation --> $DIR/issue-30355.rs:5:8 | LL | &X(*Y) - | - ^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` = help: unsized fn params are gated as an unstable feature diff --git a/src/test/ui/unsized/issue-71659.stderr b/src/test/ui/unsized/issue-71659.stderr index d7b95f55769fd..50060e53a49d6 100644 --- a/src/test/ui/unsized/issue-71659.stderr +++ b/src/test/ui/unsized/issue-71659.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied - --> $DIR/issue-71659.rs:30:15 + --> $DIR/issue-71659.rs:30:13 | LL | let x = x.cast::<[i32]>(); - | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` + | ^ ---- required by a bound introduced by this call + | | + | the trait `CastTo<[i32]>` is not implemented for `dyn Foo` | note: required by a bound in `Cast::cast` --> $DIR/issue-71659.rs:19:15 diff --git a/src/test/ui/unsized/issue-75707.stderr b/src/test/ui/unsized/issue-75707.stderr index 7d0a2cb85b612..97618ed05ed38 100644 --- a/src/test/ui/unsized/issue-75707.stderr +++ b/src/test/ui/unsized/issue-75707.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `MyCall: Callback` is not satisfied - --> $DIR/issue-75707.rs:15:5 + --> $DIR/issue-75707.rs:15:9 | LL | f::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` | note: required by a bound in `f` --> $DIR/issue-75707.rs:9:9 diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr index 0221ef16b4965..b477260543258 100644 --- a/src/test/ui/unsized/unsized-fn-param.stderr +++ b/src/test/ui/unsized/unsized-fn-param.stderr @@ -2,9 +2,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:11:11 | LL | foo11("bar", &"baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` @@ -17,9 +15,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:13:19 | LL | foo12(&"bar", "baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` @@ -32,9 +28,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:16:11 | LL | foo21("bar", &"baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` @@ -47,9 +41,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:18:19 | LL | foo22(&"bar", "baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index c9510e92fecb4..dff1b0a5112a4 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -25,10 +25,10 @@ LL + fn foo2() { not_sized::>() } | error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/unsized-struct.rs:13:24 + --> $DIR/unsized-struct.rs:13:35 | LL | fn bar2() { is_sized::>() } - | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr index d64091b15eb1f..9ad1ac6b4df61 100644 --- a/src/test/ui/unsized/unsized3.stderr +++ b/src/test/ui/unsized/unsized3.stderr @@ -79,14 +79,12 @@ LL | fn f5(x: &Y) {} | ++++++++ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized3.rs:40:8 + --> $DIR/unsized3.rs:40:5 | LL | fn f9(x1: Box>) { | - this type parameter needs to be `std::marker::Sized` LL | f5(&(*x1, 34)); - | -- ^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^ doesn't have a size known at compile-time | note: required because it appears within the type `S` --> $DIR/unsized3.rs:28:8 @@ -106,9 +104,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim LL | fn f10(x1: Box>) { | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); - | -- ^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^^ doesn't have a size known at compile-time | note: required because it appears within the type `S` --> $DIR/unsized3.rs:28:8 diff --git a/src/test/ui/where-clauses/where-clause-method-substituion.stderr b/src/test/ui/where-clauses/where-clause-method-substituion.stderr index f431deee73f9a..8c47ed6d4317a 100644 --- a/src/test/ui/where-clauses/where-clause-method-substituion.stderr +++ b/src/test/ui/where-clauses/where-clause-method-substituion.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `X: Foo` is not satisfied - --> $DIR/where-clause-method-substituion.rs:20:7 + --> $DIR/where-clause-method-substituion.rs:20:16 | LL | 1.method::(); - | ^^^^^^ the trait `Foo` is not implemented for `X` + | ^ the trait `Foo` is not implemented for `X` | note: required by a bound in `Bar::method` --> $DIR/where-clause-method-substituion.rs:6:34 diff --git a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr index c13552bc26eee..e90502977ff6a 100644 --- a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr +++ b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `Bar: Eq` is not satisfied - --> $DIR/where-clauses-method-unsatisfied.rs:18:14 + --> $DIR/where-clauses-method-unsatisfied.rs:18:7 | LL | x.equals(&x); - | ------ ^^ the trait `Eq` is not implemented for `Bar` - | | - | required by a bound introduced by this call + | ^^^^^^ the trait `Eq` is not implemented for `Bar` | note: required by a bound in `Foo::::equals` --> $DIR/where-clauses-method-unsatisfied.rs:11:52 From d05fea6ac47c07606190803bc6ec4e2d7c206351 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 16 Aug 2022 23:13:23 +0000 Subject: [PATCH 02/16] Account for relative paths --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 15 ++++++++++++--- src/test/ui/async-await/issue-72442.stderr | 6 ++++-- .../ui/async-await/pin-needed-to-poll-2.stderr | 6 ++++-- src/test/ui/box/into-boxed-slice-fail.stderr | 12 ++++++++---- src/test/ui/chalkify/bugs/async.stderr | 11 ++++++++--- src/test/ui/dst/dst-rvalue.stderr | 12 ++++++++---- src/test/ui/inference/issue-86162-2.stderr | 2 +- src/test/ui/issues/issue-17651.stderr | 6 ++++-- src/test/ui/proc-macro/signature.stderr | 5 ++++- .../trait-where-clause.stderr | 12 ++++++------ .../expected-boxed-future-isnt-pinned.stderr | 12 ++++++++---- src/test/ui/suggestions/issue-84973.stderr | 11 ++++++++--- .../mut-borrow-needed-by-trait.stderr | 6 ++++-- .../ui/suggestions/suggest-change-mut.stderr | 16 +++++++++++++--- .../inheritance/repeated-supertrait-ambig.stderr | 6 ++++-- src/test/ui/traits/issue-77982.stderr | 16 ++++++++++++++-- .../traits/suggest-deferences/issue-39029.fixed | 2 +- .../traits/suggest-deferences/issue-39029.stderr | 12 +----------- 18 files changed, 112 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 1d59840bf0ae9..550c3395d3ca6 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1645,7 +1645,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }) }); - let fallback_param_to_point_at = predicate_substs.types().find_map(|ty| { ty.walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() @@ -1660,8 +1659,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let hir = self.tcx.hir(); + match hir.get(hir_id) { - hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(hir::QPath::Resolved(_, path)), hir_id, .. }) => { + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(qpath), hir_id, .. }) => { if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(callee, args), hir_id: call_hir_id, .. }) = hir.get(hir.get_parent_node(*hir_id)) && callee.hir_id == *hir_id @@ -1677,12 +1677,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - if let Some(param_to_point_at) = param_to_point_at + if let hir::QPath::Resolved(_, path) = qpath + && let Some(param_to_point_at) = param_to_point_at && let Some(segment) = path.segments.last() && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { return; } + + if let hir::QPath::TypeRelative(_, segment) = qpath + && let Some(param_to_point_at) = param_to_point_at + && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) + { + return; + } } } hir::Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(segment, args, ..), .. }) => { @@ -1727,6 +1735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .enumerate() .filter(|(_, ty)| ty.walk().any(|arg| arg == param_to_point_at)) .collect(); + if let [(idx, _)] = args_referencing_param.as_slice() && let Some(arg) = args.get(*idx) { diff --git a/src/test/ui/async-await/issue-72442.stderr b/src/test/ui/async-await/issue-72442.stderr index 49fc81d3babc6..919abf646037d 100644 --- a/src/test/ui/async-await/issue-72442.stderr +++ b/src/test/ui/async-await/issue-72442.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Option<&str>: AsRef` is not satisfied - --> $DIR/issue-72442.rs:12:25 + --> $DIR/issue-72442.rs:12:36 | LL | let mut f = File::open(path.to_str())?; - | ^^^^^^^^^^ the trait `AsRef` is not implemented for `Option<&str>` + | ---------- ^^^^^^^^^^^^^ the trait `AsRef` is not implemented for `Option<&str>` + | | + | required by a bound introduced by this call | note: required by a bound in `File::open` --> $SRC_DIR/std/src/fs.rs:LL:COL diff --git a/src/test/ui/async-await/pin-needed-to-poll-2.stderr b/src/test/ui/async-await/pin-needed-to-poll-2.stderr index 3aea93a60ff2d..83d1a02c876b1 100644 --- a/src/test/ui/async-await/pin-needed-to-poll-2.stderr +++ b/src/test/ui/async-await/pin-needed-to-poll-2.stderr @@ -1,8 +1,10 @@ error[E0277]: `PhantomPinned` cannot be unpinned - --> $DIR/pin-needed-to-poll-2.rs:43:9 + --> $DIR/pin-needed-to-poll-2.rs:43:18 | LL | Pin::new(&mut self.sleep).poll(cx) - | ^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned` + | -------- ^^^^^^^^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required because it appears within the type `Sleep` diff --git a/src/test/ui/box/into-boxed-slice-fail.stderr b/src/test/ui/box/into-boxed-slice-fail.stderr index 5e73d8737ea9d..de654fdc1a4b5 100644 --- a/src/test/ui/box/into-boxed-slice-fail.stderr +++ b/src/test/ui/box/into-boxed-slice-fail.stderr @@ -1,8 +1,10 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/into-boxed-slice-fail.rs:7:13 + --> $DIR/into-boxed-slice-fail.rs:7:35 | LL | let _ = Box::into_boxed_slice(boxed_slice); - | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | --------------------- ^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `[u8]` note: required by a bound in `Box::::into_boxed_slice` @@ -21,10 +23,12 @@ LL | let _ = Box::into_boxed_slice(boxed_slice); = note: slice and array elements must have `Sized` type error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time - --> $DIR/into-boxed-slice-fail.rs:11:13 + --> $DIR/into-boxed-slice-fail.rs:11:35 | LL | let _ = Box::into_boxed_slice(boxed_trait); - | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | --------------------- ^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `dyn Debug` note: required by a bound in `Box::::into_boxed_slice` diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr index f53ed53f73c49..91b4f7879e4e4 100644 --- a/src/test/ui/chalkify/bugs/async.stderr +++ b/src/test/ui/chalkify/bugs/async.stderr @@ -2,10 +2,13 @@ error[E0277]: the trait bound `[static generator@$DIR/async.rs:7:29: 9:2]: Gener --> $DIR/async.rs:7:29 | LL | async fn foo(x: u32) -> u32 { - | _____________________________^ + | _____________________________- LL | | x LL | | } - | |_^ the trait `Generator` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]` + | | ^ + | | | + | |_the trait `Generator` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]` + | required by a bound introduced by this call | note: required by a bound in `std::future::from_generator` --> $SRC_DIR/core/src/future/mod.rs:LL:COL @@ -20,7 +23,9 @@ LL | async fn foo(x: u32) -> u32 { | _____________________________^ LL | | x LL | | } - | |_^ + | | ^ required by a bound introduced by this call + | |_| + | | note: required by a bound in `std::future::from_generator` --> $SRC_DIR/core/src/future/mod.rs:LL:COL diff --git a/src/test/ui/dst/dst-rvalue.stderr b/src/test/ui/dst/dst-rvalue.stderr index 5fafdb0620305..727f4d843033f 100644 --- a/src/test/ui/dst/dst-rvalue.stderr +++ b/src/test/ui/dst/dst-rvalue.stderr @@ -1,8 +1,10 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/dst-rvalue.rs:4:24 + --> $DIR/dst-rvalue.rs:4:33 | LL | let _x: Box = Box::new(*"hello world"); - | ^^^^^^^^ doesn't have a size known at compile-time + | -------- ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `str` note: required by a bound in `Box::::new` @@ -12,10 +14,12 @@ LL | impl Box { | ^ required by this bound in `Box::::new` error[E0277]: the size for values of type `[isize]` cannot be known at compilation time - --> $DIR/dst-rvalue.rs:8:28 + --> $DIR/dst-rvalue.rs:8:37 | LL | let _x: Box<[isize]> = Box::new(*array); - | ^^^^^^^^ doesn't have a size known at compile-time + | -------- ^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `[isize]` note: required by a bound in `Box::::new` diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr index 30e6e10eaa2fd..9aff2cec160f2 100644 --- a/src/test/ui/inference/issue-86162-2.stderr +++ b/src/test/ui/inference/issue-86162-2.stderr @@ -4,7 +4,7 @@ error[E0283]: type annotations needed LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! | -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` | | - | type must be known at this point + | required by a bound introduced by this call | = note: cannot satisfy `_: Clone` note: required by a bound in `Foo::bar` diff --git a/src/test/ui/issues/issue-17651.stderr b/src/test/ui/issues/issue-17651.stderr index 792b8294b4413..efaaeeda2fab6 100644 --- a/src/test/ui/issues/issue-17651.stderr +++ b/src/test/ui/issues/issue-17651.stderr @@ -1,8 +1,10 @@ error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time - --> $DIR/issue-17651.rs:5:9 + --> $DIR/issue-17651.rs:5:18 | LL | (|| Box::new(*(&[0][..])))(); - | ^^^^^^^^ doesn't have a size known at compile-time + | -------- ^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `[{integer}]` note: required by a bound in `Box::::new` diff --git a/src/test/ui/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr index a6bd98ddb1977..78b0beff0da39 100644 --- a/src/test/ui/proc-macro/signature.stderr +++ b/src/test/ui/proc-macro/signature.stderr @@ -5,7 +5,10 @@ LL | / pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { LL | | LL | | loop {} LL | | } - | |_^ call the function in a closure: `|| unsafe { /* code */ }` + | | ^ + | | | + | |_call the function in a closure: `|| unsafe { /* code */ }` + | required by a bound introduced by this call | = help: the trait `Fn<(proc_macro::TokenStream,)>` is not implemented for `unsafe extern "C" fn(i32, u32) -> u32 {foo}` = note: unsafe function cannot be called generically without an unsafe block diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr index d5b2d26973096..fd5fe25ddcfb4 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr @@ -20,16 +20,16 @@ LL | const fn test1() { | ++++++++++++ error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause.rs:15:5 + --> $DIR/trait-where-clause.rs:15:12 | LL | T::c::(); - | ^^^^^^^^^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `~const Bar` is not implemented for `T` | note: the trait `Bar` is implemented for `T`, but that implementation is not `const` - --> $DIR/trait-where-clause.rs:15:5 + --> $DIR/trait-where-clause.rs:15:12 | LL | T::c::(); - | ^^^^^^^^^ + | ^ note: required by a bound in `Foo::c` --> $DIR/trait-where-clause.rs:8:13 | @@ -57,10 +57,10 @@ LL | fn test3() { | +++++ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:29:5 + --> $DIR/trait-where-clause.rs:29:12 | LL | T::c::(); - | ^^^^^^^^^ the trait `Bar` is not implemented for `T` + | ^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::c` --> $DIR/trait-where-clause.rs:8:13 diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 71facf57e8d65..e43a4e79bfe8c 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -46,10 +46,12 @@ LL | pub const fn new(pointer: P) -> Pin

{ | ^^^ error[E0277]: `dyn Future + Send` cannot be unpinned - --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5 + --> $DIR/expected-boxed-future-isnt-pinned.rs:19:14 | LL | Pin::new(x) - | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` + | -------- ^ the trait `Unpin` is not implemented for `dyn Future + Send` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required by a bound in `Pin::

::new` @@ -59,10 +61,12 @@ LL | impl> Pin

{ | ^^^^^ required by this bound in `Pin::

::new` error[E0277]: `dyn Future + Send` cannot be unpinned - --> $DIR/expected-boxed-future-isnt-pinned.rs:24:5 + --> $DIR/expected-boxed-future-isnt-pinned.rs:24:14 | LL | Pin::new(Box::new(x)) - | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` + | -------- ^^^^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required by a bound in `Pin::

::new` diff --git a/src/test/ui/suggestions/issue-84973.stderr b/src/test/ui/suggestions/issue-84973.stderr index ad8558599080b..24c989ec3e86d 100644 --- a/src/test/ui/suggestions/issue-84973.stderr +++ b/src/test/ui/suggestions/issue-84973.stderr @@ -1,10 +1,11 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied - --> $DIR/issue-84973.rs:6:13 + --> $DIR/issue-84973.rs:6:24 | LL | let o = Other::new(f); - | ^^^^^^^^^^ the trait `SomeTrait` is not implemented for `Fancy` + | ---------- ^ expected an implementor of trait `SomeTrait` + | | + | required by a bound introduced by this call | - = help: the trait `SomeTrait` is implemented for `&'a Fancy` note: required by a bound in `Other::<'a, G>::new` --> $DIR/issue-84973.rs:25:8 | @@ -13,6 +14,10 @@ LL | G: SomeTrait, LL | { LL | pub fn new(g: G) -> Self { | --- required by a bound in this +help: consider borrowing here + | +LL | let o = Other::new(&f); + | + error: aborting due to previous error diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 420be973b724e..0aa22f9fe8de5 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:17:14 + --> $DIR/mut-borrow-needed-by-trait.rs:17:29 | LL | let fp = BufWriter::new(fp); - | ^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` + | -------------- ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` + | | + | required by a bound introduced by this call | = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` note: required by a bound in `BufWriter::::new` diff --git a/src/test/ui/suggestions/suggest-change-mut.stderr b/src/test/ui/suggestions/suggest-change-mut.stderr index 671596fe45520..889b11a741084 100644 --- a/src/test/ui/suggestions/suggest-change-mut.stderr +++ b/src/test/ui/suggestions/suggest-change-mut.stderr @@ -1,19 +1,29 @@ error[E0277]: the trait bound `&T: std::io::Read` is not satisfied - --> $DIR/suggest-change-mut.rs:12:33 + --> $DIR/suggest-change-mut.rs:12:48 | LL | let mut stream_reader = BufReader::new(&stream); - | ^^^^^^^^^^^^^^ the trait `std::io::Read` is not implemented for `&T` + | -------------- ^^^^^^^ the trait `std::io::Read` is not implemented for `&T` + | | + | required by a bound introduced by this call | - = note: `std::io::Read` is implemented for `&mut T`, but not for `&T` note: required by a bound in `BufReader::::new` --> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL | LL | impl BufReader { | ^^^^ required by this bound in `BufReader::::new` +help: consider removing the leading `&`-reference + | +LL - let mut stream_reader = BufReader::new(&stream); +LL + let mut stream_reader = BufReader::new(stream); + | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | fn issue_81421(mut stream: T) where &T: std::io::Read { | +++++++++++++++++++++++ +help: consider changing this borrow's mutability + | +LL | let mut stream_reader = BufReader::new(&mut stream); + | ~~~~ error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its trait bounds were not satisfied --> $DIR/suggest-change-mut.rs:16:23 diff --git a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr index 28c7c85d48416..6ef9ee81a9bd2 100644 --- a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr +++ b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr @@ -24,10 +24,12 @@ LL | fn with_trait>(c: &C) -> bool { | ++++++++++++++++ error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:34:5 + --> $DIR/repeated-supertrait-ambig.rs:34:34 | LL | ::same_as(c, 22) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | ---------------------------- ^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `CompareTo`: > diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index b990cef318bcc..93a36a2287402 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -39,6 +39,17 @@ help: consider specifying the generic argument LL | opts.get::(opt.as_ref()); | +++++ +error[E0282]: type annotations needed + --> $DIR/issue-77982.rs:13:59 + | +LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); + | ^^^^ + | +help: try using a fully qualified path to specify the expected types + | +LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); + | +++++++++++++++++++++++ ~ + error[E0283]: type annotations needed --> $DIR/issue-77982.rs:13:59 | @@ -98,6 +109,7 @@ help: consider giving this pattern a type, where the type for type parameter `T` LL | let _: Box = (&()).bar(); | ++++++++ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/traits/suggest-deferences/issue-39029.fixed b/src/test/ui/traits/suggest-deferences/issue-39029.fixed index 90d097105edc6..a1abf668b8b6e 100644 --- a/src/test/ui/traits/suggest-deferences/issue-39029.fixed +++ b/src/test/ui/traits/suggest-deferences/issue-39029.fixed @@ -13,6 +13,6 @@ impl std::ops::Deref for NoToSocketAddrs { fn main() { let _works = TcpListener::bind("some string"); let bad = NoToSocketAddrs("bad".to_owned()); - let _errors = TcpListener::bind(&bad); + let _errors = TcpListener::bind(&*bad); //~^ ERROR the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied } diff --git a/src/test/ui/traits/suggest-deferences/issue-39029.stderr b/src/test/ui/traits/suggest-deferences/issue-39029.stderr index 1317a8445f513..eb2b88059d485 100644 --- a/src/test/ui/traits/suggest-deferences/issue-39029.stderr +++ b/src/test/ui/traits/suggest-deferences/issue-39029.stderr @@ -1,21 +1,11 @@ error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied - --> $DIR/issue-39029.rs:16:19 + --> $DIR/issue-39029.rs:16:37 | LL | let _errors = TcpListener::bind(&bad); | ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs` | | | required by a bound introduced by this call | - = help: the following other types implement trait `ToSocketAddrs`: - &'a [std::net::SocketAddr] - &T - (&str, u16) - (IpAddr, u16) - (Ipv4Addr, u16) - (Ipv6Addr, u16) - (String, u16) - SocketAddrV4 - and 4 others = note: required for `&NoToSocketAddrs` to implement `ToSocketAddrs` note: required by a bound in `TcpListener::bind` --> $SRC_DIR/std/src/net/tcp.rs:LL:COL From c9cb19d26e3e868bc32a95b8cb1a003fa8d365a8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 16 Aug 2022 23:28:20 +0000 Subject: [PATCH 03/16] Skip mentioning lang item --- compiler/rustc_typeck/src/check/fn_ctxt/checks.rs | 9 +++++++++ src/test/ui/chalkify/bugs/async.stderr | 11 +++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 550c3395d3ca6..5a2a68d0604c7 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1622,6 +1622,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx)) = *error.obligation.cause.code().peel_derives() else { return; }; + + // Skip over mentioning async lang item + if Some(def_id) == self.tcx.lang_items().from_generator_fn() + && error.obligation.cause.span.desugaring_kind() + == Some(rustc_span::DesugaringKind::Async) + { + return; + } + let Some(unsubstituted_pred) = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) else { return; }; diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr index 91b4f7879e4e4..f53ed53f73c49 100644 --- a/src/test/ui/chalkify/bugs/async.stderr +++ b/src/test/ui/chalkify/bugs/async.stderr @@ -2,13 +2,10 @@ error[E0277]: the trait bound `[static generator@$DIR/async.rs:7:29: 9:2]: Gener --> $DIR/async.rs:7:29 | LL | async fn foo(x: u32) -> u32 { - | _____________________________- + | _____________________________^ LL | | x LL | | } - | | ^ - | | | - | |_the trait `Generator` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]` - | required by a bound introduced by this call + | |_^ the trait `Generator` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]` | note: required by a bound in `std::future::from_generator` --> $SRC_DIR/core/src/future/mod.rs:LL:COL @@ -23,9 +20,7 @@ LL | async fn foo(x: u32) -> u32 { | _____________________________^ LL | | x LL | | } - | | ^ required by a bound introduced by this call - | |_| - | + | |_^ | note: required by a bound in `std::future::from_generator` --> $SRC_DIR/core/src/future/mod.rs:LL:COL From 3a1aa3c76eb06bf6eba9c10eaccced92420c2fac Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 16 Aug 2022 23:37:56 +0000 Subject: [PATCH 04/16] Do not favor projection type when pointing out arg causing fulfillment error --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 20 ++++++++++++++++++- .../associated-types-path-2.stderr | 12 +++++++---- .../issue-27675-unchecked-bounds.stderr | 6 ++---- src/test/ui/issues/issue-69683.stderr | 2 +- .../enforce-supertrait-projection.stderr | 6 ++---- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 5a2a68d0604c7..f2f327e081265 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1742,7 +1742,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .inputs() .iter() .enumerate() - .filter(|(_, ty)| ty.walk().any(|arg| arg == param_to_point_at)) + .filter(|(_, ty)| { + let mut walk = ty.walk(); + while let Some(arg) = walk.next() { + if arg == param_to_point_at { + return true; + } else if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(..) = ty.kind() + { + // This logic may seem a bit strange, but typically when + // we have a projection type in a function signature, the + // argument that's being passed into that signature is + // not actually constraining that projection in a meaningful + // way. So we skip it, and see improvements in some UI tests + // due to it. + walk.skip_current_subtree(); + } + } + false + }) .collect(); if let [(idx, _)] = args_referencing_param.as_slice() diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 7e3cccae3eae5..5edd5c864e135 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -17,10 +17,12 @@ LL | f1(2i32, 4u32); | ~~~ error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:5 + --> $DIR/associated-types-path-2.rs:29:8 | LL | f1(2u32, 4u32); - | ^^ the trait `Foo` is not implemented for `u32` + | -- ^^^^ the trait `Foo` is not implemented for `u32` + | | + | required by a bound introduced by this call | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` @@ -38,10 +40,12 @@ LL | f1(2u32, 4u32); = help: the trait `Foo` is implemented for `i32` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:35:5 + --> $DIR/associated-types-path-2.rs:35:8 | LL | f1(2u32, 4i32); - | ^^ the trait `Foo` is not implemented for `u32` + | -- ^^^^ the trait `Foo` is not implemented for `u32` + | | + | required by a bound introduced by this call | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr index 22daaf329102a..a14a273b3ece9 100644 --- a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr +++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/issue-27675-unchecked-bounds.rs:15:31 + --> $DIR/issue-27675-unchecked-bounds.rs:15:12 | LL | copy::>(t) - | ------------------------- ^ the trait `Copy` is not implemented for `T` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` | note: required by a bound in `copy` --> $DIR/issue-27675-unchecked-bounds.rs:10:12 diff --git a/src/test/ui/issues/issue-69683.stderr b/src/test/ui/issues/issue-69683.stderr index 6d9a1c6fbf9bd..248fb75b4c4e6 100644 --- a/src/test/ui/issues/issue-69683.stderr +++ b/src/test/ui/issues/issue-69683.stderr @@ -14,7 +14,7 @@ error[E0283]: type annotations needed --> $DIR/issue-69683.rs:30:10 | LL | 0u16.foo(b); - | ^^^ - type must be known at this point + | ^^^ | note: multiple `impl`s satisfying `u8: Element<_>` found --> $DIR/issue-69683.rs:5:1 diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr index 9e221daabe545..cbf0938665447 100644 --- a/src/test/ui/traits/object/enforce-supertrait-projection.stderr +++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr @@ -1,14 +1,12 @@ error[E0271]: type mismatch resolving ` as SuperTrait>::A == B` - --> $DIR/enforce-supertrait-projection.rs:9:42 + --> $DIR/enforce-supertrait-projection.rs:9:17 | LL | fn transmute(x: A) -> B { | - - expected type parameter | | | found type parameter LL | foo::>(x) - | ------------------------------------ ^ expected type parameter `B`, found type parameter `A` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A` | = note: expected type parameter `B` found type parameter `A` From 52e2065ed4dba1a68a5f85e8de212e76dde72e7a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 16 Aug 2022 23:54:54 +0000 Subject: [PATCH 05/16] Revert closure mismatch spans --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 9 ++ .../anonymous-higher-ranked-lifetime.stderr | 110 +++++++----------- .../expect-infer-var-appearing-twice.stderr | 15 +-- src/test/ui/mismatched_types/E0631.stderr | 20 ++-- .../mismatched_types/closure-arg-count.stderr | 26 ++--- .../closure-arg-type-mismatch.stderr | 30 ++--- .../ui/mismatched_types/issue-36053-2.stderr | 10 +- .../unboxed-closures-vtable-mismatch.rs | 1 - .../unboxed-closures-vtable-mismatch.stderr | 6 +- 9 files changed, 94 insertions(+), 133 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index f2f327e081265..204bb6a532dc3 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1630,6 +1630,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { return; } + // Skip over closure arg mismatch, which has a better heuristic + // to determine what span to point at. + if let traits::FulfillmentErrorCode::CodeSelectionError( + traits::SelectionError::OutputTypeParameterMismatch(_, expected, _), + ) = error.code + && let ty::Closure(..) | ty::Generator(..) = expected.skip_binder().self_ty().kind() + { + return; + } let Some(unsubstituted_pred) = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) else { return; }; diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index d6deefe693f1f..1a0a5fdf4eb23 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -1,12 +1,10 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:2:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5 | LL | f1(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r, 's> fn(&'r (), &'s ()) -> _` found closure signature `fn((), ()) -> _` @@ -17,14 +15,12 @@ LL | fn f1(_: F) where F: Fn(&(), &()) {} | ^^^^^^^^^^^^ required by this bound in `f1` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:3:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5 | LL | f2(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'a, 'r> fn(&'a (), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -35,14 +31,12 @@ LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f2` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:4:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 | LL | f3(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r> fn(&(), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -53,14 +47,12 @@ LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^ required by this bound in `f3` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:5:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5 | LL | f4(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r, 's> fn(&'s (), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -71,14 +63,12 @@ LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f4` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:6:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 | LL | f5(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r> fn(&'r (), &'r ()) -> _` found closure signature `fn((), ()) -> _` @@ -89,14 +79,12 @@ LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f5` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:7:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5 | LL | g1(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _` found closure signature `fn((), ()) -> _` @@ -107,14 +95,12 @@ LL | fn g1(_: F) where F: Fn(&(), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g1` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:8:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 | LL | g2(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r> fn(&'r (), for<'r> fn(&'r ())) -> _` found closure signature `fn((), ()) -> _` @@ -125,14 +111,12 @@ LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} | ^^^^^^^^^^^^^^^^ required by this bound in `g2` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:9:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5 | LL | g3(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _` found closure signature `fn((), ()) -> _` @@ -143,14 +127,12 @@ LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g3` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:10:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 | LL | g4(|_: (), _: ()| {}); - | -- --------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ -------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` found closure signature `fn((), ()) -> _` @@ -161,14 +143,12 @@ LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g4` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:11:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5 | LL | h1(|_: (), _: (), _: (), _: ()| {}); - | -- ----------------------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ ---------------------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r, 's> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>, &'s (), for<'r, 's> fn(&'r (), &'s ())) -> _` found closure signature `fn((), (), (), ()) -> _` @@ -179,14 +159,12 @@ LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h1` error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:12:8 + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 | LL | h2(|_: (), _: (), _: (), _: ()| {}); - | -- ----------------------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^ ---------------------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'t0, 'r> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _` found closure signature `fn((), (), (), ()) -> _` diff --git a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr index b013798c8247c..8dccf929b2bd1 100644 --- a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr +++ b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr @@ -1,15 +1,10 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/expect-infer-var-appearing-twice.rs:14:18 + --> $DIR/expect-infer-var-appearing-twice.rs:14:5 | -LL | with_closure(|x: u32, y: i32| { - | ------------ ^--------------- - | | | - | _____|____________found signature defined here - | | | - | | required by a bound introduced by this call -LL | | -LL | | }); - | |_____^ expected due to this +LL | with_closure(|x: u32, y: i32| { + | ^^^^^^^^^^^^ ---------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `fn(_, _) -> _` found closure signature `fn(u32, i32) -> _` diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 32ec9ecc474fb..410ea4b0b3439 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -1,12 +1,10 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/E0631.rs:7:9 + --> $DIR/E0631.rs:7:5 | LL | foo(|_: isize| {}); - | --- ----------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^^ ---------- found signature defined here + | | + | expected due to this | = note: expected closure signature `fn(usize) -> _` found closure signature `fn(isize) -> _` @@ -17,14 +15,12 @@ LL | fn foo(_: F) {} | ^^^^^^^^^ required by this bound in `foo` error[E0631]: type mismatch in closure arguments - --> $DIR/E0631.rs:8:9 + --> $DIR/E0631.rs:8:5 | LL | bar(|_: isize| {}); - | --- ----------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^^ ---------- found signature defined here + | | + | expected due to this | = note: expected closure signature `fn(usize) -> _` found closure signature `fn(isize) -> _` diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index c194e1dbc9a43..a6ed22781e95f 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -46,14 +46,12 @@ LL | [1, 2, 3].sort_by(|tuple, tuple2| panic!()); | ~~~~~~~~~~~~~~~ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:13:7 + --> $DIR/closure-arg-count.rs:13:5 | LL | f(|| panic!()); - | - --^^^^^^^^^ - | | | - | | expected closure that takes 1 argument - | | takes 0 arguments - | required by a bound introduced by this call + | ^ -- takes 0 arguments + | | + | expected closure that takes 1 argument | note: required by a bound in `f` --> $DIR/closure-arg-count.rs:3:9 @@ -66,14 +64,12 @@ LL | f(|_| panic!()); | ~~~ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:15:9 + --> $DIR/closure-arg-count.rs:15:5 | LL | f( move || panic!()); - | - ----------^^^^^^^^^ - | | | - | | expected closure that takes 1 argument - | | takes 0 arguments - | required by a bound introduced by this call + | ^ ---------- takes 0 arguments + | | + | expected closure that takes 1 argument | note: required by a bound in `f` --> $DIR/closure-arg-count.rs:3:9 @@ -137,14 +133,12 @@ LL | F: FnMut(Self::Item) -> B, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:27:57 + --> $DIR/closure-arg-count.rs:27:53 | LL | let bar = |i, x, y| i; | --------- takes 3 distinct arguments LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); - | --- ^^^ expected closure that takes a single 2-tuple as argument - | | - | required by a bound introduced by this call + | ^^^ expected closure that takes a single 2-tuple as argument | note: required by a bound in `map` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 0df71af3e70f7..71469bfec2d39 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -1,12 +1,10 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/closure-arg-type-mismatch.rs:3:18 + --> $DIR/closure-arg-type-mismatch.rs:3:14 | LL | a.iter().map(|_: (u32, u32)| 45); - | --- ---------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^^ --------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `fn((u32, u32)) -> _` @@ -17,14 +15,12 @@ LL | F: FnMut(Self::Item) -> B, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` error[E0631]: type mismatch in closure arguments - --> $DIR/closure-arg-type-mismatch.rs:4:18 + --> $DIR/closure-arg-type-mismatch.rs:4:14 | LL | a.iter().map(|_: &(u16, u16)| 45); - | --- ----------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^^ ---------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `for<'r> fn(&'r (u16, u16)) -> _` @@ -35,14 +31,12 @@ LL | F: FnMut(Self::Item) -> B, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` error[E0631]: type mismatch in closure arguments - --> $DIR/closure-arg-type-mismatch.rs:5:18 + --> $DIR/closure-arg-type-mismatch.rs:5:14 | LL | a.iter().map(|_: (u16, u16)| 45); - | --- ---------------^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^^ --------------- found signature defined here + | | + | expected due to this | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `fn((u16, u16)) -> _` diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index 86348b5047528..b11ea97d160be 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -1,12 +1,10 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/issue-36053-2.rs:7:39 + --> $DIR/issue-36053-2.rs:7:32 | LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); - | ------ ---------^^^^^ - | | | - | | expected due to this - | | found signature defined here - | required by a bound introduced by this call + | ^^^^^^ --------- found signature defined here + | | + | expected due to this | = note: expected closure signature `for<'r> fn(&'r &str) -> _` found closure signature `for<'r> fn(&'r str) -> _` diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs index 8dbe3472ea893..0d64ded215ad4 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs @@ -17,6 +17,5 @@ pub fn main() { //~^ ERROR type mismatch //~| NOTE expected due to this //~| NOTE expected closure signature `fn(isize, _) -> _` - //~| NOTE required by a bound introduced by this call println!("{}", z); } diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index 54b2200652746..0b0d9f10786f3 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -1,13 +1,11 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closures-vtable-mismatch.rs:16:24 + --> $DIR/unboxed-closures-vtable-mismatch.rs:16:13 | LL | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); | ----------------------------- found signature defined here LL | LL | let z = call_it(3, f); - | ------- ^ expected due to this - | | - | required by a bound introduced by this call + | ^^^^^^^ expected due to this | = note: expected closure signature `fn(isize, _) -> _` found closure signature `fn(usize, _) -> _` From 70b29f7c2d6d4b86d5b1492f3aa63969a62b25bf Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Aug 2022 12:22:07 +0000 Subject: [PATCH 06/16] Note closure kind mismatch cause --- .../src/traits/error_reporting/mod.rs | 3 +- .../closure_context/issue-26046-fn-mut.stderr | 2 ++ .../issue-26046-fn-once.stderr | 2 ++ .../closure-origin-array-diagnostics.stderr | 10 ++++++- .../closure-origin-tuple-diagnostics.stderr | 10 ++++++- .../ui/closures/closure-wrong-kind.stderr | 10 ++++++- src/test/ui/issues/issue-34349.stderr | 10 ++++++- .../move-ref-patterns-closure-captures.stderr | 30 +++++++++++++++++-- ...-infer-fn-once-move-from-projection.stderr | 12 +++++++- 9 files changed, 79 insertions(+), 10 deletions(-) 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 ab445afe6d6ea..70fac83325a9c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -860,8 +860,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } - err.emit(); - return; + err } ty::PredicateKind::WellFormed(ty) => { diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.stderr b/src/test/ui/closure_context/issue-26046-fn-mut.stderr index 74d3c4977ee65..f744b71c284b0 100644 --- a/src/test/ui/closure_context/issue-26046-fn-mut.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-mut.stderr @@ -8,6 +8,8 @@ LL | num += 1; ... LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here + | + = note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()` error: aborting due to previous error diff --git a/src/test/ui/closure_context/issue-26046-fn-once.stderr b/src/test/ui/closure_context/issue-26046-fn-once.stderr index 473e8e8417e6e..34f94f9dca6d3 100644 --- a/src/test/ui/closure_context/issue-26046-fn-once.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-once.stderr @@ -8,6 +8,8 @@ LL | vec ... LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here + | + = note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec` error: aborting due to previous error diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr index b5f06e38f6d93..309c63e52932b 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr @@ -7,7 +7,15 @@ LL | let [_, _s] = s; | - closure is `FnOnce` because it moves the variable `s` out of its environment LL | }; LL | expect_fn(c); - | - the requirement to implement `Fn` derives from here + | --------- - the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `expect_fn` + --> $DIR/closure-origin-array-diagnostics.rs:5:17 + | +LL | fn expect_fn(_f: F) {} + | ^^^^ required by this bound in `expect_fn` error: aborting due to previous error diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr index 66cd847db50ca..3e77635f9e0c8 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr @@ -7,7 +7,15 @@ LL | let s = s.1; | --- closure is `FnOnce` because it moves the variable `s.1` out of its environment LL | }; LL | expect_fn(c); - | - the requirement to implement `Fn` derives from here + | --------- - the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `expect_fn` + --> $DIR/closure-origin-tuple-diagnostics.rs:5:17 + | +LL | fn expect_fn(_f: F) {} + | ^^^^ required by this bound in `expect_fn` error: aborting due to previous error diff --git a/src/test/ui/closures/closure-wrong-kind.stderr b/src/test/ui/closures/closure-wrong-kind.stderr index 421be56d9173e..9ea55d764f345 100644 --- a/src/test/ui/closures/closure-wrong-kind.stderr +++ b/src/test/ui/closures/closure-wrong-kind.stderr @@ -6,7 +6,15 @@ LL | let closure = |_| foo(x); | | | this closure implements `FnOnce`, not `Fn` LL | bar(closure); - | ------- the requirement to implement `Fn` derives from here + | --- ------- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `bar` + --> $DIR/closure-wrong-kind.rs:6:11 + | +LL | fn bar(_: T) {} + | ^^^^^^^ required by this bound in `bar` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-34349.stderr b/src/test/ui/issues/issue-34349.stderr index 272feb1e3794f..8e9a16619f3b1 100644 --- a/src/test/ui/issues/issue-34349.stderr +++ b/src/test/ui/issues/issue-34349.stderr @@ -7,7 +7,15 @@ LL | farewell.push_str("!!!"); | -------- closure is `FnMut` because it mutates the variable `farewell` here ... LL | apply(diary); - | ----- the requirement to implement `Fn` derives from here + | ----- ----- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `apply` + --> $DIR/issue-34349.rs:11:32 + | +LL | fn apply(f: F) where F: Fn() { + | ^^^^ required by this bound in `apply` error: aborting due to previous error diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr index 683162a5daec6..eba65a61803d0 100644 --- a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr @@ -8,7 +8,15 @@ LL | drop::(_x1); | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment ... LL | accept_fn_mut(&c1); - | --- the requirement to implement `FnMut` derives from here + | ------------- --- the requirement to implement `FnMut` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `accept_fn_mut` + --> $DIR/move-ref-patterns-closure-captures.rs:4:31 + | +LL | fn accept_fn_mut(_: &impl FnMut()) {} + | ^^^^^^^ required by this bound in `accept_fn_mut` error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> $DIR/move-ref-patterns-closure-captures.rs:9:14 @@ -20,7 +28,15 @@ LL | drop::(_x1); | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment ... LL | accept_fn(&c1); - | --- the requirement to implement `Fn` derives from here + | --------- --- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `accept_fn` + --> $DIR/move-ref-patterns-closure-captures.rs:5:27 + | +LL | fn accept_fn(_: &impl Fn()) {} + | ^^^^ required by this bound in `accept_fn` error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` --> $DIR/move-ref-patterns-closure-captures.rs:20:14 @@ -32,7 +48,15 @@ LL | drop::<&mut U>(_x2); | --- closure is `FnMut` because it mutates the variable `_x2` here ... LL | accept_fn(&c2); - | --- the requirement to implement `Fn` derives from here + | --------- --- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `accept_fn` + --> $DIR/move-ref-patterns-closure-captures.rs:5:27 + | +LL | fn accept_fn(_: &impl Fn()) {} + | ^^^^ required by this bound in `accept_fn` error: aborting due to 3 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr index 4ea1ee3c37a7e..635ebbb71d070 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -6,7 +6,17 @@ LL | let c = || drop(y.0); | | | this closure implements `FnOnce`, not `Fn` LL | foo(c); - | - the requirement to implement `Fn` derives from here + | --- - the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `foo` + --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:4:14 + | +LL | fn foo(f: F) + | --- required by a bound in this +LL | where F: Fn() + | ^^^^ required by this bound in `foo` error: aborting due to previous error From c8746766cb2e375c8b9eeb1bab656aca4cc2a9d1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 00:21:40 +0000 Subject: [PATCH 07/16] Rework ambiguity errors --- compiler/rustc_middle/src/ty/generics.rs | 11 +++++ .../rustc_typeck/src/check/fn_ctxt/checks.rs | 40 +++++++++++++++-- src/test/ui/error-codes/E0283.stderr | 21 ++------- src/test/ui/inference/issue-72690.stderr | 36 ++++----------- src/test/ui/issues/issue-69455.stderr | 7 ++- ...od-ambig-one-trait-unknown-int-type.stderr | 4 +- ...s-by-name-in-suggestion-issue-96292.stderr | 4 +- src/test/ui/traits/issue-77982.stderr | 31 +++---------- .../multidispatch-convert-ambig-dest.stderr | 2 +- ...t-non-existing-fully-qualified-path.stderr | 4 +- ...ully-qualified-path-with-adjustment.stderr | 36 ++++----------- ...y-qualified-path-without-adjustment.stderr | 44 +++++-------------- 12 files changed, 95 insertions(+), 145 deletions(-) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index add2df25884e3..6e8afd4d539e2 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -122,6 +122,17 @@ pub struct Generics { } impl<'tcx> Generics { + pub fn param_def_id_to_index(&self, tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { + if let Some(idx) = self.param_def_id_to_index.get(&def_id) { + Some(*idx) + } else if let Some(parent) = self.parent { + let parent = tcx.generics_of(parent); + parent.param_def_id_to_index(tcx, def_id) + } else { + None + } + } + #[inline] pub fn count(&self) -> usize { self.parent_count + self.params.len() diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 204bb6a532dc3..35a3ae3ebf7cc 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -27,13 +27,14 @@ use rustc_infer::infer::InferOk; use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty}; +use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::{self, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext}; use std::iter; +use std::ops::ControlFlow; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -1649,7 +1650,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Projection(pred) => pred.projection_ty.substs, _ => ty::List::empty(), }; - let param_to_point_at = predicate_substs.types().find_map(|ty| { + let mut param_to_point_at = predicate_substs.types().find_map(|ty| { ty.walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Param(param_ty) = ty.kind() @@ -1663,7 +1664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }) }); - let fallback_param_to_point_at = predicate_substs.types().find_map(|ty| { + let mut fallback_param_to_point_at = predicate_substs.types().find_map(|ty| { ty.walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Param(param_ty) = ty.kind() @@ -1676,6 +1677,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) }); + // Also skip over ambiguity errors, which have their own machinery + // to print a relevant error. + if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code { + fallback_param_to_point_at = None; + param_to_point_at = + self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); + } + let hir = self.tcx.hir(); match hir.get(hir_id) { @@ -1737,6 +1746,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn find_ambiguous_parameter_in>( + &self, + item_def_id: DefId, + t: T, + ) -> Option> { + struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId); + impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> { + type BreakTy = ty::GenericArg<'tcx>; + fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { + if let Some(origin) = self.0.type_var_origin(ty) + && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) + = origin.kind + && let generics = self.0.tcx.generics_of(self.1) + && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) + && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1).get(index as usize) + { + ControlFlow::Break(*subst) + } else { + ty.super_visit_with(self) + } + } + } + t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value() + } + fn point_at_args_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index 162d4922d0089..90a28874ead8c 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -12,24 +12,11 @@ help: use a fully-qualified path to a specific available implementation (2 found LL | let cont: u32 = <::Impl as Generator>::create(); | ++++++++++ + -error[E0282]: type annotations needed - --> $DIR/E0283.rs:35:24 - | -LL | let bar = foo_impl.into() * 1u32; - | ^^^^ - | -help: try using a fully qualified path to specify the expected types - | -LL | let bar = >::into(foo_impl) * 1u32; - | ++++++++++++++++++++++++ ~ - error[E0283]: type annotations needed --> $DIR/E0283.rs:35:24 | LL | let bar = foo_impl.into() * 1u32; - | -------- ^^^^ - | | - | type must be known at this point + | ^^^^ | note: multiple `impl`s satisfying `Impl: Into<_>` found --> $DIR/E0283.rs:17:1 @@ -44,7 +31,7 @@ help: try using a fully qualified path to specify the expected types LL | let bar = >::into(foo_impl) * 1u32; | ++++++++++++++++++++++++ ~ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0282, E0283, E0790. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0283, E0790. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/inference/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr index 3504b294ab25e..d4eeda07366a8 100644 --- a/src/test/ui/inference/issue-72690.stderr +++ b/src/test/ui/inference/issue-72690.stderr @@ -12,9 +12,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:7:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -41,9 +39,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:12:26 | LL | |x| String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -59,9 +55,7 @@ error[E0283]: type annotations needed for `&T` --> $DIR/issue-72690.rs:17:9 | LL | let _ = "x".as_ref(); - | ^ --- ------ required by a bound introduced by this call - | | - | type must be known at this point + | ^ ------ type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -87,9 +81,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:21:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -115,9 +107,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:28:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -143,9 +133,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:37:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -171,9 +159,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:46:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -199,9 +185,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:53:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; @@ -227,9 +211,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:62:22 | LL | String::from("x".as_ref()); - | --- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; diff --git a/src/test/ui/issues/issue-69455.stderr b/src/test/ui/issues/issue-69455.stderr index 3e40777c8d0aa..9d11cf19ea77c 100644 --- a/src/test/ui/issues/issue-69455.stderr +++ b/src/test/ui/issues/issue-69455.stderr @@ -14,10 +14,9 @@ error[E0283]: type annotations needed --> $DIR/issue-69455.rs:29:41 | LL | println!("{}", 23u64.test(xs.iter().sum())); - | ----- ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` - | | | - | | required by a bound introduced by this call - | type must be known at this point + | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | | + | required by a bound introduced by this call | note: multiple `impl`s satisfying `u64: Test<_>` found --> $DIR/issue-69455.rs:11:1 diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 754735988e48e..e0f8a5447b081 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -13,9 +13,7 @@ error[E0283]: type annotations needed --> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7 | LL | x.foo(); - | - ^^^ - | | - | type must be known at this point + | ^^^ | note: multiple `impl`s satisfying `Vec<_>: Foo` found --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1 diff --git a/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr index e8d90fb336e19..57b2587ae5ccd 100644 --- a/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr +++ b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr @@ -13,9 +13,7 @@ error[E0283]: type annotations needed --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11 | LL | thing.method(42); - | ----- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:7:1 diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 93a36a2287402..e210f11b3e0c1 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -24,9 +24,8 @@ error[E0283]: type annotations needed --> $DIR/issue-77982.rs:8:10 | LL | opts.get(opt.as_ref()); - | ^^^ --- ------ required by a bound introduced by this call - | | | - | | type must be known at this point + | ^^^ ------ type must be known at this point + | | | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: @@ -39,24 +38,13 @@ help: consider specifying the generic argument LL | opts.get::(opt.as_ref()); | +++++ -error[E0282]: type annotations needed - --> $DIR/issue-77982.rs:13:59 - | -LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); - | ^^^^ - | -help: try using a fully qualified path to specify the expected types - | -LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); - | +++++++++++++++++++++++ ~ - error[E0283]: type annotations needed --> $DIR/issue-77982.rs:13:59 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); | --------- ^^^^ | | - | type must be known at this point + | required by a bound introduced by this call | = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`: - impl From for u32; @@ -73,9 +61,7 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:36:9 | LL | let _ = ().foo(); - | ^ -- --- required by a bound introduced by this call - | | - | type must be known at this point + | ^ --- type must be known at this point | note: multiple `impl`s satisfying `(): Foo<'_, _>` found --> $DIR/issue-77982.rs:29:1 @@ -93,9 +79,7 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:40:9 | LL | let _ = (&()).bar(); - | ^ ----- --- required by a bound introduced by this call - | | - | type must be known at this point + | ^ --- type must be known at this point | note: multiple `impl`s satisfying `&(): Bar<'_, _>` found --> $DIR/issue-77982.rs:32:1 @@ -109,7 +93,6 @@ help: consider giving this pattern a type, where the type for type parameter `T` LL | let _: Box = (&()).bar(); | ++++++++ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0282, E0283. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr index 83fb04646c53f..6e6172eea4746 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -13,7 +13,7 @@ error[E0283]: type annotations needed --> $DIR/multidispatch-convert-ambig-dest.rs:26:5 | LL | test(22, std::default::Default::default()); - | ^^^^ -- type must be known at this point + | ^^^^ -------------------------------- type must be known at this point | | | cannot infer type of the type parameter `U` declared on the function `test` | diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr index 294af65347592..53178328c56af 100644 --- a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr +++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr @@ -13,9 +13,7 @@ error[E0283]: type annotations needed --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:21:7 | LL | a.method(); - | - ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `B: I<_>` found --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1 diff --git a/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr b/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr index 07f7bfb7cb461..68b31a1ca34e3 100644 --- a/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr +++ b/src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr @@ -13,9 +13,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:45:11 | LL | thing.method(); - | ----- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -34,9 +32,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:48:11 | LL | thing.mut_method(); - | ----- ^^^^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -55,9 +51,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:49:11 | LL | thing.by_self(); - | ----- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:22:1 @@ -76,9 +70,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:52:14 | LL | deref_to.method(); - | -------- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -97,9 +89,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:53:14 | LL | deref_to.mut_method(); - | -------- ^^^^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -118,9 +108,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:54:14 | LL | deref_to.by_self(); - | -------- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:22:1 @@ -139,9 +127,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:57:20 | LL | deref_deref_to.method(); - | -------------- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -160,9 +146,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:58:20 | LL | deref_deref_to.mut_method(); - | -------------- ^^^^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:10:1 @@ -181,9 +165,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:59:20 | LL | deref_deref_to.by_self(); - | -------------- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:22:1 diff --git a/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr b/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr index bcc25e103b112..27518a54e7507 100644 --- a/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr +++ b/src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr @@ -13,9 +13,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:45:15 | LL | ref_thing.method(); - | --------- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -34,9 +32,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:48:15 | LL | ref_thing.by_self(); - | --------- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 @@ -55,9 +51,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:51:15 | LL | mut_thing.method(); - | --------- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -76,9 +70,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:52:15 | LL | mut_thing.mut_method(); - | --------- ^^^^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -97,9 +89,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:53:15 | LL | mut_thing.by_self(); - | --------- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 @@ -118,9 +108,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:56:14 | LL | deref_to.method(); - | -------- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -139,9 +127,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:57:14 | LL | deref_to.mut_method(); - | -------- ^^^^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -160,9 +146,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:58:14 | LL | deref_to.by_self(); - | -------- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 @@ -181,9 +165,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:61:20 | LL | deref_deref_to.method(); - | -------------- ^^^^^^ - | | - | type must be known at this point + | ^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -202,9 +184,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:62:20 | LL | deref_deref_to.mut_method(); - | -------------- ^^^^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^^^^ | note: multiple `impl`s satisfying `Thing: Method<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:10:1 @@ -223,9 +203,7 @@ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:63:20 | LL | deref_deref_to.by_self(); - | -------------- ^^^^^^^ - | | - | type must be known at this point + | ^^^^^^^ | note: multiple `impl`s satisfying `&Thing: MethodRef<_>` found --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:23:1 From 24559ce2fedcda97c3273804dc8eb0bf756566eb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 01:28:26 +0000 Subject: [PATCH 08/16] Prefer non-Self non-method types over Self, first --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 26 +++++++++++++++ ...e-21659-show-relevant-trait-impls-1.stderr | 8 ++--- ...e-21659-show-relevant-trait-impls-2.stderr | 8 ++--- ...lue-fallback-issue-66757.nofallback.stderr | 6 ++-- .../ui/on-unimplemented/multiple-impls.stderr | 12 +++---- src/test/ui/on-unimplemented/on-impl.stderr | 4 +-- .../repeated-supertrait-ambig.stderr | 32 +++++++++---------- .../type-params-in-different-spaces-2.stderr | 12 ++++--- .../ui/ufcs/ufcs-qpath-self-mismatch.stderr | 4 +-- 9 files changed, 72 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 35a3ae3ebf7cc..182e69d2aae43 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1669,6 +1669,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Param(param_ty) = ty.kind() && self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id + && param_ty.name != rustc_span::symbol::kw::SelfUpper + { + Some(arg) + } else { + None + } + }) + }); + let mut self_param_to_point_at = predicate_substs.types().find_map(|ty| { + ty.walk().find_map(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + && param_ty.name == rustc_span::symbol::kw::SelfUpper { Some(arg) } else { @@ -1681,6 +1694,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to print a relevant error. if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code { fallback_param_to_point_at = None; + self_param_to_point_at = None; param_to_point_at = self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); } @@ -1704,6 +1718,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } + if let Some(self_param_to_point_at) = self_param_to_point_at + && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, *call_hir_id, callee.span, args) + { + return; + } + if let hir::QPath::Resolved(_, path) = qpath && let Some(param_to_point_at) = param_to_point_at && let Some(segment) = path.segments.last() @@ -1733,6 +1753,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } + if let Some(self_param_to_point_at) = self_param_to_point_at + && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, hir_id, segment.ident.span, args) + { + return; + } + if let Some(param_to_point_at) = param_to_point_at && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr index f2f8d84ad3bb0..b69fcd5d32a60 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `Bar: Foo` is not satisfied - --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:5 + --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:12 | LL | f1.foo(1usize); - | ^^ --- required by a bound introduced by this call - | | - | the trait `Foo` is not implemented for `Bar` + | --- ^^^^^^ the trait `Foo` is not implemented for `Bar` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `Foo`: > diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index b0c41e2fae1ac..5e0e4a0115a0e 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `Bar: Foo` is not satisfied - --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:5 + --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:12 | LL | f1.foo(1usize); - | ^^ --- required by a bound introduced by this call - | | - | the trait `Foo` is not implemented for `Bar` + | --- ^^^^^^ the trait `Foo` is not implemented for `Bar` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `Foo`: > diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr index e2045591390e1..06e902bca70fe 100644 --- a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `E: From<()>` is not satisfied - --> $DIR/never-value-fallback-issue-66757.rs:28:5 + --> $DIR/never-value-fallback-issue-66757.rs:28:26 | LL | >::from(never); - | ^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `E` + | -------------------- ^^^^^ the trait `From<()>` is not implemented for `E` + | | + | required by a bound introduced by this call | = help: the trait `From` is implemented for `E` diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index ad0cebb37360a..8b94c8545fff4 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/multiple-impls.rs:33:18 + --> $DIR/multiple-impls.rs:33:33 | LL | Index::index(&[] as &[i32], 2u32); - | ------------ ^^^^^^^^^^^^^ trait message + | ------------ ^^^^ trait message | | | required by a bound introduced by this call | @@ -23,10 +23,10 @@ LL | Index::index(&[] as &[i32], 2u32); <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:35:18 + --> $DIR/multiple-impls.rs:35:33 | LL | Index::index(&[] as &[i32], Foo(2u32)); - | ------------ ^^^^^^^^^^^^^ on impl for Foo + | ------------ ^^^^^^^^^ on impl for Foo | | | required by a bound introduced by this call | @@ -47,10 +47,10 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:37:18 + --> $DIR/multiple-impls.rs:37:33 | LL | Index::index(&[] as &[i32], Bar(2u32)); - | ------------ ^^^^^^^^^^^^^ on impl for Bar + | ------------ ^^^^^^^^^ on impl for Bar | | | required by a bound introduced by this call | diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index 769a3d77a5726..46902ad30a516 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/on-impl.rs:22:25 + --> $DIR/on-impl.rs:22:47 | LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); - | ------------------- ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | ------------------- ^^^^ a usize is required to index into a slice | | | required by a bound introduced by this call | diff --git a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr index 6ef9ee81a9bd2..656e0d0bf2662 100644 --- a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr +++ b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr @@ -1,22 +1,22 @@ error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:26:5 + --> $DIR/repeated-supertrait-ambig.rs:26:15 | LL | c.same_as(22) - | ^ ------- required by a bound introduced by this call - | | - | the trait `CompareTo` is not implemented for `dyn CompareToInts` + | ------- ^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `CompareTo`: > > error[E0277]: the trait bound `C: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:30:5 + --> $DIR/repeated-supertrait-ambig.rs:30:15 | LL | c.same_as(22) - | ^ ------- required by a bound introduced by this call - | | - | the trait `CompareTo` is not implemented for `C` + | ------- ^^ the trait `CompareTo` is not implemented for `C` + | | + | required by a bound introduced by this call | help: consider further restricting this bound | @@ -24,10 +24,10 @@ LL | fn with_trait>(c: &C) -> bool { | ++++++++++++++++ error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:34:34 + --> $DIR/repeated-supertrait-ambig.rs:34:37 | LL | ::same_as(c, 22) - | ---------------------------- ^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | ---------------------------- ^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` | | | required by a bound introduced by this call | @@ -36,10 +36,10 @@ LL | ::same_as(c, 22) > error[E0277]: the trait bound `C: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:38:24 + --> $DIR/repeated-supertrait-ambig.rs:38:27 | LL | CompareTo::same_as(c, 22) - | ------------------ ^ the trait `CompareTo` is not implemented for `C` + | ------------------ ^^ the trait `CompareTo` is not implemented for `C` | | | required by a bound introduced by this call | @@ -49,12 +49,12 @@ LL | fn with_ufcs2>(c: &C) -> bool { | ++++++++++++++++ error[E0277]: the trait bound `i64: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:42:16 + --> $DIR/repeated-supertrait-ambig.rs:42:31 | LL | assert_eq!(22_i64.same_as(22), true); - | ^^^^^^ ------- required by a bound introduced by this call - | | - | the trait `CompareTo` is not implemented for `i64` + | ------- ^^ the trait `CompareTo` is not implemented for `i64` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `CompareTo`: > diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr index 53610985f31da..220b3929c8857 100644 --- a/src/test/ui/type/type-params-in-different-spaces-2.stderr +++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Self: Tr` is not satisfied - --> $DIR/type-params-in-different-spaces-2.rs:10:9 + --> $DIR/type-params-in-different-spaces-2.rs:10:16 | LL | Tr::op(u) - | ^^^^^^ the trait `Tr` is not implemented for `Self` + | ------ ^ the trait `Tr` is not implemented for `Self` + | | + | required by a bound introduced by this call | help: consider further restricting `Self` | @@ -10,10 +12,12 @@ LL | fn test(u: U) -> Self where Self: Tr { | +++++++++++++++++ error[E0277]: the trait bound `Self: Tr` is not satisfied - --> $DIR/type-params-in-different-spaces-2.rs:16:9 + --> $DIR/type-params-in-different-spaces-2.rs:16:16 | LL | Tr::op(u) - | ^^^^^^ the trait `Tr` is not implemented for `Self` + | ------ ^ the trait `Tr` is not implemented for `Self` + | | + | required by a bound introduced by this call | help: consider further restricting `Self` | diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 4f721f987aee8..f08c81bc1e937 100644 --- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -1,8 +1,8 @@ error[E0277]: cannot add `u32` to `i32` - --> $DIR/ufcs-qpath-self-mismatch.rs:4:28 + --> $DIR/ufcs-qpath-self-mismatch.rs:4:31 | LL | >::add(1, 2); - | ---------------------- ^ no implementation for `i32 + u32` + | ---------------------- ^ no implementation for `i32 + u32` | | | required by a bound introduced by this call | From c0c6603c79280c34aeba14fea1a5cd3d0e8275eb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 02:22:06 +0000 Subject: [PATCH 09/16] Deduplicate errors that come from places like normalization, sized --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 62 ++++++++++++++----- src/test/ui/iterators/issue-28098.stderr | 34 +--------- .../ui/on-unimplemented/multiple-impls.stderr | 35 +---------- src/test/ui/on-unimplemented/on-impl.stderr | 11 +--- src/test/ui/str/str-idx.stderr | 24 +------ src/test/ui/str/str-mut-idx.stderr | 24 +------ .../mut-borrow-needed-by-trait.stderr | 15 +---- 7 files changed, 53 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 182e69d2aae43..7c4d812a1b615 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -15,6 +15,7 @@ use crate::check::{ use crate::structured_errors::StructuredDiagnostic; use rustc_ast as ast; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -1612,24 +1613,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, errors: &mut Vec>, ) { + let mut remap_cause = FxHashSet::default(); + let mut not_adjusted = vec![]; + for error in errors { - self.adjust_fulfillment_error_for_expr_obligation(error); + let before_span = error.obligation.cause.span; + if self.adjust_fulfillment_error_for_expr_obligation(error) { + remap_cause.insert(( + before_span, + error.obligation.predicate, + error.obligation.cause.clone(), + )); + remap_cause.insert(( + before_span, + error.obligation.predicate.without_const(self.tcx), + error.obligation.cause.clone(), + )); + } else { + not_adjusted.push(error); + } + } + + for error in not_adjusted { + for (span, predicate, cause) in &remap_cause { + if *predicate == error.obligation.predicate + && span.contains(error.obligation.cause.span) + { + error.obligation.cause = cause.clone(); + continue; + } + } } } fn adjust_fulfillment_error_for_expr_obligation( &self, error: &mut traits::FulfillmentError<'tcx>, - ) { + ) -> bool { let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx)) - = *error.obligation.cause.code().peel_derives() else { return; }; + = *error.obligation.cause.code().peel_derives() else { return false; }; // Skip over mentioning async lang item if Some(def_id) == self.tcx.lang_items().from_generator_fn() && error.obligation.cause.span.desugaring_kind() == Some(rustc_span::DesugaringKind::Async) { - return; + return false; } // Skip over closure arg mismatch, which has a better heuristic // to determine what span to point at. @@ -1638,11 +1667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) = error.code && let ty::Closure(..) | ty::Generator(..) = expected.skip_binder().self_ty().kind() { - return; + return false; } let Some(unsubstituted_pred) = - self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) else { return; }; + self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) + else { return false; }; let generics = self.tcx.generics_of(def_id); let predicate_substs = match unsubstituted_pred.kind().skip_binder() { @@ -1709,19 +1739,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let Some(param_to_point_at) = param_to_point_at && self.point_at_args_if_possible(error, def_id, param_to_point_at, *call_hir_id, callee.span, args) { - return; + return true; } if let Some(fallback_param_to_point_at) = fallback_param_to_point_at && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, *call_hir_id, callee.span, args) { - return; + return true; } if let Some(self_param_to_point_at) = self_param_to_point_at && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, *call_hir_id, callee.span, args) { - return; + return true; } if let hir::QPath::Resolved(_, path) = qpath @@ -1729,14 +1759,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Some(segment) = path.segments.last() && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { - return; + return true; } if let hir::QPath::TypeRelative(_, segment) = qpath && let Some(param_to_point_at) = param_to_point_at && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { - return; + return true; } } } @@ -1744,25 +1774,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(param_to_point_at) = param_to_point_at && self.point_at_args_if_possible(error, def_id, param_to_point_at, hir_id, segment.ident.span, args) { - return; + return true; } if let Some(fallback_param_to_point_at) = fallback_param_to_point_at && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, hir_id, segment.ident.span, args) { - return; + return true; } if let Some(self_param_to_point_at) = self_param_to_point_at && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, hir_id, segment.ident.span, args) { - return; + return true; } if let Some(param_to_point_at) = param_to_point_at && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { - return; + return true; } } hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(..), .. }) => { @@ -1770,6 +1800,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => {} } + + false } fn find_ambiguous_parameter_in>( diff --git a/src/test/ui/iterators/issue-28098.stderr b/src/test/ui/iterators/issue-28098.stderr index 542807fb91ca3..53b610c172392 100644 --- a/src/test/ui/iterators/issue-28098.stderr +++ b/src/test/ui/iterators/issue-28098.stderr @@ -8,14 +8,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:2:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:5:14 | @@ -35,14 +27,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:8:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:17:28 | @@ -53,14 +37,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:17:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:20:28 | @@ -71,14 +47,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:20:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:23:14 | @@ -88,6 +56,6 @@ LL | for _ in false {} = help: the trait `Iterator` is not implemented for `bool` = note: required for `bool` to implement `IntoIterator` -error: aborting due to 10 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index 8b94c8545fff4..d47a398412fe4 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -11,17 +11,6 @@ LL | Index::index(&[] as &[i32], 2u32); <[i32] as Index>> <[i32] as Index>> -error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/multiple-impls.rs:33:5 - | -LL | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^ trait message - | - = help: the trait `Index` is not implemented for `[i32]` - = help: the following other types implement trait `Index`: - <[i32] as Index>> - <[i32] as Index>> - error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:35:33 | @@ -35,17 +24,6 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); <[i32] as Index>> <[i32] as Index>> -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:35:5 - | -LL | Index::index(&[] as &[i32], Foo(2u32)); - | ^^^^^^^^^^^^ on impl for Foo - | - = help: the trait `Index>` is not implemented for `[i32]` - = help: the following other types implement trait `Index`: - <[i32] as Index>> - <[i32] as Index>> - error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:37:33 | @@ -59,17 +37,6 @@ LL | Index::index(&[] as &[i32], Bar(2u32)); <[i32] as Index>> <[i32] as Index>> -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:37:5 - | -LL | Index::index(&[] as &[i32], Bar(2u32)); - | ^^^^^^^^^^^^ on impl for Bar - | - = help: the trait `Index>` is not implemented for `[i32]` - = help: the following other types implement trait `Index`: - <[i32] as Index>> - <[i32] as Index>> - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index 46902ad30a516..01315b854098e 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -9,15 +9,6 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` -error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/on-impl.rs:22:5 - | -LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); - | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice - | - = help: the trait `Index` is not implemented for `[i32]` - = help: the trait `Index` is implemented for `[i32]` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 6daa74657bd8e..019305def2932 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -28,17 +28,6 @@ note: required by a bound in `core::str::::get` LL | pub const fn get>(&self, i: I) -> Option<&I::Output> { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-idx.rs:4:15 - | -LL | let _ = s.get(4); - | ^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-idx.rs:5:29 | @@ -57,17 +46,6 @@ note: required by a bound in `core::str::::get_unchecked` LL | pub const unsafe fn get_unchecked>(&self, i: I) -> &I::Output { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-idx.rs:5:15 - | -LL | let _ = s.get_unchecked(4); - | ^^^^^^^^^^^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-idx.rs:6:19 | @@ -77,6 +55,6 @@ LL | let _: u8 = s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required for `str` to implement `Index` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index d063088aded83..b165c482590a2 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -52,17 +52,6 @@ note: required by a bound in `core::str::::get_mut` LL | pub const fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_mut` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-mut-idx.rs:9:7 - | -LL | s.get_mut(1); - | ^^^^^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-mut-idx.rs:11:25 | @@ -81,17 +70,6 @@ note: required by a bound in `core::str::::get_unchecked_mut` LL | pub const unsafe fn get_unchecked_mut>( | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked_mut` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-mut-idx.rs:11:7 - | -LL | s.get_unchecked_mut(1); - | ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-mut-idx.rs:13:7 | @@ -101,6 +79,6 @@ LL | s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required for `str` to implement `Index` -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 0aa22f9fe8de5..d121932c842e3 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -13,19 +13,6 @@ note: required by a bound in `BufWriter::::new` LL | impl BufWriter { | ^^^^^ required by this bound in `BufWriter::::new` -error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:17:14 - | -LL | let fp = BufWriter::new(fp); - | ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` - | - = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` -note: required by a bound in `BufWriter` - --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL - | -LL | pub struct BufWriter { - | ^^^^^ required by this bound in `BufWriter` - error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | @@ -55,7 +42,7 @@ LL | pub struct BufWriter { which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. From 292ab399b339154e77fef54efe8b975654259733 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 04:57:17 +0000 Subject: [PATCH 10/16] Point at struct field if possible --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 294 +++++++++++------- src/test/ui/chalkify/type_wf.rs | 4 +- src/test/ui/chalkify/type_wf.stderr | 6 +- src/test/ui/range/range-1.stderr | 2 +- .../bound/on-structs-and-enums-locals.rs | 2 +- .../bound/on-structs-and-enums-locals.stderr | 6 +- .../traits/bound/on-structs-and-enums-xc1.rs | 2 +- .../bound/on-structs-and-enums-xc1.stderr | 6 +- .../ui/union/union-generic.mirunsafeck.stderr | 4 +- .../union/union-generic.thirunsafeck.stderr | 4 +- 10 files changed, 194 insertions(+), 136 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 7c4d812a1b615..15938b3c9b9cd 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1680,48 +1680,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Projection(pred) => pred.projection_ty.substs, _ => ty::List::empty(), }; - let mut param_to_point_at = predicate_substs.types().find_map(|ty| { - ty.walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Param(param_ty) = ty.kind() - // Look for a param ty that is local to this method/fn - // and not inherited from an impl, for example. - && self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id - { - Some(arg) - } else { - None - } - }) - }); - let mut fallback_param_to_point_at = predicate_substs.types().find_map(|ty| { - ty.walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Param(param_ty) = ty.kind() - && self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id - && param_ty.name != rustc_span::symbol::kw::SelfUpper - { - Some(arg) - } else { - None - } + + let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| { + predicate_substs.types().find_map(|ty| { + ty.walk().find_map(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + && matches(param_ty) + { + Some(arg) + } else { + None + } + }) }) + }; + + // Prefer generics that are local to the fn item, since these are likely + // to be the cause of the unsatisfied predicaete. + let mut param_to_point_at = find_param_matching(&|param_ty| { + self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id }); - let mut self_param_to_point_at = predicate_substs.types().find_map(|ty| { - ty.walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Param(param_ty) = ty.kind() - && param_ty.name == rustc_span::symbol::kw::SelfUpper - { - Some(arg) - } else { - None - } - }) + // Fall back to generic that isn't local to the fn item. This will come + // from a trait or impl, for example. + let mut fallback_param_to_point_at = find_param_matching(&|param_ty| { + self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id + && param_ty.name != rustc_span::symbol::kw::SelfUpper }); - - // Also skip over ambiguity errors, which have their own machinery - // to print a relevant error. + // Finally, the `Self` parameter is possibly the reason that the predicate + // is unsatisfied. This is less likely to be true for methods, because the + // method probe means that we already kinda check that the predicates due + // to the `Self` type are true. + let mut self_param_to_point_at = + find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper); + + // For ambiguity errors, we actually want to look for a parameter that is + // the source of the inference type left over in this predicate. if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code { fallback_param_to_point_at = None; self_param_to_point_at = None; @@ -1737,99 +1731,101 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { = hir.get(hir.get_parent_node(*hir_id)) && callee.hir_id == *hir_id { - if let Some(param_to_point_at) = param_to_point_at - && self.point_at_args_if_possible(error, def_id, param_to_point_at, *call_hir_id, callee.span, args) { - return true; - } - - if let Some(fallback_param_to_point_at) = fallback_param_to_point_at - && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, *call_hir_id, callee.span, args) - { - return true; - } - - if let Some(self_param_to_point_at) = self_param_to_point_at - && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, *call_hir_id, callee.span, args) - { - return true; - } - - if let hir::QPath::Resolved(_, path) = qpath - && let Some(param_to_point_at) = param_to_point_at - && let Some(segment) = path.segments.last() - && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) - { - return true; + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] { + if let Some(param) = param + && self.point_at_arg_if_possible(error, def_id, param, *call_hir_id, callee.span, args) + { + return true; + } } - if let hir::QPath::TypeRelative(_, segment) = qpath - && let Some(param_to_point_at) = param_to_point_at - && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) + // Notably, we only point to params that are local to the + // item we're checking, since those are the ones we are able + // to look in the hir::PathSegment for. Everything else + // would require a deeper search into the qpath than I think + // is worthwhile. + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath) { return true; } } } - hir::Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(segment, args, ..), .. }) => { - if let Some(param_to_point_at) = param_to_point_at - && self.point_at_args_if_possible(error, def_id, param_to_point_at, hir_id, segment.ident.span, args) + hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::MethodCall(segment, args, ..), + .. + }) => { + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] { - return true; + if let Some(param) = param + && self.point_at_arg_if_possible(error, def_id, param, hir_id, segment.ident.span, args) + { + return true; + } } - if let Some(fallback_param_to_point_at) = fallback_param_to_point_at - && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, hir_id, segment.ident.span, args) + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment) { return true; } - - if let Some(self_param_to_point_at) = self_param_to_point_at - && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, hir_id, segment.ident.span, args) + } + hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Struct(qpath, fields, ..), .. + }) => { + if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) = + self.typeck_results.borrow().qpath_res(qpath, hir_id) { - return true; + for param in + [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + { + if let Some(param) = param + && self.point_at_field_if_possible(error, def_id, param, variant_def_id, fields) + { + return true; + } + } } if let Some(param_to_point_at) = param_to_point_at - && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) + && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath) { return true; } } - hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(..), .. }) => { - // fixme - } _ => {} } false } - fn find_ambiguous_parameter_in>( + fn point_at_path_if_possible( &self, - item_def_id: DefId, - t: T, - ) -> Option> { - struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId); - impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> { - type BreakTy = ty::GenericArg<'tcx>; - fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { - if let Some(origin) = self.0.type_var_origin(ty) - && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) - = origin.kind - && let generics = self.0.tcx.generics_of(self.1) - && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) - && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1).get(index as usize) + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param: ty::GenericArg<'tcx>, + qpath: &QPath<'tcx>, + ) -> bool { + match qpath { + hir::QPath::Resolved(_, path) => { + if let Some(segment) = path.segments.last() + && self.point_at_generic_if_possible(error, def_id, param, segment) { - ControlFlow::Break(*subst) - } else { - ty.super_visit_with(self) + return true; } } + hir::QPath::TypeRelative(_, segment) => { + if self.point_at_generic_if_possible(error, def_id, param, segment) { + return true; + } + } + _ => {} } - t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value() + + false } - fn point_at_args_if_possible( + fn point_at_arg_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, def_id: DefId, @@ -1843,25 +1839,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .inputs() .iter() .enumerate() - .filter(|(_, ty)| { - let mut walk = ty.walk(); - while let Some(arg) = walk.next() { - if arg == param_to_point_at { - return true; - } else if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Projection(..) = ty.kind() - { - // This logic may seem a bit strange, but typically when - // we have a projection type in a function signature, the - // argument that's being passed into that signature is - // not actually constraining that projection in a meaningful - // way. So we skip it, and see improvements in some UI tests - // due to it. - walk.skip_current_subtree(); - } - } - false - }) + .filter(|(_, ty)| find_param_in_ty(ty, param_to_point_at)) .collect(); if let [(idx, _)] = args_referencing_param.as_slice() @@ -1886,7 +1864,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn point_at_generics_if_possible( + fn point_at_field_if_possible( + &self, + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param_to_point_at: ty::GenericArg<'tcx>, + variant_def_id: DefId, + expr_fields: &[hir::ExprField<'tcx>], + ) -> bool { + let def = self.tcx.adt_def(def_id); + let identity_substs = ty::InternalSubsts::identity_for_item(self.tcx, def_id); + let fields_referencing_param: Vec<_> = def + .variant_with_id(variant_def_id) + .fields + .iter() + .filter(|field| { + let field_ty = field.ty(self.tcx, identity_substs); + match find_param_in_ty(field_ty, param_to_point_at) { + Ok(value) => value, + Err(value) => return value, + } + }) + .collect(); + if let [field] = fields_referencing_param.as_slice() { + for expr_field in expr_fields { + if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx) + { + error.obligation.cause.span = expr_field.span; + } + } + true + } else { + false + } + } + + fn point_at_generic_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, def_id: DefId, @@ -1912,6 +1925,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true } + fn find_ambiguous_parameter_in>( + &self, + item_def_id: DefId, + t: T, + ) -> Option> { + struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId); + impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> { + type BreakTy = ty::GenericArg<'tcx>; + fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { + if let Some(origin) = self.0.type_var_origin(ty) + && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) + = origin.kind + && let generics = self.0.tcx.generics_of(self.1) + && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) + && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1).get(index as usize) + { + ControlFlow::Break(*subst) + } else { + ty.super_visit_with(self) + } + } + } + t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value() + } + fn label_fn_like( &self, err: &mut Diagnostic, @@ -2053,3 +2091,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + +fn find_param_in_ty(ty: Ty, param_to_point_at: ty::GenericArg) -> bool { + let mut walk = ty.walk(); + while let Some(arg) = walk.next() { + if arg == param_to_point_at { + return true; + } else if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(..) = ty.kind() + { + // This logic may seem a bit strange, but typically when + // we have a projection type in a function signature, the + // argument that's being passed into that signature is + // not actually constraining that projection's substs in + // a meaningful way. So we skip it, and see improvements + // in some UI tests. + walk.skip_current_subtree(); + } + } + false +} diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs index dd83a03fdf691..eeeefcfb7dd15 100644 --- a/src/test/ui/chalkify/type_wf.rs +++ b/src/test/ui/chalkify/type_wf.rs @@ -15,8 +15,8 @@ fn main() { x: 5, }; - let s = S { //~ ERROR the trait bound `{float}: Foo` is not satisfied - x: 5.0, + let s = S { + x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied }; let s = S { diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr index 7f8566082cd26..28314928a3c26 100644 --- a/src/test/ui/chalkify/type_wf.stderr +++ b/src/test/ui/chalkify/type_wf.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `{float}: Foo` is not satisfied - --> $DIR/type_wf.rs:18:13 + --> $DIR/type_wf.rs:19:9 | -LL | let s = S { - | ^ the trait `Foo` is not implemented for `{float}` +LL | x: 5.0, + | ^^^^^^ the trait `Foo` is not implemented for `{float}` | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `S` diff --git a/src/test/ui/range/range-1.stderr b/src/test/ui/range/range-1.stderr index 0e3bb66ab61e9..aaea91ce0cbae 100644 --- a/src/test/ui/range/range-1.stderr +++ b/src/test/ui/range/range-1.stderr @@ -27,7 +27,7 @@ error[E0277]: the size for values of type `[{integer}]` cannot be known at compi --> $DIR/range-1.rs:14:17 | LL | let range = *arr..; - | ^^^^^^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[{integer}]` note: required by a bound in `RangeFrom` diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.rs b/src/test/ui/traits/bound/on-structs-and-enums-locals.rs index 21c0ce80f8a8d..60ba343bb0a5c 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-locals.rs +++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.rs @@ -8,8 +8,8 @@ struct Foo { fn main() { let foo = Foo { - //~^ ERROR E0277 x: 3 + //~^ ERROR E0277 }; let baz: Foo = loop { }; diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr index c9068a270020d..4abff9fb0495a 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr +++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr @@ -11,10 +11,10 @@ LL | struct Foo { | ^^^^^ required by this bound in `Foo` error[E0277]: the trait bound `{integer}: Trait` is not satisfied - --> $DIR/on-structs-and-enums-locals.rs:10:15 + --> $DIR/on-structs-and-enums-locals.rs:11:9 | -LL | let foo = Foo { - | ^^^ the trait `Trait` is not implemented for `{integer}` +LL | x: 3 + | ^^^^ the trait `Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs b/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs index 8156868e048d9..5ef35b513e0fb 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs +++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs @@ -6,8 +6,8 @@ use on_structs_and_enums_xc::{Bar, Foo, Trait}; fn main() { let foo = Foo { - //~^ ERROR E0277 x: 3 + //~^ ERROR E0277 }; let bar: Bar = return; //~^ ERROR E0277 diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr index f4cc64af94f37..dd0de44f3b119 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr +++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr @@ -11,10 +11,10 @@ LL | pub enum Bar { | ^^^^^ required by this bound in `Bar` error[E0277]: the trait bound `{integer}: Trait` is not satisfied - --> $DIR/on-structs-and-enums-xc1.rs:8:15 + --> $DIR/on-structs-and-enums-xc1.rs:9:9 | -LL | let foo = Foo { - | ^^^ the trait `Trait` is not implemented for `{integer}` +LL | x: 3 + | ^^^^ the trait `Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 diff --git a/src/test/ui/union/union-generic.mirunsafeck.stderr b/src/test/ui/union/union-generic.mirunsafeck.stderr index a4f0c400d7310..037022a91fcd0 100644 --- a/src/test/ui/union/union-generic.mirunsafeck.stderr +++ b/src/test/ui/union/union-generic.mirunsafeck.stderr @@ -11,10 +11,10 @@ LL | union U { | ^^^^ required by this bound in `U` error[E0277]: the trait bound `Rc: Copy` is not satisfied - --> $DIR/union-generic.rs:13:13 + --> $DIR/union-generic.rs:13:17 | LL | let u = U::> { a: Default::default() }; - | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc` + | ^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `U` --> $DIR/union-generic.rs:6:12 diff --git a/src/test/ui/union/union-generic.thirunsafeck.stderr b/src/test/ui/union/union-generic.thirunsafeck.stderr index a4f0c400d7310..037022a91fcd0 100644 --- a/src/test/ui/union/union-generic.thirunsafeck.stderr +++ b/src/test/ui/union/union-generic.thirunsafeck.stderr @@ -11,10 +11,10 @@ LL | union U { | ^^^^ required by this bound in `U` error[E0277]: the trait bound `Rc: Copy` is not satisfied - --> $DIR/union-generic.rs:13:13 + --> $DIR/union-generic.rs:13:17 | LL | let u = U::> { a: Default::default() }; - | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc` + | ^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `U` --> $DIR/union-generic.rs:6:12 From 6848ba2665d10380f259addbd9f60d0ab8d3542a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 06:17:36 +0000 Subject: [PATCH 11/16] Comment a bit, use find_ancestor_in_same_ctxt to suppress some weird macro notes --- compiler/rustc_span/src/lib.rs | 7 + .../rustc_typeck/src/check/fn_ctxt/checks.rs | 240 +++++++++++------- src/test/ui/fmt/send-sync.stderr | 2 - src/test/ui/issues/issue-60218.stderr | 1 - .../feature-gate-never_type_fallback.stderr | 1 - 5 files changed, 151 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d14e28e85be1a..a624e3ab1429f 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -664,6 +664,13 @@ impl Span { Some(self) } + pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option { + while !Span::eq_ctxt(self, other) { + self = self.parent_callsite()?; + } + Some(self) + } + /// Edition of the crate from which this span came. pub fn edition(self) -> edition::Edition { self.ctxt().edition() diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 15938b3c9b9cd..12f73ae96e9e5 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -657,7 +657,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); }; - self.label_fn_like(&mut err, fn_def_id, callee_ty, Some(mismatch_idx), is_method); + self.label_fn_like( + &mut err, + fn_def_id, + callee_ty, + Some(mismatch_idx), + is_method, + ); err.emit(); return; } @@ -1064,8 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let suggestion_text = if let Some(provided_idx) = provided_idx && let (_, provided_span) = provided_arg_tys[*provided_idx] - && let Ok(arg_text) = - source_map.span_to_snippet(provided_span) + && let Ok(arg_text) = source_map.span_to_snippet(provided_span) { arg_text } else { @@ -1603,22 +1608,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk - /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s - /// reference a type argument. The reason to walk also the checked type is that the coerced type - /// can be not easily comparable with predicate type (because of coercion). If the types match - /// for either checked or coerced type, and there's only *one* argument that does, we point at - /// the corresponding argument's expression span instead of the `fn` call path span. + /// Given a vector of fulfillment errors, try to adjust the spans of the + /// errors to more accurately point at the cause of the failure. + /// + /// This applies to calls, methods, and struct expressions. This will also + /// try to deduplicate errors that are due to the same cause but might + /// have been created with different [`ObligationCause`][traits::ObligationCause]s. pub(super) fn adjust_fulfillment_errors_for_expr_obligation( &self, errors: &mut Vec>, ) { + // Store a mapping from `(Span, Predicate) -> ObligationCause`, so that + // other errors that have the same span and predicate can also get fixed, + // even if their `ObligationCauseCode` isn't an `Expr*Obligation` kind. + // This is important since if we adjust one span but not the other, then + // we will have "duplicated" the error on the UI side. let mut remap_cause = FxHashSet::default(); let mut not_adjusted = vec![]; for error in errors { let before_span = error.obligation.cause.span; - if self.adjust_fulfillment_error_for_expr_obligation(error) { + if self.adjust_fulfillment_error_for_expr_obligation(error) + || before_span != error.obligation.cause.span + { + // Store both the predicate and the predicate *without constness* + // since sometimes we instantiate and check both of these in a + // method call, for example. remap_cause.insert(( before_span, error.obligation.predicate, @@ -1630,6 +1645,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error.obligation.cause.clone(), )); } else { + // If it failed to be adjusted once around, it may be adjusted + // via the "remap cause" mapping the second time... not_adjusted.push(error); } } @@ -1697,7 +1714,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Prefer generics that are local to the fn item, since these are likely - // to be the cause of the unsatisfied predicaete. + // to be the cause of the unsatisfied predicate. let mut param_to_point_at = find_param_matching(&|param_ty| { self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id }); @@ -1708,14 +1725,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && param_ty.name != rustc_span::symbol::kw::SelfUpper }); // Finally, the `Self` parameter is possibly the reason that the predicate - // is unsatisfied. This is less likely to be true for methods, because the + // is unsatisfied. This is less likely to be true for methods, because // method probe means that we already kinda check that the predicates due // to the `Self` type are true. let mut self_param_to_point_at = find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper); - // For ambiguity errors, we actually want to look for a parameter that is - // the source of the inference type left over in this predicate. + // Finally, for ambiguity-related errors, we actually want to look + // for a parameter that is the source of the inference type left + // over in this predicate. if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code { fallback_param_to_point_at = None; self_param_to_point_at = None; @@ -1724,25 +1742,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let hir = self.tcx.hir(); - match hir.get(hir_id) { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(qpath), hir_id, .. }) => { - if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(callee, args), hir_id: call_hir_id, .. }) - = hir.get(hir.get_parent_node(*hir_id)) + if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Call(callee, args), + hir_id: call_hir_id, + .. + }) = hir.get(hir.get_parent_node(*hir_id)) && callee.hir_id == *hir_id { - for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] { + for param in + [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + { if let Some(param) = param - && self.point_at_arg_if_possible(error, def_id, param, *call_hir_id, callee.span, args) + && self.point_at_arg_if_possible( + error, + def_id, + param, + *call_hir_id, + callee.span, + args, + ) { return true; } } - // Notably, we only point to params that are local to the // item we're checking, since those are the ones we are able - // to look in the hir::PathSegment for. Everything else - // would require a deeper search into the qpath than I think + // to look in the final `hir::PathSegment` for. Everything else + // would require a deeper search into the `qpath` than I think // is worthwhile. if let Some(param_to_point_at) = param_to_point_at && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath) @@ -1758,12 +1786,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] { if let Some(param) = param - && self.point_at_arg_if_possible(error, def_id, param, hir_id, segment.ident.span, args) + && self.point_at_arg_if_possible( + error, + def_id, + param, + hir_id, + segment.ident.span, + args, + ) { return true; } } - if let Some(param_to_point_at) = param_to_point_at && self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment) { @@ -1780,13 +1814,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] { if let Some(param) = param - && self.point_at_field_if_possible(error, def_id, param, variant_def_id, fields) + && self.point_at_field_if_possible( + error, + def_id, + param, + variant_def_id, + fields, + ) { return true; } } } - if let Some(param_to_point_at) = param_to_point_at && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath) { @@ -1799,32 +1838,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } - fn point_at_path_if_possible( - &self, - error: &mut traits::FulfillmentError<'tcx>, - def_id: DefId, - param: ty::GenericArg<'tcx>, - qpath: &QPath<'tcx>, - ) -> bool { - match qpath { - hir::QPath::Resolved(_, path) => { - if let Some(segment) = path.segments.last() - && self.point_at_generic_if_possible(error, def_id, param, segment) - { - return true; - } - } - hir::QPath::TypeRelative(_, segment) => { - if self.point_at_generic_if_possible(error, def_id, param, segment) { - return true; - } - } - _ => {} - } - - false - } - fn point_at_arg_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, @@ -1839,13 +1852,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .inputs() .iter() .enumerate() - .filter(|(_, ty)| find_param_in_ty(ty, param_to_point_at)) + .filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at)) .collect(); - if let [(idx, _)] = args_referencing_param.as_slice() - && let Some(arg) = args.get(*idx) - { - error.obligation.cause.span = arg.span; + // If there's one field that references the given generic, great! + if let [(idx, _)] = args_referencing_param.as_slice() && let Some(arg) = args.get(*idx) { + error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span); error.obligation.cause.map_code(|parent_code| { ObligationCauseCode::FunctionArgumentObligation { arg_hir_id: arg.hir_id, @@ -1853,15 +1865,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { parent_code, } }); - true + return true; } else if args_referencing_param.len() > 0 { - // If more than one argument applies, then point to the callee + // If more than one argument applies, then point to the callee span at least... // We have chance to fix this up further in `point_at_generics_if_possible` error.obligation.cause.span = callee_span; - false - } else { - false } + + false } fn point_at_field_if_possible( @@ -1873,6 +1884,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_fields: &[hir::ExprField<'tcx>], ) -> bool { let def = self.tcx.adt_def(def_id); + let identity_substs = ty::InternalSubsts::identity_for_item(self.tcx, def_id); let fields_referencing_param: Vec<_> = def .variant_with_id(variant_def_id) @@ -1880,23 +1892,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .filter(|field| { let field_ty = field.ty(self.tcx, identity_substs); - match find_param_in_ty(field_ty, param_to_point_at) { - Ok(value) => value, - Err(value) => return value, - } + find_param_in_ty(field_ty, param_to_point_at) }) .collect(); + if let [field] = fields_referencing_param.as_slice() { for expr_field in expr_fields { + // Look for the ExprField that matches the field, using the + // same rules that check_expr_struct uses for macro hygiene. if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx) { - error.obligation.cause.span = expr_field.span; + error.obligation.cause.span = expr_field + .span + .find_ancestor_in_same_ctxt(error.obligation.cause.span) + .unwrap_or(expr_field.span); + return true; } } - true - } else { - false } + + false + } + + fn point_at_path_if_possible( + &self, + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param: ty::GenericArg<'tcx>, + qpath: &QPath<'tcx>, + ) -> bool { + match qpath { + hir::QPath::Resolved(_, path) => { + if let Some(segment) = path.segments.last() + && self.point_at_generic_if_possible(error, def_id, param, segment) + { + return true; + } + } + hir::QPath::TypeRelative(_, segment) => { + if self.point_at_generic_if_possible(error, def_id, param, segment) { + return true; + } + } + _ => {} + } + + false } fn point_at_generic_if_possible( @@ -1921,7 +1962,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .filter(|arg| matches!(arg, hir::GenericArg::Type(_))) .nth(index) else { return false; }; - error.obligation.cause.span = arg.span(); + error.obligation.cause.span = arg + .span() + .find_ancestor_in_same_ctxt(error.obligation.cause.span) + .unwrap_or(arg.span()); true } @@ -1935,11 +1979,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { type BreakTy = ty::GenericArg<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { if let Some(origin) = self.0.type_var_origin(ty) - && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) - = origin.kind + && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) = + origin.kind && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) - && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1).get(index as usize) + && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1) + .get(index as usize) { ControlFlow::Break(*subst) } else { @@ -2015,14 +2060,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let new_def_id = self.probe(|_| { let trait_ref = ty::TraitRef::new( call_kind.to_def_id(self.tcx), - self.tcx.mk_substs([ - ty::GenericArg::from(callee_ty), - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: rustc_span::DUMMY_SP, - }) - .into(), - ].into_iter()), + self.tcx.mk_substs( + [ + ty::GenericArg::from(callee_ty), + self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: rustc_span::DUMMY_SP, + }) + .into(), + ] + .into_iter(), + ), ); let obligation = traits::Obligation::new( traits::ObligationCause::dummy(), @@ -2037,7 +2085,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(Some(traits::ImplSource::UserDefined(impl_source))) => { Some(impl_source.impl_def_id) } - _ => None + _ => None, } }); if let Some(new_def_id) = new_def_id { @@ -2092,22 +2140,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -fn find_param_in_ty(ty: Ty, param_to_point_at: ty::GenericArg) -> bool { +fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>) -> bool { let mut walk = ty.walk(); while let Some(arg) = walk.next() { if arg == param_to_point_at { - return true; - } else if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Projection(..) = ty.kind() - { - // This logic may seem a bit strange, but typically when - // we have a projection type in a function signature, the - // argument that's being passed into that signature is - // not actually constraining that projection's substs in - // a meaningful way. So we skip it, and see improvements - // in some UI tests. - walk.skip_current_subtree(); - } + return true; + } else if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(..) = ty.kind() + { + // This logic may seem a bit strange, but typically when + // we have a projection type in a function signature, the + // argument that's being passed into that signature is + // not actually constraining that projection's substs in + // a meaningful way. So we skip it, and see improvements + // in some UI tests. + walk.skip_current_subtree(); + } } false } diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 62bcf3175e21b..3ed040c3ab359 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -17,7 +17,6 @@ note: required by a bound in `send` | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` - = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely --> $DIR/send-sync.rs:9:10 @@ -38,7 +37,6 @@ note: required by a bound in `sync` | LL | fn sync(_: T) {} | ^^^^ required by this bound in `sync` - = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-60218.stderr b/src/test/ui/issues/issue-60218.stderr index 9105492c9ad94..dd72b6515ddca 100644 --- a/src/test/ui/issues/issue-60218.stderr +++ b/src/test/ui/issues/issue-60218.stderr @@ -14,7 +14,6 @@ LL | pub fn trigger_error(iterable: I, functor: F) ... LL | for<'t> ::IntoIter, F> as Iterator>::Item: Foo, | ^^^ required by this bound in `trigger_error` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 6a4726a8cc9e0..6dc039fc35db7 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -13,7 +13,6 @@ note: required by a bound in `foo` | LL | fn foo(_: impl T) {} | ^ required by this bound in `foo` - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error From 8917894fda4c1c47369523448c75137c7b01fb6e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 06:48:09 +0000 Subject: [PATCH 12/16] Targeted fixes addressing erroneous suggestions --- .../src/traits/error_reporting/suggestions.rs | 36 ++++++++++++++----- src/test/ui/binop/issue-77910-1.stderr | 6 +--- src/test/ui/closures/closure-move-sync.stderr | 8 ----- src/test/ui/generator/not-send-sync.stderr | 4 --- .../print/generator-print-verbose-2.stderr | 4 --- .../interior-mutability.stderr | 4 --- ...70724-add_type_neq_err_label-unwrap.stderr | 6 +--- 7 files changed, 29 insertions(+), 39 deletions(-) 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 418eae9b0e8d7..4561ab0bfe403 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -671,11 +671,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { // It only make sense when suggesting dereferences for arguments - let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { - return false; - }; - let param_env = obligation.param_env; - let body_id = obligation.cause.body_id; + let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() + else { return false; }; + let Some(typeck_results) = self.in_progress_typeck_results + else { return false; }; + let typeck_results = typeck_results.borrow(); + let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id) + else { return false; }; + let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr) + else { return false; }; + let span = obligation.cause.span; let mut real_trait_pred = trait_pred; let mut code = obligation.cause.code(); @@ -687,9 +692,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Skipping binder here, remapping below let real_ty = real_trait_pred.self_ty().skip_binder(); + if self.can_eq(obligation.param_env, real_ty, arg_ty).is_err() { + continue; + } if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { - let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span); + let mut autoderef = Autoderef::new( + self, + obligation.param_env, + obligation.cause.body_id, + span, + base_ty, + span, + ); if let Some(steps) = autoderef.find_map(|(ty, steps)| { // Re-add the `&` let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); @@ -697,8 +712,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Remapping bound vars here let real_trait_pred_and_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); - let obligation = self - .mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred_and_ty); + let obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + real_trait_pred_and_ty, + ); Some(steps).filter(|_| self.predicate_may_hold(&obligation)) }) { if steps > 0 { @@ -727,7 +744,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let real_trait_pred_and_base_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty)); let obligation = self.mk_trait_obligation_with_new_self_ty( - param_env, + obligation.param_env, real_trait_pred_and_base_ty, ); if self.predicate_may_hold(&obligation) { @@ -855,6 +872,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => return false, }; if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. }) + && obligation.cause.span.can_be_used_for_suggestions() { // When the obligation error has been ensured to have been caused by // an argument, the `obligation.cause.span` points at the expression diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr index 7ff5752fc3585..68303b842088e 100644 --- a/src/test/ui/binop/issue-77910-1.stderr +++ b/src/test/ui/binop/issue-77910-1.stderr @@ -19,12 +19,8 @@ LL | assert_eq!(foo, y); | ^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}` + = help: use parentheses to call the function: `foo(s)` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use parentheses to call the function - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | $crate::panicking::assert_failed(kind, &*left_val(s), &*right_val, $crate::option::Option::None); - | +++ error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr index 7b9f59fcc67d0..a2ca06b4e6e1a 100644 --- a/src/test/ui/closures/closure-move-sync.stderr +++ b/src/test/ui/closures/closure-move-sync.stderr @@ -22,10 +22,6 @@ note: required by a bound in `spawn` | LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` -help: consider dereferencing here - | -LL | let t = thread::spawn(*|| { - | + error[E0277]: `Sender<()>` cannot be shared between threads safely --> $DIR/closure-move-sync.rs:18:19 @@ -47,10 +43,6 @@ note: required by a bound in `spawn` | LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` -help: consider dereferencing here - | -LL | thread::spawn(*|| tx.send(()).unwrap()); - | + error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 97dbaf73ade6b..a821c57b923a0 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -23,10 +23,6 @@ note: required by a bound in `assert_send` | LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` -help: consider dereferencing here - | -LL | assert_send(*|| { - | + error: generator cannot be shared between threads safely --> $DIR/not-send-sync.rs:9:17 diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr index 14e0581897813..909e49c38b8d1 100644 --- a/src/test/ui/generator/print/generator-print-verbose-2.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr @@ -23,10 +23,6 @@ note: required by a bound in `assert_send` | LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` -help: consider dereferencing here - | -LL | assert_send(*|| { - | + error: generator cannot be shared between threads safely --> $DIR/generator-print-verbose-2.rs:12:17 diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index ee476e7aa384c..94f41c9259886 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -19,10 +19,6 @@ note: required by a bound in `catch_unwind` | LL | pub fn catch_unwind R + UnwindSafe, R>(f: F) -> Result { | ^^^^^^^^^^ required by this bound in `catch_unwind` -help: consider dereferencing here - | -LL | catch_unwind(*|| { x.set(23); }); - | + error: aborting due to previous error diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr index b834920b0d041..c6e6ea1e096af 100644 --- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr +++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr @@ -34,12 +34,8 @@ LL | assert_eq!(a, 0); | ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `fn() -> i32 {a}` + = help: use parentheses to call the function: `a()` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use parentheses to call the function - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | $crate::panicking::assert_failed(kind, &*left_val(), &*right_val, $crate::option::Option::None); - | ++ error: aborting due to 3 previous errors From 2a16a127a0ed1bf961ca7bce40499f6c407d53e2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 16:20:22 +0000 Subject: [PATCH 13/16] More docs --- compiler/rustc_middle/src/traits/mod.rs | 16 +++++++++++----- compiler/rustc_middle/src/ty/generics.rs | 4 ++++ compiler/rustc_span/src/lib.rs | 3 +++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index e91878c62fd6c..9b82320e556b3 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -234,15 +234,21 @@ pub enum ObligationCauseCode<'tcx> { /// This is the trait reference from the given projection. ProjectionWf(ty::ProjectionTy<'tcx>), - /// In an impl of trait `X` for type `Y`, type `Y` must - /// also implement all supertraits of `X`. + /// Must satisfy all of the where-clause predicates of the + /// given item. ItemObligation(DefId), - ExprItemObligation(DefId, rustc_hir::HirId, usize), - - /// Like `ItemObligation`, but with extra detail on the source of the obligation. + /// Like `ItemObligation`, but carries the span of the + /// predicate when it can be identified. BindingObligation(DefId, Span), + /// Like `ItemObligation`, but carries the `HirId` of the + /// expression that caused the obligation, and the `usize` + /// indicates exactly which predicate it is in the list of + /// instantiated predicates. + ExprItemObligation(DefId, rustc_hir::HirId, usize), + + /// Combines `ExprItemObligation` and `BindingObligation`. ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 6e8afd4d539e2..823e7f22af24d 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -122,6 +122,10 @@ pub struct Generics { } impl<'tcx> Generics { + /// Looks through the generics and all parents to find the index of the + /// given param def-id. This is in comparison to the `param_def_id_to_index` + /// struct member, which only stores information about this item's own + /// generics. pub fn param_def_id_to_index(&self, tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { if let Some(idx) = self.param_def_id_to_index.get(&def_id) { Some(*idx) diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index a624e3ab1429f..860af7fe93a07 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -664,6 +664,9 @@ impl Span { Some(self) } + /// Like `find_ancestor_inside`, but specifically for when spans might not + /// overlaps. Take care when using this, and prefer `find_ancestor_inside` + /// when you know that the spans are nested (modulo macro expansion). pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option { while !Span::eq_ctxt(self, other) { self = self.parent_callsite()?; From d2f54b1990c916c1af15124ce45dbdaa9758f7b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Aug 2022 12:16:35 +0000 Subject: [PATCH 14/16] Adjust messages, address some nits --- .../src/traits/error_reporting/suggestions.rs | 76 +++++++++---------- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 26 ++++--- src/test/ui/chalkify/type_wf.stderr | 4 +- .../ui/consts/const-block-const-bound.stderr | 4 +- src/test/ui/derives/deriving-copyclone.stderr | 6 +- src/test/ui/issues/issue-20605.stderr | 2 +- .../ui/kindck/kindck-impl-type-params-2.rs | 2 +- .../kindck/kindck-impl-type-params-2.stderr | 2 +- .../kindck-inherited-copy-bound.curr.stderr | 2 +- ...copy-bound.object_safe_for_dispatch.stderr | 2 +- .../const-drop-fail.precise.stderr | 4 +- .../const-drop-fail.stock.stderr | 4 +- .../imm-ref-trait-object-literal.stderr | 2 +- src/test/ui/suggestions/issue-62843.stderr | 2 +- src/test/ui/suggestions/issue-84973-2.stderr | 2 +- .../suggestions/issue-84973-negative.stderr | 2 +- src/test/ui/suggestions/issue-84973.stderr | 2 +- .../ui/suggestions/slice-issue-87994.stderr | 8 +- ...ggest-imm-mut-trait-implementations.stderr | 6 +- .../bound/on-structs-and-enums-locals.stderr | 4 +- .../bound/on-structs-and-enums-xc1.stderr | 4 +- src/test/ui/traits/issue-71136.stderr | 8 +- .../negated-auto-traits-error.stderr | 2 +- 23 files changed, 91 insertions(+), 85 deletions(-) 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 4561ab0bfe403..803f0dadc020f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -973,6 +973,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { || ref_inner_ty_satisfies_pred { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + // We don't want a borrowing suggestion on the fields in structs, + // ``` + // struct Foo { + // the_foos: Vec + // } + // ``` + if !matches!( + span.ctxt().outer_expn_data().kind, + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) + ) { + return false; + } + if snippet.starts_with('&') { + // This is already a literal borrow and the obligation is failing + // somewhere else in the obligation chain. Do not suggest non-sense. + return false; + } // We have a very specific type of error, where just borrowing this argument // might solve the problem. In cases like this, the important part is the // original type obligation, not the last one that failed, which is arbitrary. @@ -986,50 +1003,33 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.message = vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)]; } - if snippet.starts_with('&') { - // This is already a literal borrow and the obligation is failing - // somewhere else in the obligation chain. Do not suggest non-sense. - return false; - } err.span_label( span, - &format!( - "expected an implementor of trait `{}`", + format!( + "the trait `{}` is not implemented for `{}`", old_pred.print_modifiers_and_trait_path(), + old_pred.self_ty().skip_binder(), ), ); - // This if is to prevent a special edge-case - if matches!( - span.ctxt().outer_expn_data().kind, - ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) - ) { - // We don't want a borrowing suggestion on the fields in structs, - // ``` - // struct Foo { - // the_foos: Vec - // } - // ``` - - if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { - err.span_suggestions( - span.shrink_to_lo(), - "consider borrowing here", - ["&".to_string(), "&mut ".to_string()].into_iter(), - Applicability::MaybeIncorrect, - ); - } else { - let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; - err.span_suggestion_verbose( - span.shrink_to_lo(), - &format!( - "consider{} borrowing here", - if is_mut { " mutably" } else { "" } - ), - format!("&{}", if is_mut { "mut " } else { "" }), - Applicability::MaybeIncorrect, - ); - } + if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { + err.span_suggestions( + span.shrink_to_lo(), + "consider borrowing here", + ["&".to_string(), "&mut ".to_string()].into_iter(), + Applicability::MaybeIncorrect, + ); + } else { + let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; + err.span_suggestion_verbose( + span.shrink_to_lo(), + &format!( + "consider{} borrowing here", + if is_mut { " mutably" } else { "" } + ), + format!("&{}", if is_mut { "mut " } else { "" }), + Applicability::MaybeIncorrect, + ); } return true; } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 12f73ae96e9e5..41314644a8170 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1753,9 +1753,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() { - if let Some(param) = param - && self.point_at_arg_if_possible( + if self.point_at_arg_if_possible( error, def_id, param, @@ -1784,17 +1785,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. }) => { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() { - if let Some(param) = param - && self.point_at_arg_if_possible( - error, - def_id, - param, - hir_id, - segment.ident.span, - args, - ) - { + if self.point_at_arg_if_possible( + error, + def_id, + param, + hir_id, + segment.ident.span, + args, + ) { return true; } } @@ -1903,6 +1904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx) { error.obligation.cause.span = expr_field + .expr .span .find_ancestor_in_same_ctxt(error.obligation.cause.span) .unwrap_or(expr_field.span); diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr index 28314928a3c26..6e8daf635175f 100644 --- a/src/test/ui/chalkify/type_wf.stderr +++ b/src/test/ui/chalkify/type_wf.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `{float}: Foo` is not satisfied - --> $DIR/type_wf.rs:19:9 + --> $DIR/type_wf.rs:19:12 | LL | x: 5.0, - | ^^^^^^ the trait `Foo` is not implemented for `{float}` + | ^^^ the trait `Foo` is not implemented for `{float}` | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `S` diff --git a/src/test/ui/consts/const-block-const-bound.stderr b/src/test/ui/consts/const-block-const-bound.stderr index 87ca771e54ed4..b9c4d8866bf9d 100644 --- a/src/test/ui/consts/const-block-const-bound.stderr +++ b/src/test/ui/consts/const-block-const-bound.stderr @@ -2,7 +2,7 @@ error[E0277]: can't drop `UnconstDrop` in const contexts --> $DIR/const-block-const-bound.rs:20:11 | LL | f(UnconstDrop); - | - ^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | - ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop` | | | required by a bound introduced by this call | @@ -23,7 +23,7 @@ error[E0277]: can't drop `NonDrop` in const contexts --> $DIR/const-block-const-bound.rs:22:11 | LL | f(NonDrop); - | - ^^^^^^^ expected an implementor of trait `~const Destruct` + | - ^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop` | | | required by a bound introduced by this call | diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr index da895098e4b8e..80e2dd7fedefd 100644 --- a/src/test/ui/derives/deriving-copyclone.stderr +++ b/src/test/ui/derives/deriving-copyclone.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `B: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:31:13 | LL | is_copy(B { a: 1, b: C }); - | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy` + | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B` | | | required by a bound introduced by this call | @@ -26,7 +26,7 @@ error[E0277]: the trait bound `B: Clone` is not satisfied --> $DIR/deriving-copyclone.rs:32:14 | LL | is_clone(B { a: 1, b: C }); - | -------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone` + | -------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `B` | | | required by a bound introduced by this call | @@ -50,7 +50,7 @@ error[E0277]: the trait bound `B: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:35:13 | LL | is_copy(B { a: 1, b: D }); - | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy` + | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B` | | | required by a bound introduced by this call | diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr index b41b602a55b5c..e1858b6398932 100644 --- a/src/test/ui/issues/issue-20605.stderr +++ b/src/test/ui/issues/issue-20605.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `dyn Iterator` cann --> $DIR/issue-20605.rs:2:17 | LL | for item in *things { *item = 0 } - | ^^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` | = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.rs b/src/test/ui/kindck/kindck-impl-type-params-2.rs index 8b0771985dc3f..8950fc51e643c 100644 --- a/src/test/ui/kindck/kindck-impl-type-params-2.rs +++ b/src/test/ui/kindck/kindck-impl-type-params-2.rs @@ -11,5 +11,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = Box::new(3); take_param(&x); - //~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied + //~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied } diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr index 06d48ff1f0f27..930d96375bff4 100644 --- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr +++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied --> $DIR/kindck-impl-type-params-2.rs:13:16 | LL | take_param(&x); diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 09661289a9b77..e81d2441e6ef8 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | take_param(&x); diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 299600eb6bf30..2380533b9c3ef 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | take_param(&x); diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index ac61c3279217b..2295a822fa48b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -5,7 +5,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | NonTrivialDrop, - | ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` @@ -52,7 +52,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds` | note: required for `ConstDropImplWithBounds` to implement `~const Destruct` --> $DIR/const-drop-fail.rs:28:25 diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index ac61c3279217b..2295a822fa48b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -5,7 +5,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | NonTrivialDrop, - | ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` @@ -52,7 +52,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds` | note: required for `ConstDropImplWithBounds` to implement `~const Destruct` --> $DIR/const-drop-fail.rs:28:25 diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr index 5f3f62a7b7570..e01102e3864ea 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr @@ -21,7 +21,7 @@ error[E0277]: the trait bound `S: Trait` is not satisfied --> $DIR/imm-ref-trait-object-literal.rs:13:7 | LL | foo(s); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `S` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-62843.stderr b/src/test/ui/suggestions/issue-62843.stderr index 607e7992b9f06..62f0943d4c9d9 100644 --- a/src/test/ui/suggestions/issue-62843.stderr +++ b/src/test/ui/suggestions/issue-62843.stderr @@ -2,7 +2,7 @@ error[E0277]: expected a `FnMut<(char,)>` closure, found `String` --> $DIR/issue-62843.rs:4:32 | LL | println!("{:?}", line.find(pattern)); - | ---- ^^^^^^^ expected an implementor of trait `Pattern<'_>` + | ---- ^^^^^^^ the trait `Pattern<'_>` is not implemented for `String` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-84973-2.stderr b/src/test/ui/suggestions/issue-84973-2.stderr index 2c54ea6724505..513bf28fb5878 100644 --- a/src/test/ui/suggestions/issue-84973-2.stderr +++ b/src/test/ui/suggestions/issue-84973-2.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied --> $DIR/issue-84973-2.rs:11:9 | LL | foo(a); - | --- ^ expected an implementor of trait `Tr` + | --- ^ the trait `Tr` is not implemented for `i32` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-84973-negative.stderr b/src/test/ui/suggestions/issue-84973-negative.stderr index 15559d4ae2c2f..ce838bce09e7b 100644 --- a/src/test/ui/suggestions/issue-84973-negative.stderr +++ b/src/test/ui/suggestions/issue-84973-negative.stderr @@ -17,7 +17,7 @@ error[E0277]: the trait bound `f32: Tr` is not satisfied --> $DIR/issue-84973-negative.rs:11:9 | LL | bar(b); - | --- ^ expected an implementor of trait `Tr` + | --- ^ the trait `Tr` is not implemented for `f32` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-84973.stderr b/src/test/ui/suggestions/issue-84973.stderr index 24c989ec3e86d..ae2bf5aac40b0 100644 --- a/src/test/ui/suggestions/issue-84973.stderr +++ b/src/test/ui/suggestions/issue-84973.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied --> $DIR/issue-84973.rs:6:24 | LL | let o = Other::new(f); - | ---------- ^ expected an implementor of trait `SomeTrait` + | ---------- ^ the trait `SomeTrait` is not implemented for `Fancy` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr index 44f0da27f1360..84ecd749b0dda 100644 --- a/src/test/ui/suggestions/slice-issue-87994.stderr +++ b/src/test/ui/suggestions/slice-issue-87994.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` | = note: the trait bound `[i32]: IntoIterator` is not satisfied = note: required for `[i32]` to implement `IntoIterator` @@ -17,7 +17,7 @@ error[E0277]: `[i32]` is not an iterator --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` | = note: the trait bound `[i32]: IntoIterator` is not satisfied = note: required for `[i32]` to implement `IntoIterator` @@ -32,7 +32,7 @@ error[E0277]: the size for values of type `[K]` cannot be known at compilation t --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` | = note: the trait bound `[K]: IntoIterator` is not satisfied = note: required for `[K]` to implement `IntoIterator` @@ -47,7 +47,7 @@ error[E0277]: `[K]` is not an iterator --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` | = note: the trait bound `[K]: IntoIterator` is not satisfied = note: required for `[K]` to implement `IntoIterator` diff --git a/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr b/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr index 6583cabe18489..f2eb651eaa426 100644 --- a/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr +++ b/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `A: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:20:9 | LL | foo(a); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `A` | | | required by a bound introduced by this call | @@ -22,7 +22,7 @@ error[E0277]: the trait bound `B: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:21:9 | LL | foo(b); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `B` | | | required by a bound introduced by this call | @@ -40,7 +40,7 @@ error[E0277]: the trait bound `C: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:22:9 | LL | foo(c); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `C` | | | required by a bound introduced by this call | diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr index 4abff9fb0495a..20bbe69c059f8 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr +++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr @@ -11,10 +11,10 @@ LL | struct Foo { | ^^^^^ required by this bound in `Foo` error[E0277]: the trait bound `{integer}: Trait` is not satisfied - --> $DIR/on-structs-and-enums-locals.rs:11:9 + --> $DIR/on-structs-and-enums-locals.rs:11:12 | LL | x: 3 - | ^^^^ the trait `Trait` is not implemented for `{integer}` + | ^ the trait `Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr index dd0de44f3b119..3fb5decb723ea 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr +++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr @@ -11,10 +11,10 @@ LL | pub enum Bar { | ^^^^^ required by this bound in `Bar` error[E0277]: the trait bound `{integer}: Trait` is not satisfied - --> $DIR/on-structs-and-enums-xc1.rs:9:9 + --> $DIR/on-structs-and-enums-xc1.rs:9:12 | LL | x: 3 - | ^^^^ the trait `Trait` is not implemented for `{integer}` + | ^ the trait `Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 diff --git a/src/test/ui/traits/issue-71136.stderr b/src/test/ui/traits/issue-71136.stderr index a8a46ec11c800..f541733929d36 100644 --- a/src/test/ui/traits/issue-71136.stderr +++ b/src/test/ui/traits/issue-71136.stderr @@ -1,14 +1,18 @@ -error[E0277]: the trait bound `Vec: Clone` is not satisfied +error[E0277]: the trait bound `Foo: Clone` is not satisfied --> $DIR/issue-71136.rs:5:5 | LL | #[derive(Clone)] | ----- in this derive macro expansion LL | struct FooHolster { LL | the_foos: Vec, - | ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Clone` + | ^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Foo` | = note: required for `Vec` to implement `Clone` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Foo` with `#[derive(Clone)]` + | +LL | #[derive(Clone)] + | error: aborting due to previous error diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr index bf7c3bcc6aa9b..41fc3600fcd54 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -61,7 +61,7 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:48:13 | LL | is_send(Box::new(TestType)); - | ------- ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Send` + | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique` | | | required by a bound introduced by this call | From 5212ac9dac4c99714ca7379f7882109fb1f07405 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Aug 2022 13:27:08 +0000 Subject: [PATCH 15/16] Make check for overlapping closure span more accurate --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 55 ++++++++++++------- src/test/ui/issues/issue-69683.stderr | 28 +--------- .../mismatched_types/closure-arg-count.stderr | 6 +- .../unboxed-closures-vtable-mismatch.rs | 1 + .../unboxed-closures-vtable-mismatch.stderr | 6 +- .../non-tupled-arg-mismatch.stderr | 6 +- 6 files changed, 46 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 41314644a8170..3642b2ab03bfa 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1669,6 +1669,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx)) = *error.obligation.cause.code().peel_derives() else { return false; }; + let hir = self.tcx.hir(); + let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; }; // Skip over mentioning async lang item if Some(def_id) == self.tcx.lang_items().from_generator_fn() @@ -1677,15 +1679,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { return false; } - // Skip over closure arg mismatch, which has a better heuristic - // to determine what span to point at. - if let traits::FulfillmentErrorCode::CodeSelectionError( - traits::SelectionError::OutputTypeParameterMismatch(_, expected, _), - ) = error.code - && let ty::Closure(..) | ty::Generator(..) = expected.skip_binder().self_ty().kind() - { - return false; - } let Some(unsubstituted_pred) = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) @@ -1741,16 +1734,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); } - let hir = self.tcx.hir(); - match hir.get(hir_id) { - hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(qpath), hir_id, .. }) => { + if self.closure_span_overlaps_error(error, expr.span) { + return false; + } + + match &expr.kind { + hir::ExprKind::Path(qpath) => { if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(callee, args), hir_id: call_hir_id, + span: call_span, .. - }) = hir.get(hir.get_parent_node(*hir_id)) - && callee.hir_id == *hir_id + }) = hir.get(hir.get_parent_node(expr.hir_id)) + && callee.hir_id == expr.hir_id { + if self.closure_span_overlaps_error(error, *call_span) { + return false; + } + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() @@ -1780,10 +1781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::MethodCall(segment, args, ..), - .. - }) => { + hir::ExprKind::MethodCall(segment, args, ..) => { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() .flatten() @@ -1805,9 +1803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return true; } } - hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Struct(qpath, fields, ..), .. - }) => { + hir::ExprKind::Struct(qpath, fields, ..) => { if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) = self.typeck_results.borrow().qpath_res(qpath, hir_id) { @@ -1839,6 +1835,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } + fn closure_span_overlaps_error( + &self, + error: &traits::FulfillmentError<'tcx>, + span: Span, + ) -> bool { + if let traits::FulfillmentErrorCode::CodeSelectionError( + traits::SelectionError::OutputTypeParameterMismatch(_, expected, _), + ) = error.code + && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind() + && span.overlaps(self.tcx.def_span(*def_id)) + { + true + } else { + false + } + } + fn point_at_arg_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, diff --git a/src/test/ui/issues/issue-69683.stderr b/src/test/ui/issues/issue-69683.stderr index 248fb75b4c4e6..193de1a35cf1a 100644 --- a/src/test/ui/issues/issue-69683.stderr +++ b/src/test/ui/issues/issue-69683.stderr @@ -37,33 +37,7 @@ help: try using a fully qualified path to specify the expected types LL | >::foo(0u16, b); | +++++++++++++++++++++ ~ -error[E0283]: type annotations needed - --> $DIR/issue-69683.rs:30:10 - | -LL | 0u16.foo(b); - | ---- ^^^ - | | - | type must be known at this point - | -note: multiple `impl`s satisfying `u8: Element<_>` found - --> $DIR/issue-69683.rs:5:1 - | -LL | impl Element<()> for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl, S> Element<[S; 3]> for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required for `u16` to implement `Foo<_>` - --> $DIR/issue-69683.rs:20:9 - | -LL | impl Foo for u16 - | ^^^^^^ ^^^ -help: try using a fully qualified path to specify the expected types - | -LL | >::foo(0u16, b); - | +++++++++++++++++++++ ~ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0283, E0284. For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index a6ed22781e95f..a02ec81983883 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -133,12 +133,14 @@ LL | F: FnMut(Self::Item) -> B, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:27:53 + --> $DIR/closure-arg-count.rs:27:57 | LL | let bar = |i, x, y| i; | --------- takes 3 distinct arguments LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); - | ^^^ expected closure that takes a single 2-tuple as argument + | --- ^^^ expected closure that takes a single 2-tuple as argument + | | + | required by a bound introduced by this call | note: required by a bound in `map` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs index 0d64ded215ad4..8dbe3472ea893 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs @@ -17,5 +17,6 @@ pub fn main() { //~^ ERROR type mismatch //~| NOTE expected due to this //~| NOTE expected closure signature `fn(isize, _) -> _` + //~| NOTE required by a bound introduced by this call println!("{}", z); } diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index 0b0d9f10786f3..54b2200652746 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -1,11 +1,13 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closures-vtable-mismatch.rs:16:13 + --> $DIR/unboxed-closures-vtable-mismatch.rs:16:24 | LL | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); | ----------------------------- found signature defined here LL | LL | let z = call_it(3, f); - | ^^^^^^^ expected due to this + | ------- ^ expected due to this + | | + | required by a bound introduced by this call | = note: expected closure signature `fn(isize, _) -> _` found closure signature `fn(usize, _) -> _` diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr index d8e9776bb0063..9a24fb8c2beec 100644 --- a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr +++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr @@ -1,10 +1,8 @@ error[E0308]: mismatched types - --> $DIR/non-tupled-arg-mismatch.rs:6:7 + --> $DIR/non-tupled-arg-mismatch.rs:6:5 | LL | a(|_: usize| {}); - | - ^^^^^^^^^^^^^ types differ - | | - | required by a bound introduced by this call + | ^ types differ | = note: expected trait `Fn` found trait `Fn<(usize,)>` From d577eb09e5ad90fc380091439bda74fae837f001 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 21 Aug 2022 03:52:08 +0000 Subject: [PATCH 16/16] Bless tests after #100769 --- .../src/traits/error_reporting/suggestions.rs | 187 +++++++++--------- ...dding-reference-to-trait-assoc-item.stderr | 4 +- 2 files changed, 97 insertions(+), 94 deletions(-) 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 803f0dadc020f..a93f9ec0397d2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -903,7 +903,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation.cause.code() { &parent_code - } else if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() { + } else if let ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code() + { obligation.cause.code() } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) = span.ctxt().outer_expn_data().kind @@ -929,35 +931,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let param_env = obligation.param_env; // Try to apply the original trait binding obligation by borrowing. - let mut try_borrowing = - |old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool { - if blacklist.contains(&old_pred.def_id()) { - return false; - } - // We map bounds to `&T` and `&mut T` - let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| { - ( - trait_pred, - self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), - ) - }); - let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| { - ( - trait_pred, - self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), - ) - }); + let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>, + blacklist: &[DefId]| + -> bool { + if blacklist.contains(&old_pred.def_id()) { + return false; + } + // We map bounds to `&T` and `&mut T` + let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| { + ( + trait_pred, + self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), + ) + }); + let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| { + ( + trait_pred, + self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), + ) + }); - let mk_result = |trait_pred_and_new_ty| { - let obligation = - self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty); - self.predicate_must_hold_modulo_regions(&obligation) - }; - let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); - let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); + let mk_result = |trait_pred_and_new_ty| { + let obligation = + self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty); + self.predicate_must_hold_modulo_regions(&obligation) + }; + let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); + let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); - let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = - if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() + let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = + if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { ( @@ -968,74 +971,74 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { (false, false) }; - if imm_ref_self_ty_satisfies_pred - || mut_ref_self_ty_satisfies_pred - || ref_inner_ty_satisfies_pred - { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - // We don't want a borrowing suggestion on the fields in structs, - // ``` - // struct Foo { - // the_foos: Vec - // } - // ``` - if !matches!( - span.ctxt().outer_expn_data().kind, - ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) - ) { - return false; - } - if snippet.starts_with('&') { - // This is already a literal borrow and the obligation is failing - // somewhere else in the obligation chain. Do not suggest non-sense. - return false; - } - // We have a very specific type of error, where just borrowing this argument - // might solve the problem. In cases like this, the important part is the - // original type obligation, not the last one that failed, which is arbitrary. - // Because of this, we modify the error to refer to the original obligation and - // return early in the caller. - - let msg = format!("the trait bound `{}` is not satisfied", old_pred); - if has_custom_message { - err.note(&msg); - } else { - err.message = - vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)]; - } - err.span_label( - span, - format!( - "the trait `{}` is not implemented for `{}`", - old_pred.print_modifiers_and_trait_path(), - old_pred.self_ty().skip_binder(), + if imm_ref_self_ty_satisfies_pred + || mut_ref_self_ty_satisfies_pred + || ref_inner_ty_satisfies_pred + { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + // We don't want a borrowing suggestion on the fields in structs, + // ``` + // struct Foo { + // the_foos: Vec + // } + // ``` + if !matches!( + span.ctxt().outer_expn_data().kind, + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) + ) { + return false; + } + if snippet.starts_with('&') { + // This is already a literal borrow and the obligation is failing + // somewhere else in the obligation chain. Do not suggest non-sense. + return false; + } + // We have a very specific type of error, where just borrowing this argument + // might solve the problem. In cases like this, the important part is the + // original type obligation, not the last one that failed, which is arbitrary. + // Because of this, we modify the error to refer to the original obligation and + // return early in the caller. + + let msg = format!("the trait bound `{}` is not satisfied", old_pred); + if has_custom_message { + err.note(&msg); + } else { + err.message = + vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)]; + } + err.span_label( + span, + format!( + "the trait `{}` is not implemented for `{}`", + old_pred.print_modifiers_and_trait_path(), + old_pred.self_ty().skip_binder(), + ), + ); + + if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { + err.span_suggestions( + span.shrink_to_lo(), + "consider borrowing here", + ["&".to_string(), "&mut ".to_string()].into_iter(), + Applicability::MaybeIncorrect, + ); + } else { + let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; + err.span_suggestion_verbose( + span.shrink_to_lo(), + &format!( + "consider{} borrowing here", + if is_mut { " mutably" } else { "" } ), + format!("&{}", if is_mut { "mut " } else { "" }), + Applicability::MaybeIncorrect, ); - - if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { - err.span_suggestions( - span.shrink_to_lo(), - "consider borrowing here", - ["&".to_string(), "&mut ".to_string()].into_iter(), - Applicability::MaybeIncorrect, - ); - } else { - let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; - err.span_suggestion_verbose( - span.shrink_to_lo(), - &format!( - "consider{} borrowing here", - if is_mut { " mutably" } else { "" } - ), - format!("&{}", if is_mut { "mut " } else { "" }), - Applicability::MaybeIncorrect, - ); - } - return true; } + return true; } - return false; - }; + } + return false; + }; if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code { try_borrowing(cause.derived.parent_trait_pred, &[]) diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr index b930d22a3915e..125a8b44f2f0a 100644 --- a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr +++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&mut usize: Default` is not satisfied --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9 | LL | foo(Default::default()); - | ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default` + | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize` | help: consider mutably borrowing here | @@ -13,7 +13,7 @@ error[E0277]: the trait bound `&usize: Default` is not satisfied --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9 | LL | bar(Default::default()); - | ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default` + | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize` | help: consider borrowing here |