From 120c24dab5806d458513b399151a411cb367697f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 24 Aug 2023 19:23:06 +0000 Subject: [PATCH 1/5] Point at appropriate type parameter in more trait bound errors --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 45 +++++++++++++++++++ .../associated-types-issue-20346.stderr | 6 +-- tests/ui/function-pointer/unsized-ret.stderr | 12 ++--- tests/ui/issues/issue-87199.stderr | 6 +-- ...-trait-object-literal-bound-regions.stderr | 6 +-- .../builtin-fn-must-return-sized.stderr | 6 +-- .../fixpoint-exponential-growth.stderr | 4 +- .../double-cycle-inductive-coinductive.stderr | 8 ++-- .../cycles/inductive-not-on-stack.stderr | 4 +- ..._of-tait-in-defining-scope.not_send.stderr | 4 +- .../overflow/exponential-trait-goals.stderr | 4 +- .../new-solver/overflow/global-cache.stderr | 4 +- .../recursive-self-normalization-2.stderr | 4 +- .../recursive-self-normalization.stderr | 4 +- .../specialization-unconstrained.stderr | 4 +- ...tion-param-candidates-are-ambiguous.stderr | 4 +- ...0804-incorrect-reference-suggestion.stderr | 6 +-- tests/ui/unsized/unsized3.stderr | 12 ++--- 18 files changed, 85 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f6a5b8f97a1..f50aeaf4511 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -67,6 +67,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) }; + // Account for enum variant constructors, where the type param corresponds to the enum + // itself. + let enum_def_id = if let hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _) = + self.tcx.def_kind(def_id) + { + // `def_id` corresponds to a constructor, and its parent is the variant, and we want + // the enum. + Some(self.tcx.parent(self.tcx.parent(def_id))) + } else { + None + }; + let variant_param_to_point_at = find_param_matching(&|param_term| { + // FIXME: It would be nice to make this not use string manipulation, + // but it's pretty hard to do this, since `ty::ParamTy` is missing + // sufficient info to determine if it is synthetic, and we don't + // always have a convenient way of getting `ty::Generics` at the call + // sites we invoke `IsSuggestable::is_suggestable`. + let include = match param_term { + ty::ParamTerm::Ty(param_ty) => !param_ty.name.as_str().starts_with("impl "), + _ => true, + }; + // Account for enum variant constructors, where the type param corresponds to the enum + // itself. + let def_id = if let Some(def_id) = enum_def_id { + def_id + } else { + def_id + }; + self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id + && include + }); // Prefer generics that are local to the fn item, since these are likely // to be the cause of the unsatisfied predicate. let mut param_to_point_at = find_param_matching(&|param_term| { @@ -102,6 +133,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &expr.kind { hir::ExprKind::Path(qpath) => { + let def_id = if let Some(def_id) = enum_def_id { + def_id + } else { + def_id + }; + if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind { + for segment in path.segments { + if let Some(param) = variant_param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param, segment) + { + return true; + } + } + } if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(callee, args), hir_id: call_hir_id, diff --git a/tests/ui/associated-types/associated-types-issue-20346.stderr b/tests/ui/associated-types/associated-types-issue-20346.stderr index b1708b96e52..d8b0433d3e8 100644 --- a/tests/ui/associated-types/associated-types-issue-20346.stderr +++ b/tests/ui/associated-types/associated-types-issue-20346.stderr @@ -1,13 +1,11 @@ error[E0271]: type mismatch resolving ` as Iterator>::Item == Option` - --> $DIR/associated-types-issue-20346.rs:34:36 + --> $DIR/associated-types-issue-20346.rs:34:33 | LL | fn test_adapter>>(it: I) { | - this type parameter ... LL | is_iterator_of::, _>(&adapter); - | ------------------------------ ^^^^^^^^ type mismatch resolving ` as Iterator>::Item == Option` - | | - | required by a bound introduced by this call + | ^ type mismatch resolving ` as Iterator>::Item == Option` | note: expected this to be `Option` --> $DIR/associated-types-issue-20346.rs:23:17 diff --git a/tests/ui/function-pointer/unsized-ret.stderr b/tests/ui/function-pointer/unsized-ret.stderr index 870f1805b58..dcfec53eeb9 100644 --- a/tests/ui/function-pointer/unsized-ret.stderr +++ b/tests/ui/function-pointer/unsized-ret.stderr @@ -1,10 +1,8 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-ret.rs:10:27 + --> $DIR/unsized-ret.rs:10:11 | LL | foo:: str, _>(None, ()); - | --------------------- ^^^^ 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 `fn() -> str`, the trait `Sized` is not implemented for `str` = note: required because it appears within the type `fn() -> str` @@ -15,12 +13,10 @@ LL | fn foo, T:std::marker::Tuple>(f: Option, t: T) { | ^^^^^ required by this bound in `foo` error[E0277]: the size for values of type `(dyn std::fmt::Display + 'a)` cannot be known at compilation time - --> $DIR/unsized-ret.rs:13:66 + --> $DIR/unsized-ret.rs:13:11 | LL | foo:: fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&(),)); - | ------------------------------------------------------------ ^^^^ 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 `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)` = note: required because it appears within the type `fn(&()) -> dyn Display` diff --git a/tests/ui/issues/issue-87199.stderr b/tests/ui/issues/issue-87199.stderr index 0ec5e73f39a..67949b37d40 100644 --- a/tests/ui/issues/issue-87199.stderr +++ b/tests/ui/issues/issue-87199.stderr @@ -17,12 +17,10 @@ LL | fn ret() -> impl Iterator + ?Send { std::iter::empty() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/issue-87199.rs:18:22 + --> $DIR/issue-87199.rs:18:15 | LL | ref_arg::<[i32]>(&[5]); - | ---------------- ^^^^ 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 `[i32]` note: required by a bound in `ref_arg` diff --git a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr index fc5a521746a..11f94c604a1 100644 --- a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr +++ b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `for<'b> &'b S: Trait` is not satisfied - --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:14 + --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:11 | LL | foo::(s); - | -------- ^ the trait `for<'b> Trait` is not implemented for `&'b S` - | | - | required by a bound introduced by this call + | ^ the trait `for<'b> Trait` is not implemented for `&'b S` | = 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/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr b/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr index f7551739b13..4eaa259617b 100644 --- a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr +++ b/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr @@ -1,10 +1,8 @@ error[E0277]: expected a `Fn<_>` closure, found `fn() -> str` - --> $DIR/builtin-fn-must-return-sized.rs:15:27 + --> $DIR/builtin-fn-must-return-sized.rs:15:11 | LL | foo:: str, _>(None, ()); - | --------------------- ^^^^ expected an `Fn<_>` closure, found `fn() -> str` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^ expected an `Fn<_>` closure, found `fn() -> str` | = help: the trait `Fn<_>` is not implemented for `fn() -> str` note: required by a bound in `foo` diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr index 7d3535e1f01..a861156711d 100644 --- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr +++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr @@ -5,10 +5,10 @@ LL | impls::>(); | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls` error[E0275]: overflow evaluating the requirement `W<_>: Trait` - --> $DIR/fixpoint-exponential-growth.rs:29:5 + --> $DIR/fixpoint-exponential-growth.rs:29:13 | LL | impls::>(); - | ^^^^^^^^^^^^^ + | ^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`) note: required by a bound in `impls` diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr index 4b8846da535..a3404da51f0 100644 --- a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr +++ b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow evaluating the requirement `(): Trait` - --> $DIR/double-cycle-inductive-coinductive.rs:32:5 + --> $DIR/double-cycle-inductive-coinductive.rs:32:19 | LL | impls_trait::<()>(); - | ^^^^^^^^^^^^^^^^^ + | ^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`) note: required by a bound in `impls_trait` @@ -12,10 +12,10 @@ LL | fn impls_trait() {} | ^^^^^ required by this bound in `impls_trait` error[E0275]: overflow evaluating the requirement `(): TraitRev` - --> $DIR/double-cycle-inductive-coinductive.rs:35:5 + --> $DIR/double-cycle-inductive-coinductive.rs:35:23 | LL | impls_trait_rev::<()>(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`) note: required by a bound in `impls_trait_rev` diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr index 0e1c86c1bb3..34115334063 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow evaluating the requirement `(): AR` - --> $DIR/inductive-not-on-stack.rs:44:5 + --> $DIR/inductive-not-on-stack.rs:44:16 | LL | impls_ar::<()>(); - | ^^^^^^^^^^^^^^ + | ^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) note: required by a bound in `impls_ar` diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr index ec1c3231abc..a31bfd9589b 100644 --- a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr +++ b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr @@ -1,8 +1,8 @@ error[E0283]: type annotations needed: cannot satisfy `Foo: Send` - --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:5 + --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18 | LL | needs_send::(); - | ^^^^^^^^^^^^^^^^^ + | ^^^ | = note: cannot satisfy `Foo: Send` note: required by a bound in `needs_send` diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr index 28a99cbbca6..beed40f3649 100644 --- a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr +++ b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr @@ -5,10 +5,10 @@ LL | impls::>(); | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls` error[E0275]: overflow evaluating the requirement `W<_>: Trait` - --> $DIR/exponential-trait-goals.rs:17:5 + --> $DIR/exponential-trait-goals.rs:17:13 | LL | impls::>(); - | ^^^^^^^^^^^^^ + | ^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`exponential_trait_goals`) note: required by a bound in `impls` diff --git a/tests/ui/traits/new-solver/overflow/global-cache.stderr b/tests/ui/traits/new-solver/overflow/global-cache.stderr index f3b86a083ad..ebb03d84b87 100644 --- a/tests/ui/traits/new-solver/overflow/global-cache.stderr +++ b/tests/ui/traits/new-solver/overflow/global-cache.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow evaluating the requirement `Inc>>>>>>: Trait` - --> $DIR/global-cache.rs:21:5 + --> $DIR/global-cache.rs:21:19 | LL | impls_trait::>>>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`) note: required by a bound in `impls_trait` diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr index eebaf21d7df..1dc63fae98c 100644 --- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow evaluating the requirement `::Assoc1: Bar` - --> $DIR/recursive-self-normalization-2.rs:16:5 + --> $DIR/recursive-self-normalization-2.rs:16:17 | LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) note: required by a bound in `needs_bar` diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr index 6a87fe2f121..afc5bfa54ac 100644 --- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr +++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Bar` - --> $DIR/recursive-self-normalization.rs:12:5 + --> $DIR/recursive-self-normalization.rs:12:17 | LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) note: required by a bound in `needs_bar` diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/new-solver/specialization-unconstrained.stderr index 9915da1a27a..ff0440d51ad 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/new-solver/specialization-unconstrained.stderr @@ -15,10 +15,10 @@ LL | default type Id = T; | ^ cannot infer type for associated type `::Id` error[E0284]: type annotations needed: cannot satisfy `::Id == ()` - --> $DIR/specialization-unconstrained.rs:20:5 + --> $DIR/specialization-unconstrained.rs:20:12 | LL | test::(); - | ^^^^^^^^^^^^^^^ cannot satisfy `::Id == ()` + | ^^^ cannot satisfy `::Id == ()` | note: required by a bound in `test` --> $DIR/specialization-unconstrained.rs:17:20 diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr index 83a0452b088..b311ac6b5a6 100644 --- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr @@ -1,8 +1,8 @@ error[E0283]: type annotations needed: cannot satisfy `T: Bar` - --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:5 + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17 | LL | needs_bar::(); - | ^^^^^^^^^^^^^^ + | ^ | = note: cannot satisfy `T: Bar` = help: the trait `Bar` is implemented for `T` diff --git a/tests/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr b/tests/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr index 08eab025370..a75024aa248 100644 --- a/tests/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr +++ b/tests/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `(): Marker` is not satisfied - --> $DIR/issue-90804-incorrect-reference-suggestion.rs:10:17 + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:10:13 | LL | check::<()>(()); - | ----------- ^^ the trait `Marker` is not implemented for `()` - | | - | required by a bound introduced by this call + | ^^ the trait `Marker` is not implemented for `()` | note: required by a bound in `check` --> $DIR/issue-90804-incorrect-reference-suggestion.rs:7:17 diff --git a/tests/ui/unsized/unsized3.stderr b/tests/ui/unsized/unsized3.stderr index 3ef9a875358..a11243980d1 100644 --- a/tests/ui/unsized/unsized3.stderr +++ b/tests/ui/unsized/unsized3.stderr @@ -1,12 +1,10 @@ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized3.rs:7:13 + --> $DIR/unsized3.rs:7:10 | LL | fn f1(x: &X) { | - this type parameter needs to be `Sized` LL | f2::(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 | note: required by a bound in `f2` --> $DIR/unsized3.rs:10:7 @@ -24,14 +22,12 @@ LL | fn f2(x: &X) { | ++++++++ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized3.rs:18:13 + --> $DIR/unsized3.rs:18:10 | LL | fn f3(x: &X) { | - this type parameter needs to be `Sized` LL | f4::(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 | note: required by a bound in `f4` --> $DIR/unsized3.rs:21:7 From bac0e556f008f5853d13fd98b859348b5ba813a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 Aug 2023 15:59:59 +0000 Subject: [PATCH 2/5] On let binding type point to type parameter that introduced unmet bound On the following example, point at `String` instead of the whole type: ``` error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/own-bound-span.rs:14:24 | LL | let _: ::P; | ^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `D::P` --> $DIR/own-bound-span.rs:4:15 | LL | type P; | ^^^^ required by this bound in `D::P` ``` --- compiler/rustc_hir_typeck/src/closure.rs | 2 +- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 154 +++++++++--------- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 12 +- ...ted-types-invalid-trait-ref-issue-18865.rs | 1 + ...types-invalid-trait-ref-issue-18865.stderr | 13 +- .../multiple-type-params-with-unmet-bounds.rs | 11 ++ ...tiple-type-params-with-unmet-bounds.stderr | 27 +++ .../own-bound-span.rs | 4 + .../own-bound-span.stderr | 16 +- tests/ui/issues/issue-66353.rs | 1 + tests/ui/issues/issue-66353.stderr | 8 +- .../assoc_type_bounds_sized_used.rs | 1 + .../assoc_type_bounds_sized_used.stderr | 26 ++- .../assoc-type-const-bound-usage.stderr | 13 +- 14 files changed, 206 insertions(+), 83 deletions(-) create mode 100644 tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs create mode 100644 tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index b19fb6da6de..e426b937542 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let inferred_sig = self.normalize( span, self.deduce_sig_from_projection( - Some(span), + Some(span), bound_predicate.rebind(proj_predicate), ), ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f50aeaf4511..5be67a4b14e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -20,10 +20,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else { return false; }; - let hir = self.tcx.hir(); - let hir::Node::Expr(expr) = hir.get(hir_id) else { - return false; - }; let Some(unsubstituted_pred) = self .tcx @@ -69,15 +65,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Account for enum variant constructors, where the type param corresponds to the enum // itself. - let enum_def_id = if let hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _) = - self.tcx.def_kind(def_id) - { - // `def_id` corresponds to a constructor, and its parent is the variant, and we want - // the enum. - Some(self.tcx.parent(self.tcx.parent(def_id))) - } else { - None - }; + let enum_def_id = + if let DefKind::Ctor(hir::def::CtorOf::Variant, _) = self.tcx.def_kind(def_id) { + // `def_id` corresponds to a constructor, and its parent is the variant, and we want + // the enum. + Some(self.tcx.parent(self.tcx.parent(def_id))) + } else { + None + }; let variant_param_to_point_at = find_param_matching(&|param_term| { // FIXME: It would be nice to make this not use string manipulation, // but it's pretty hard to do this, since `ty::ParamTy` is missing @@ -90,11 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Account for enum variant constructors, where the type param corresponds to the enum // itself. - let def_id = if let Some(def_id) = enum_def_id { - def_id - } else { - def_id - }; + let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id }; self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id && include }); @@ -127,68 +118,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); } - if self.closure_span_overlaps_error(error, expr.span) { - return false; - } - - match &expr.kind { - hir::ExprKind::Path(qpath) => { - let def_id = if let Some(def_id) = enum_def_id { - def_id - } else { - def_id - }; - if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind { - for segment in path.segments { - if let Some(param) = variant_param_to_point_at - && self.point_at_generic_if_possible(error, def_id, param, segment) - { - return true; - } - } + let hir = self.tcx.hir(); + let (expr, qpath) = match hir.get(hir_id) { + hir::Node::Expr(expr) => { + if self.closure_span_overlaps_error(error, expr.span) { + return false; } - if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Call(callee, args), - hir_id: call_hir_id, - span: call_span, - .. - }) = hir.get_parent(expr.hir_id) - && callee.hir_id == expr.hir_id - { - if self.closure_span_overlaps_error(error, *call_span) { - return false; - } + let qpath = + if let hir::ExprKind::Path(qpath) = expr.kind { Some(qpath) } else { None }; - for param in - [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] - .into_iter() - .flatten() + (Some(*expr), qpath) + } + hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => (None, Some(*qpath)), + _ => return false, + }; + + if let Some(qpath) = qpath { + let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id }; + if let hir::QPath::Resolved(None, path) = qpath { + for segment in path.segments { + if let Some(param) = variant_param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param, segment) { - if self.blame_specific_arg_if_possible( - error, - def_id, - param, - *call_hir_id, - callee.span, - None, - args, - ) - { - return true; - } - } - } - - for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] - .into_iter() - .flatten() - { - if self.point_at_path_if_possible(error, def_id, param, qpath) { return true; } } } - hir::ExprKind::MethodCall(segment, receiver, args, ..) => { + if let hir::QPath::TypeRelative(_ty, segment) = qpath { + if let Some(param) = variant_param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param, segment) + { + return true; + } + } + if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Call(callee, args), + hir_id: call_hir_id, + span: call_span, + .. + }) = hir.get_parent(hir_id) + && callee.hir_id == 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() + .flatten() + { + if self.blame_specific_arg_if_possible( + error, + def_id, + param, + *call_hir_id, + callee.span, + None, + args, + ) + { + return true; + } + } + } + + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() + { + if self.point_at_path_if_possible(error, def_id, param, &qpath) { + return true; + } + } + } + + match expr.map(|e| e.kind) { + Some(hir::ExprKind::MethodCall(segment, receiver, args, ..)) => { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() .flatten() @@ -220,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return true; } } - hir::ExprKind::Struct(qpath, fields, ..) => { + Some(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) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 6a82b00211e..45bf43efa83 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -317,7 +317,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) { // FIXME: normalization and escaping regions - let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty }; + let ty = if !ty.has_escaping_bound_vars() { + if let ty::Alias(ty::AliasKind::Projection, ty::AliasTy { args, def_id, .. }) = + ty.kind() + { + self.add_required_obligations_for_hir(span, *def_id, args, hir_id); + self.select_obligations_where_possible(|_| {}); + } + self.normalize(span, ty) + } else { + ty + }; self.write_ty(hir_id, ty) } diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs index 3bd3f3a757c..473a68833b6 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs @@ -9,6 +9,7 @@ trait Foo { fn f>(t: &T) { let u: >::Bar = t.get_bar(); //~^ ERROR the trait bound `T: Foo` is not satisfied + //~| ERROR the trait bound `T: Foo` is not satisfied } fn main() { } diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr index 8fecfdf7b93..02906e821c5 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr @@ -1,3 +1,14 @@ +error[E0277]: the trait bound `T: Foo` is not satisfied + --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:22 + | +LL | let u: >::Bar = t.get_bar(); + | ^^^^^ the trait `Foo` is not implemented for `T` + | +help: consider further restricting this bound + | +LL | fn f + Foo>(t: &T) { + | ++++++++++++ + error[E0277]: the trait bound `T: Foo` is not satisfied --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12 | @@ -9,6 +20,6 @@ help: consider further restricting this bound LL | fn f + Foo>(t: &T) { | ++++++++++++ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs new file mode 100644 index 00000000000..ffb45f4bc75 --- /dev/null +++ b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs @@ -0,0 +1,11 @@ +trait Trait { + type P; +} +impl Trait for () { + type P = (); +} +fn main() { + let _: <() as Trait>::P; + //~^ ERROR the trait bound `String: Copy` is not satisfied + //~| ERROR the trait bound `String: Copy` is not satisfied +} diff --git a/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr new file mode 100644 index 00000000000..7f3b75c0629 --- /dev/null +++ b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr @@ -0,0 +1,27 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/multiple-type-params-with-unmet-bounds.rs:8:29 + | +LL | let _: <() as Trait>::P; + | ^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `Trait::P` + --> $DIR/multiple-type-params-with-unmet-bounds.rs:2:15 + | +LL | type P; + | ^^^^ required by this bound in `Trait::P` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/multiple-type-params-with-unmet-bounds.rs:8:12 + | +LL | let _: <() as Trait>::P; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `Trait::P` + --> $DIR/multiple-type-params-with-unmet-bounds.rs:2:15 + | +LL | type P; + | ^^^^ required by this bound in `Trait::P` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/own-bound-span.rs b/tests/ui/generic-associated-types/own-bound-span.rs index 3699f7296f5..72d0fd9897f 100644 --- a/tests/ui/generic-associated-types/own-bound-span.rs +++ b/tests/ui/generic-associated-types/own-bound-span.rs @@ -4,6 +4,8 @@ trait D { type P; //~^ NOTE required by this bound in `D::P` //~| NOTE required by a bound in `D::P` + //~| NOTE required by this bound in `D::P` + //~| NOTE required by a bound in `D::P` } impl D for S { @@ -14,4 +16,6 @@ fn main() { let _: ::P; //~^ ERROR the trait bound `String: Copy` is not satisfied //~| NOTE the trait `Copy` is not implemented for `String` + //~| ERROR the trait bound `String: Copy` is not satisfied + //~| NOTE the trait `Copy` is not implemented for `String` } diff --git a/tests/ui/generic-associated-types/own-bound-span.stderr b/tests/ui/generic-associated-types/own-bound-span.stderr index 8ab8ea623b2..98bf55bc208 100644 --- a/tests/ui/generic-associated-types/own-bound-span.stderr +++ b/tests/ui/generic-associated-types/own-bound-span.stderr @@ -1,5 +1,17 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/own-bound-span.rs:14:12 + --> $DIR/own-bound-span.rs:16:24 + | +LL | let _: ::P; + | ^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `D::P` + --> $DIR/own-bound-span.rs:4:15 + | +LL | type P; + | ^^^^ required by this bound in `D::P` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/own-bound-span.rs:16:12 | LL | let _: ::P; | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` @@ -10,6 +22,6 @@ note: required by a bound in `D::P` LL | type P; | ^^^^ required by this bound in `D::P` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-66353.rs b/tests/ui/issues/issue-66353.rs index d8abdd5206e..484a28e564b 100644 --- a/tests/ui/issues/issue-66353.rs +++ b/tests/ui/issues/issue-66353.rs @@ -11,5 +11,6 @@ trait _A { fn main() { _Func::< <() as _A>::AssocT >::func(()); //~^ ERROR the trait bound `(): _A` is not satisfied + //~| ERROR the trait bound `(): _A` is not satisfied //~| ERROR the trait bound `(): _Func<_>` is not satisfied } diff --git a/tests/ui/issues/issue-66353.stderr b/tests/ui/issues/issue-66353.stderr index 3356180974f..49eb013c1d8 100644 --- a/tests/ui/issues/issue-66353.stderr +++ b/tests/ui/issues/issue-66353.stderr @@ -1,3 +1,9 @@ +error[E0277]: the trait bound `(): _A` is not satisfied + --> $DIR/issue-66353.rs:12:15 + | +LL | _Func::< <() as _A>::AssocT >::func(()); + | ^^ the trait `_A` is not implemented for `()` + error[E0277]: the trait bound `(): _A` is not satisfied --> $DIR/issue-66353.rs:12:14 | @@ -12,6 +18,6 @@ LL | _Func::< <() as _A>::AssocT >::func(()); | | | required by a bound introduced by this call -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/tests/ui/object-safety/assoc_type_bounds_sized_used.rs b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs index cf5345b1c1d..f685a7f626f 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs +++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs @@ -12,6 +12,7 @@ fn bop() { let _ = ::Bar::default(); //~^ ERROR: trait bounds were not satisfied //~| ERROR: the size for values of type `T` cannot be known at compilation time + //~| ERROR: the size for values of type `T` cannot be known at compilation time } fn main() { diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr index f8488d842e2..f551d657ab5 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr +++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr @@ -1,3 +1,25 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/assoc_type_bounds_sized_used.rs:12:14 + | +LL | fn bop() { + | - this type parameter needs to be `Sized` +LL | let _ = ::Bar::default(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `Bop::Bar` + --> $DIR/assoc_type_bounds_sized_used.rs:8:15 + | +LL | type Bar: Default + | --- required by a bound in this associated type +LL | where +LL | Self: Sized; + | ^^^^^ required by this bound in `Bop::Bar` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn bop() { +LL + fn bop() { + | + error[E0599]: the function or associated item `default` exists for associated type `::Bar`, but its trait bounds were not satisfied --> $DIR/assoc_type_bounds_sized_used.rs:12:30 | @@ -35,7 +57,7 @@ LL + fn bop() { | error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time - --> $DIR/assoc_type_bounds_sized_used.rs:18:11 + --> $DIR/assoc_type_bounds_sized_used.rs:19:11 | LL | bop::(); | ^^^^^^^ doesn't have a size known at compile-time @@ -47,7 +69,7 @@ note: required by a bound in `bop` LL | fn bop() { | ^^^ required by this bound in `bop` -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/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr index 4fcfe9d4769..72ff11d586f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr @@ -1,3 +1,14 @@ +error[E0277]: the trait bound `T: Foo` is not satisfied + --> $DIR/assoc-type-const-bound-usage.rs:12:6 + | +LL | ::Assoc::foo(); + | ^ the trait `Foo` is not implemented for `T` + | +help: consider further restricting this bound + | +LL | const fn foo() { + | +++++ + error[E0277]: the trait bound `T: Foo` is not satisfied --> $DIR/assoc-type-const-bound-usage.rs:12:5 | @@ -9,6 +20,6 @@ help: consider further restricting this bound LL | const fn foo() { | +++++ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. From b6494a7bb4dd5dfe0c772ef1ac7539ab5f535044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Aug 2023 19:25:46 +0000 Subject: [PATCH 3/5] More accurately point at arguments --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 78 ++++++++----------- .../argument-suggestions/issue-100154.stderr | 6 +- ...types-invalid-trait-ref-issue-18865.stderr | 4 +- .../associated-types-issue-20346.stderr | 6 +- .../ui/const-generics/exhaustive-value.stderr | 4 +- tests/ui/inference/issue-72690.stderr | 14 ++-- tests/ui/issues/issue-29147.stderr | 4 +- ...e-66923-show-error-for-correct-call.stderr | 6 +- ...valid-iterator-chain-with-int-infer.stderr | 6 +- .../iterators/invalid-iterator-chain.stderr | 30 ++++--- tests/ui/methods/issues/issue-61525.stderr | 4 +- ...lue-fallback-issue-66757.nofallback.stderr | 6 +- tests/ui/on-unimplemented/sum.stderr | 12 ++- tests/ui/suggestions/assoc-const-as-fn.stderr | 6 +- ...-trait-object-literal-bound-regions.stderr | 6 +- .../ui/traits/bad-method-typaram-kind.stderr | 4 +- ...dont-autoderef-ty-with-escaping-var.stderr | 6 +- .../repeated-supertrait-ambig.stderr | 6 +- tests/ui/traits/issue-77982.stderr | 18 +---- .../specialization-unconstrained.stderr | 4 +- .../reservation-impl/no-use.next.stderr | 6 +- .../traits/reservation-impl/no-use.old.stderr | 6 +- tests/ui/traits/suggest-where-clause.stderr | 12 +-- tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr | 6 +- 24 files changed, 124 insertions(+), 136 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 5be67a4b14e..2acb43c51da 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -43,6 +43,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return false, }; + let direct_param = if let ty::ClauseKind::Trait(pred) = unsubstituted_pred.kind().skip_binder() + && let ty = pred.trait_ref.self_ty() + && let ty::Param(_param) = ty.kind() + && let Some(arg) = predicate_args.get(0) + && let ty::GenericArgKind::Type(arg_ty) = arg.unpack() + && arg_ty == ty + { + Some(*arg) + } else { + None + }; let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| { predicate_args.iter().find_map(|arg| { arg.walk().find_map(|arg| { @@ -63,32 +74,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) }; - // Account for enum variant constructors, where the type param corresponds to the enum - // itself. - let enum_def_id = - if let DefKind::Ctor(hir::def::CtorOf::Variant, _) = self.tcx.def_kind(def_id) { - // `def_id` corresponds to a constructor, and its parent is the variant, and we want - // the enum. - Some(self.tcx.parent(self.tcx.parent(def_id))) - } else { - None - }; - let variant_param_to_point_at = find_param_matching(&|param_term| { - // FIXME: It would be nice to make this not use string manipulation, - // but it's pretty hard to do this, since `ty::ParamTy` is missing - // sufficient info to determine if it is synthetic, and we don't - // always have a convenient way of getting `ty::Generics` at the call - // sites we invoke `IsSuggestable::is_suggestable`. - let include = match param_term { - ty::ParamTerm::Ty(param_ty) => !param_ty.name.as_str().starts_with("impl "), - _ => true, - }; - // Account for enum variant constructors, where the type param corresponds to the enum - // itself. - let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id }; - self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id - && include - }); // Prefer generics that are local to the fn item, since these are likely // to be the cause of the unsatisfied predicate. let mut param_to_point_at = find_param_matching(&|param_term| { @@ -134,20 +119,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let Some(qpath) = qpath { - let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id }; - if let hir::QPath::Resolved(None, path) = qpath { - for segment in path.segments { - if let Some(param) = variant_param_to_point_at - && self.point_at_generic_if_possible(error, def_id, param, segment) - { - return true; - } - } - } - if let hir::QPath::TypeRelative(_ty, segment) = qpath { - if let Some(param) = variant_param_to_point_at - && self.point_at_generic_if_possible(error, def_id, param, segment) - { + if let Some(param) = direct_param { + if self.point_at_path_if_possible(error, def_id, param, &qpath) { return true; } } @@ -195,6 +168,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match expr.map(|e| e.kind) { Some(hir::ExprKind::MethodCall(segment, receiver, args, ..)) => { + if let Some(param) = direct_param + && self.point_at_generic_if_possible(error, def_id, param, segment) + { + error.obligation.cause.map_code(|parent_code| { + ObligationCauseCode::FunctionArgumentObligation { + arg_hir_id: receiver.hir_id, + call_hir_id: hir_id, + parent_code, + } + }); + return true; + } for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() .flatten() @@ -251,9 +236,14 @@ 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() + for param in [ + direct_param, + param_to_point_at, + fallback_param_to_point_at, + self_param_to_point_at, + ] + .into_iter() + .flatten() { if self.point_at_path_if_possible(error, def_id, param, qpath) { return true; @@ -485,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /** - * Recursively searches for the most-specific blamable expression. + * Recursively searches for the most-specific blameable expression. * For example, if you have a chain of constraints like: * - want `Vec: Copy` * - because `Option>: Copy` needs `Vec: Copy` because `impl Copy for Option` diff --git a/tests/ui/argument-suggestions/issue-100154.stderr b/tests/ui/argument-suggestions/issue-100154.stderr index 2504f616fb7..966f56e2a15 100644 --- a/tests/ui/argument-suggestions/issue-100154.stderr +++ b/tests/ui/argument-suggestions/issue-100154.stderr @@ -14,12 +14,10 @@ LL | fn foo(i: impl std::fmt::Display) {} = note: `impl Trait` cannot be explicitly specified as a generic argument error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-100154.rs:4:15 + --> $DIR/issue-100154.rs:4:11 | LL | foo::<()>(()); - | --------- ^^ `()` cannot be formatted with the default formatter - | | - | required by a bound introduced by this call + | ^^ `()` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr index 02906e821c5..fc63f4b3e30 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:22 + --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:13 | LL | let u: >::Bar = t.get_bar(); - | ^^^^^ the trait `Foo` is not implemented for `T` + | ^ the trait `Foo` is not implemented for `T` | help: consider further restricting this bound | diff --git a/tests/ui/associated-types/associated-types-issue-20346.stderr b/tests/ui/associated-types/associated-types-issue-20346.stderr index d8b0433d3e8..b1708b96e52 100644 --- a/tests/ui/associated-types/associated-types-issue-20346.stderr +++ b/tests/ui/associated-types/associated-types-issue-20346.stderr @@ -1,11 +1,13 @@ error[E0271]: type mismatch resolving ` as Iterator>::Item == Option` - --> $DIR/associated-types-issue-20346.rs:34:33 + --> $DIR/associated-types-issue-20346.rs:34:36 | LL | fn test_adapter>>(it: I) { | - this type parameter ... LL | is_iterator_of::, _>(&adapter); - | ^ type mismatch resolving ` as Iterator>::Item == Option` + | ------------------------------ ^^^^^^^^ type mismatch resolving ` as Iterator>::Item == Option` + | | + | required by a bound introduced by this call | note: expected this to be `Option` --> $DIR/associated-types-issue-20346.rs:23:17 diff --git a/tests/ui/const-generics/exhaustive-value.stderr b/tests/ui/const-generics/exhaustive-value.stderr index 0828f7896dc..deb65ddba70 100644 --- a/tests/ui/const-generics/exhaustive-value.stderr +++ b/tests/ui/const-generics/exhaustive-value.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/exhaustive-value.rs:262:16 + --> $DIR/exhaustive-value.rs:262:6 | LL | <() as Foo>::test() - | ^ the trait `Foo` is not implemented for `()` + | ^^ the trait `Foo` is not implemented for `()` | = help: the following other types implement trait `Foo`: <() as Foo<0>> diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 8eda71ec09b..9b96e6dd89b 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -2,7 +2,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:7:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; @@ -71,7 +71,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:21:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; @@ -97,7 +97,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:28:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; @@ -123,7 +123,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:37:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; @@ -149,7 +149,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:46:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; @@ -175,7 +175,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:53:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; @@ -201,7 +201,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:62:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ^^^^^^ cannot infer type for reference `&_` | = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl<> From<&String> for String; diff --git a/tests/ui/issues/issue-29147.stderr b/tests/ui/issues/issue-29147.stderr index 138d477dc6b..d0d9485310b 100644 --- a/tests/ui/issues/issue-29147.stderr +++ b/tests/ui/issues/issue-29147.stderr @@ -1,8 +1,8 @@ error[E0283]: type annotations needed - --> $DIR/issue-29147.rs:22:13 + --> $DIR/issue-29147.rs:22:14 | LL | let _ = >::xxx; - | ^^^^^^^^^^^^ cannot infer type for struct `S5<_>` + | ^^^^^ cannot infer type for struct `S5<_>` | note: multiple `impl`s satisfying `S5<_>: Foo` found --> $DIR/issue-29147.rs:18:1 diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr index cec482a53ba..22b1da64cb3 100644 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -17,10 +17,12 @@ note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL 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:39 | LL | let x3 = x1.into_iter().collect::>(); - | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | ------- ^^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr index 7f1b9c38e67..e728fec2910 100644 --- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}` - --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:41 + --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:47 | LL | let x = Some(()).iter().map(|()| 1).sum::(); - | ^^^ value of type `f32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `f32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum<{integer}>` is not implemented for `f32` = help: the following other types implement trait `Sum`: diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index a2688107d10..b355da5cb76 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -17,10 +17,12 @@ note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()` - --> $DIR/invalid-iterator-chain.rs:15:27 + --> $DIR/invalid-iterator-chain.rs:15:33 | LL | println!("{}", scores.sum::()); - | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: @@ -42,10 +44,12 @@ note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()` - --> $DIR/invalid-iterator-chain.rs:26:14 + --> $DIR/invalid-iterator-chain.rs:26:20 | LL | .sum::(), - | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: @@ -74,10 +78,12 @@ note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `f64` - --> $DIR/invalid-iterator-chain.rs:36:14 + --> $DIR/invalid-iterator-chain.rs:36:20 | LL | .sum::(), - | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum` is not implemented for `i32` = help: the following other types implement trait `Sum`: @@ -102,10 +108,12 @@ note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()` - --> $DIR/invalid-iterator-chain.rs:38:54 + --> $DIR/invalid-iterator-chain.rs:38:60 | LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); - | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: @@ -123,10 +131,12 @@ note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()` - --> $DIR/invalid-iterator-chain.rs:39:40 + --> $DIR/invalid-iterator-chain.rs:39:46 | LL | println!("{}", vec![(), ()].iter().sum::()); - | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum<&()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: diff --git a/tests/ui/methods/issues/issue-61525.stderr b/tests/ui/methods/issues/issue-61525.stderr index a8afdeb8401..a329b52e373 100644 --- a/tests/ui/methods/issues/issue-61525.stderr +++ b/tests/ui/methods/issues/issue-61525.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `dyn ToString` cannot be known at compilation time - --> $DIR/issue-61525.rs:14:33 + --> $DIR/issue-61525.rs:14:19 | LL | 1.query::("") - | ----- ^^ 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 | diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr index 06e902bca70..54c16230fe6 100644 --- a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `E: From<()>` is not satisfied - --> $DIR/never-value-fallback-issue-66757.rs:28:26 + --> $DIR/never-value-fallback-issue-66757.rs:28:6 | LL | >::from(never); - | -------------------- ^^^^^ the trait `From<()>` is not implemented for `E` - | | - | required by a bound introduced by this call + | ^ the trait `From<()>` is not implemented for `E` | = help: the trait `From` is implemented for `E` diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr index a2357e49b07..257dec20074 100644 --- a/tests/ui/on-unimplemented/sum.stderr +++ b/tests/ui/on-unimplemented/sum.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()` - --> $DIR/sum.rs:4:25 + --> $DIR/sum.rs:4:31 | LL | vec![(), ()].iter().sum::(); - | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | --- ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Sum<&()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: @@ -19,10 +21,12 @@ note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `i32` cannot be made by multiplying all elements of type `&()` from an iterator - --> $DIR/sum.rs:7:25 + --> $DIR/sum.rs:7:35 | LL | vec![(), ()].iter().product::(); - | ^^^^^^^ value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator` + | ------- ^^^ value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator` + | | + | required by a bound introduced by this call | = help: the trait `Product<&()>` is not implemented for `i32` = help: the following other types implement trait `Product`: diff --git a/tests/ui/suggestions/assoc-const-as-fn.stderr b/tests/ui/suggestions/assoc-const-as-fn.stderr index 3b6e947c59f..d55d968b600 100644 --- a/tests/ui/suggestions/assoc-const-as-fn.stderr +++ b/tests/ui/suggestions/assoc-const-as-fn.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `T: GlUniformScalar` is not satisfied - --> $DIR/assoc-const-as-fn.rs:14:40 + --> $DIR/assoc-const-as-fn.rs:14:6 | LL | ::FACTORY(1, value); - | ------------------------------- ^^^^^ the trait `GlUniformScalar` is not implemented for `T` - | | - | required by a bound introduced by this call + | ^ the trait `GlUniformScalar` is not implemented for `T` | help: consider further restricting this bound | diff --git a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr index 11f94c604a1..fc5a521746a 100644 --- a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr +++ b/tests/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:11 + --> $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/tests/ui/traits/bad-method-typaram-kind.stderr b/tests/ui/traits/bad-method-typaram-kind.stderr index 074284cbdd4..bdcfbe79558 100644 --- a/tests/ui/traits/bad-method-typaram-kind.stderr +++ b/tests/ui/traits/bad-method-typaram-kind.stderr @@ -2,7 +2,9 @@ error[E0277]: `T` cannot be sent between threads safely --> $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 + | | + | required by a bound introduced by this call | = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Bar::bar` diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr index 934d20b2267..263c59ee327 100644 --- a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr +++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr @@ -5,12 +5,10 @@ LL | >::ref_foo(unknown); | ^^^^^^^ not found in this scope error[E0277]: the trait bound `for<'a> &'a mut Vec<&'a u32>: Foo<'static, i32>` is not satisfied - --> $DIR/dont-autoderef-ty-with-escaping-var.rs:17:35 + --> $DIR/dont-autoderef-ty-with-escaping-var.rs:17:6 | LL | >::ref_foo(unknown); - | ----------------------------- ^^^^^^^ the trait `for<'a> Foo<'static, i32>` is not implemented for `&'a mut Vec<&'a u32>` - | | - | required by a bound introduced by this call + | ^^^ the trait `for<'a> Foo<'static, i32>` is not implemented for `&'a mut Vec<&'a u32>` | note: required for `i32` to implement `RefFoo` --> $DIR/dont-autoderef-ty-with-escaping-var.rs:9:9 diff --git a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr index 656e0d0bf26..7027fa69e03 100644 --- a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr +++ b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr @@ -24,12 +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:37 + --> $DIR/repeated-supertrait-ambig.rs:34:6 | LL | ::same_as(c, 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`: > diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index d4fea05fe4b..33cc186ac0b 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -35,23 +35,12 @@ help: consider specifying the generic argument LL | opts.get::(opt.as_ref()); | +++++ -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/issue-77982.rs:13:59 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); - | --------- ^^^^ - | | - | required by a bound introduced by this call + | ^^^^ | - = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate: - - impl From for u32; - - impl From for u32; - - impl From for u32; - - impl From for u32; - - impl From for u32; - - impl From for u32; - - impl From for T; - - impl From for T; 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(); @@ -95,4 +84,5 @@ LL | let _: Box = (&()).bar(); error: aborting due to 5 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/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/new-solver/specialization-unconstrained.stderr index ff0440d51ad..9915da1a27a 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/new-solver/specialization-unconstrained.stderr @@ -15,10 +15,10 @@ LL | default type Id = T; | ^ cannot infer type for associated type `::Id` error[E0284]: type annotations needed: cannot satisfy `::Id == ()` - --> $DIR/specialization-unconstrained.rs:20:12 + --> $DIR/specialization-unconstrained.rs:20:5 | LL | test::(); - | ^^^ cannot satisfy `::Id == ()` + | ^^^^^^^^^^^^^^^ cannot satisfy `::Id == ()` | note: required by a bound in `test` --> $DIR/specialization-unconstrained.rs:17:20 diff --git a/tests/ui/traits/reservation-impl/no-use.next.stderr b/tests/ui/traits/reservation-impl/no-use.next.stderr index 542e3a28adf..632f0f81624 100644 --- a/tests/ui/traits/reservation-impl/no-use.next.stderr +++ b/tests/ui/traits/reservation-impl/no-use.next.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `(): MyTrait` is not satisfied - --> $DIR/no-use.rs:11:26 + --> $DIR/no-use.rs:11:6 | LL | <() as MyTrait>::foo(&()); - | -------------------- ^^^ the trait `MyTrait` is not implemented for `()` - | | - | required by a bound introduced by this call + | ^^ the trait `MyTrait` is not implemented for `()` | = help: the trait `MyTrait` is implemented for `()` diff --git a/tests/ui/traits/reservation-impl/no-use.old.stderr b/tests/ui/traits/reservation-impl/no-use.old.stderr index 542e3a28adf..632f0f81624 100644 --- a/tests/ui/traits/reservation-impl/no-use.old.stderr +++ b/tests/ui/traits/reservation-impl/no-use.old.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `(): MyTrait` is not satisfied - --> $DIR/no-use.rs:11:26 + --> $DIR/no-use.rs:11:6 | LL | <() as MyTrait>::foo(&()); - | -------------------- ^^^ the trait `MyTrait` is not implemented for `()` - | | - | required by a bound introduced by this call + | ^^ the trait `MyTrait` is not implemented for `()` | = help: the trait `MyTrait` is implemented for `()` diff --git a/tests/ui/traits/suggest-where-clause.stderr b/tests/ui/traits/suggest-where-clause.stderr index 5a539884873..e3bbf768c6e 100644 --- a/tests/ui/traits/suggest-where-clause.stderr +++ b/tests/ui/traits/suggest-where-clause.stderr @@ -38,10 +38,10 @@ LL + fn check() { | error[E0277]: the trait bound `u64: From` is not satisfied - --> $DIR/suggest-where-clause.rs:15:18 + --> $DIR/suggest-where-clause.rs:15:6 | LL | >::from; - | ^ the trait `From` is not implemented for `u64` + | ^^^ the trait `From` is not implemented for `u64` | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | @@ -49,10 +49,10 @@ LL | fn check() where u64: From { | ++++++++++++++++++ error[E0277]: the trait bound `u64: From<::Item>` is not satisfied - --> $DIR/suggest-where-clause.rs:18:18 + --> $DIR/suggest-where-clause.rs:18:6 | LL | ::Item>>::from; - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<::Item>` is not implemented for `u64` + | ^^^ the trait `From<::Item>` is not implemented for `u64` | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | @@ -60,10 +60,10 @@ LL | fn check() where u64: From<::Item> { | ++++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `Misc<_>: From` is not satisfied - --> $DIR/suggest-where-clause.rs:23:22 + --> $DIR/suggest-where-clause.rs:23:6 | LL | as From>::from; - | ^ the trait `From` is not implemented for `Misc<_>` + | ^^^^^^^ the trait `From` is not implemented for `Misc<_>` error[E0277]: the size for values of type `[T]` cannot be known at compilation time --> $DIR/suggest-where-clause.rs:28:20 diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 85adf775139..ae0a06e6328 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -1,10 +1,8 @@ error[E0277]: cannot add `u32` to `i32` - --> $DIR/ufcs-qpath-self-mismatch.rs:4:31 + --> $DIR/ufcs-qpath-self-mismatch.rs:4:6 | LL | >::add(1, 2); - | ---------------------- ^ no implementation for `i32 + u32` - | | - | required by a bound introduced by this call + | ^^^ no implementation for `i32 + u32` | = help: the trait `Add` is not implemented for `i32` = help: the following other types implement trait `Add`: From ef11db803cd6aa8aea6ba501fea62f8c6601294c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Aug 2023 19:35:54 +0000 Subject: [PATCH 4/5] Remove unnecessary `select_obligations_where_possible` and redundant errors --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 1 - ...ted-types-invalid-trait-ref-issue-18865.rs | 1 - ...types-invalid-trait-ref-issue-18865.stderr | 13 +---- .../multiple-type-params-with-unmet-bounds.rs | 1 - ...tiple-type-params-with-unmet-bounds.stderr | 14 +---- .../own-bound-span.rs | 4 -- .../own-bound-span.stderr | 16 +----- tests/ui/issues/issue-66353.rs | 1 - tests/ui/issues/issue-66353.stderr | 8 +-- .../assoc_type_bounds_sized_used.rs | 1 - .../assoc_type_bounds_sized_used.stderr | 54 ++++++------------- .../assoc-type-const-bound-usage.stderr | 13 +---- 12 files changed, 22 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 45bf43efa83..823422fab14 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -322,7 +322,6 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { ty.kind() { self.add_required_obligations_for_hir(span, *def_id, args, hir_id); - self.select_obligations_where_possible(|_| {}); } self.normalize(span, ty) } else { diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs index 473a68833b6..3bd3f3a757c 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs @@ -9,7 +9,6 @@ trait Foo { fn f>(t: &T) { let u: >::Bar = t.get_bar(); //~^ ERROR the trait bound `T: Foo` is not satisfied - //~| ERROR the trait bound `T: Foo` is not satisfied } fn main() { } diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr index fc63f4b3e30..676d6353d98 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr @@ -9,17 +9,6 @@ help: consider further restricting this bound LL | fn f + Foo>(t: &T) { | ++++++++++++ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12 - | -LL | let u: >::Bar = t.get_bar(); - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T` - | -help: consider further restricting this bound - | -LL | fn f + Foo>(t: &T) { - | ++++++++++++ - -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/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs index ffb45f4bc75..b127b3f6e1f 100644 --- a/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs +++ b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.rs @@ -7,5 +7,4 @@ impl Trait for () { fn main() { let _: <() as Trait>::P; //~^ ERROR the trait bound `String: Copy` is not satisfied - //~| ERROR the trait bound `String: Copy` is not satisfied } diff --git a/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr index 7f3b75c0629..72a987b4a1d 100644 --- a/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr +++ b/tests/ui/generic-associated-types/multiple-type-params-with-unmet-bounds.stderr @@ -10,18 +10,6 @@ note: required by a bound in `Trait::P` LL | type P; | ^^^^ required by this bound in `Trait::P` -error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/multiple-type-params-with-unmet-bounds.rs:8:12 - | -LL | let _: <() as Trait>::P; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` - | -note: required by a bound in `Trait::P` - --> $DIR/multiple-type-params-with-unmet-bounds.rs:2:15 - | -LL | type P; - | ^^^^ required by this bound in `Trait::P` - -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/tests/ui/generic-associated-types/own-bound-span.rs b/tests/ui/generic-associated-types/own-bound-span.rs index 72d0fd9897f..3699f7296f5 100644 --- a/tests/ui/generic-associated-types/own-bound-span.rs +++ b/tests/ui/generic-associated-types/own-bound-span.rs @@ -4,8 +4,6 @@ trait D { type P; //~^ NOTE required by this bound in `D::P` //~| NOTE required by a bound in `D::P` - //~| NOTE required by this bound in `D::P` - //~| NOTE required by a bound in `D::P` } impl D for S { @@ -16,6 +14,4 @@ fn main() { let _: ::P; //~^ ERROR the trait bound `String: Copy` is not satisfied //~| NOTE the trait `Copy` is not implemented for `String` - //~| ERROR the trait bound `String: Copy` is not satisfied - //~| NOTE the trait `Copy` is not implemented for `String` } diff --git a/tests/ui/generic-associated-types/own-bound-span.stderr b/tests/ui/generic-associated-types/own-bound-span.stderr index 98bf55bc208..4a0566ca7b5 100644 --- a/tests/ui/generic-associated-types/own-bound-span.stderr +++ b/tests/ui/generic-associated-types/own-bound-span.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/own-bound-span.rs:16:24 + --> $DIR/own-bound-span.rs:14:24 | LL | let _: ::P; | ^^^^^^ the trait `Copy` is not implemented for `String` @@ -10,18 +10,6 @@ note: required by a bound in `D::P` LL | type P; | ^^^^ required by this bound in `D::P` -error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/own-bound-span.rs:16:12 - | -LL | let _: ::P; - | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` - | -note: required by a bound in `D::P` - --> $DIR/own-bound-span.rs:4:15 - | -LL | type P; - | ^^^^ required by this bound in `D::P` - -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/tests/ui/issues/issue-66353.rs b/tests/ui/issues/issue-66353.rs index 484a28e564b..d8abdd5206e 100644 --- a/tests/ui/issues/issue-66353.rs +++ b/tests/ui/issues/issue-66353.rs @@ -11,6 +11,5 @@ trait _A { fn main() { _Func::< <() as _A>::AssocT >::func(()); //~^ ERROR the trait bound `(): _A` is not satisfied - //~| ERROR the trait bound `(): _A` is not satisfied //~| ERROR the trait bound `(): _Func<_>` is not satisfied } diff --git a/tests/ui/issues/issue-66353.stderr b/tests/ui/issues/issue-66353.stderr index 49eb013c1d8..71530f58220 100644 --- a/tests/ui/issues/issue-66353.stderr +++ b/tests/ui/issues/issue-66353.stderr @@ -4,12 +4,6 @@ error[E0277]: the trait bound `(): _A` is not satisfied LL | _Func::< <() as _A>::AssocT >::func(()); | ^^ the trait `_A` is not implemented for `()` -error[E0277]: the trait bound `(): _A` is not satisfied - --> $DIR/issue-66353.rs:12:14 - | -LL | _Func::< <() as _A>::AssocT >::func(()); - | ^^^^^^^^^^^^^^^^^^ the trait `_A` is not implemented for `()` - error[E0277]: the trait bound `(): _Func<_>` is not satisfied --> $DIR/issue-66353.rs:12:41 | @@ -18,6 +12,6 @@ LL | _Func::< <() as _A>::AssocT >::func(()); | | | required by a bound introduced by this call -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs index f685a7f626f..cf5345b1c1d 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs +++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs @@ -12,7 +12,6 @@ fn bop() { let _ = ::Bar::default(); //~^ ERROR: trait bounds were not satisfied //~| ERROR: the size for values of type `T` cannot be known at compilation time - //~| ERROR: the size for values of type `T` cannot be known at compilation time } fn main() { diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr index f551d657ab5..6b5bc360349 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr +++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr @@ -1,3 +1,17 @@ +error[E0599]: the function or associated item `default` exists for associated type `::Bar`, but its trait bounds were not satisfied + --> $DIR/assoc_type_bounds_sized_used.rs:12:30 + | +LL | let _ = ::Bar::default(); + | ^^^^^^^ function or associated item cannot be called on `::Bar` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `T: Sized` + which is required by `::Bar: Default` +help: consider restricting the type parameter to satisfy the trait bound + | +LL | fn bop() where T: Sized { + | ++++++++++++++ + error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/assoc_type_bounds_sized_used.rs:12:14 | @@ -20,44 +34,8 @@ LL - fn bop() { LL + fn bop() { | -error[E0599]: the function or associated item `default` exists for associated type `::Bar`, but its trait bounds were not satisfied - --> $DIR/assoc_type_bounds_sized_used.rs:12:30 - | -LL | let _ = ::Bar::default(); - | ^^^^^^^ function or associated item cannot be called on `::Bar` due to unsatisfied trait bounds - | - = note: the following trait bounds were not satisfied: - `T: Sized` - which is required by `::Bar: Default` -help: consider restricting the type parameter to satisfy the trait bound - | -LL | fn bop() where T: Sized { - | ++++++++++++++ - -error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/assoc_type_bounds_sized_used.rs:12:13 - | -LL | fn bop() { - | - this type parameter needs to be `Sized` -LL | let _ = ::Bar::default(); - | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | -note: required by a bound in `Bop::Bar` - --> $DIR/assoc_type_bounds_sized_used.rs:8:15 - | -LL | type Bar: Default - | --- required by a bound in this associated type -LL | where -LL | Self: Sized; - | ^^^^^ required by this bound in `Bop::Bar` -help: consider removing the `?Sized` bound to make the type parameter `Sized` - | -LL - fn bop() { -LL + fn bop() { - | - error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time - --> $DIR/assoc_type_bounds_sized_used.rs:19:11 + --> $DIR/assoc_type_bounds_sized_used.rs:18:11 | LL | bop::(); | ^^^^^^^ doesn't have a size known at compile-time @@ -69,7 +47,7 @@ note: required by a bound in `bop` LL | fn bop() { | ^^^ required by this bound in `bop` -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`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr index 72ff11d586f..ad11c090f12 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr @@ -9,17 +9,6 @@ help: consider further restricting this bound LL | const fn foo() { | +++++ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/assoc-type-const-bound-usage.rs:12:5 - | -LL | ::Assoc::foo(); - | ^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T` - | -help: consider further restricting this bound - | -LL | const fn foo() { - | +++++ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. From 7411e25abe1bb6d32b5f9949950201bcfe6250e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 26 Aug 2023 19:53:11 +0000 Subject: [PATCH 5/5] Account for `Weak` alias kinds when adding more targetted obligation --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 6 ++++-- ...n-crate-has-lazy-type-aliases.locally_eager.stderr | 8 ++++---- ...rn-crate-has-lazy-type-aliases.locally_lazy.stderr | 8 ++++---- tests/ui/lazy-type-alias/trailing-where-clause.stderr | 11 +++++++---- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 823422fab14..7707cc6de54 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -318,8 +318,10 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) { // FIXME: normalization and escaping regions let ty = if !ty.has_escaping_bound_vars() { - if let ty::Alias(ty::AliasKind::Projection, ty::AliasTy { args, def_id, .. }) = - ty.kind() + if let ty::Alias( + ty::AliasKind::Projection | ty::AliasKind::Weak, + ty::AliasTy { args, def_id, .. }, + ) = ty.kind() { self.add_required_obligations_for_hir(span, *def_id, args, hir_id); } diff --git a/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr b/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr index 9e0e2bfa872..3b216ac1581 100644 --- a/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr +++ b/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/extern-crate-has-lazy-type-aliases.rs:15:12 + --> $DIR/extern-crate-has-lazy-type-aliases.rs:15:24 | LL | let _: lazy::Alias; - | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | ^^^^^^ the trait `Copy` is not implemented for `String` | -note: required by a bound on the type alias `Alias` +note: required by a bound in `lazy::Alias` --> $DIR/auxiliary/lazy.rs:4:19 | LL | pub type Alias = Option; - | ^^^^ required by this bound + | ^^^^ required by this bound in `Alias` error: aborting due to previous error diff --git a/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr b/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr index 9e0e2bfa872..3b216ac1581 100644 --- a/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr +++ b/tests/ui/lazy-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/extern-crate-has-lazy-type-aliases.rs:15:12 + --> $DIR/extern-crate-has-lazy-type-aliases.rs:15:24 | LL | let _: lazy::Alias; - | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | ^^^^^^ the trait `Copy` is not implemented for `String` | -note: required by a bound on the type alias `Alias` +note: required by a bound in `lazy::Alias` --> $DIR/auxiliary/lazy.rs:4:19 | LL | pub type Alias = Option; - | ^^^^ required by this bound + | ^^^^ required by this bound in `Alias` error: aborting due to previous error diff --git a/tests/ui/lazy-type-alias/trailing-where-clause.stderr b/tests/ui/lazy-type-alias/trailing-where-clause.stderr index d7606ba6b2a..193f80b23d3 100644 --- a/tests/ui/lazy-type-alias/trailing-where-clause.stderr +++ b/tests/ui/lazy-type-alias/trailing-where-clause.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `String: From<()>` is not satisfied - --> $DIR/trailing-where-clause.rs:12:12 + --> $DIR/trailing-where-clause.rs:12:18 | LL | let _: Alias<()>; - | ^^^^^^^^^ the trait `From<()>` is not implemented for `String` + | ^^ the trait `From<()>` is not implemented for `String` | = help: the following other types implement trait `From`: > @@ -11,11 +11,14 @@ LL | let _: Alias<()>; > > > -note: required by a bound on the type alias `Alias` +note: required by a bound in `Alias` --> $DIR/trailing-where-clause.rs:8:13 | +LL | type Alias = T + | ----- required by a bound in this type alias +LL | where LL | String: From; - | ^^^^^^^ required by this bound + | ^^^^^^^ required by this bound in `Alias` error: aborting due to previous error