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] 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