From 446b46673d111f5f00e89e7fa208eaf233b6a7a8 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 6 Oct 2021 12:27:42 +0000 Subject: [PATCH] Point at bounds when comparing impl items to trait --- .../rustc_typeck/src/check/compare_method.rs | 30 +++++++++++++------ ...regions-bound-missing-bound-in-impl.stderr | 4 +-- .../proj-outlives-region.stderr | 4 +-- .../ui/compare-method/region-extra-2.stderr | 4 +-- .../ui/compare-method/region-extra.stderr | 4 +-- .../ui/compare-method/region-unrelated.stderr | 4 +-- .../trait-bound-on-type-parameter.stderr | 4 +-- .../traits-misc-mismatch-1.stderr | 28 ++++++++--------- .../traits-misc-mismatch-2.stderr | 4 +-- src/test/ui/error-codes/E0276.stderr | 4 +-- .../impl_bounds.stderr | 4 +-- src/test/ui/impl-trait/issue-55872-1.stderr | 4 +-- src/test/ui/issues/issue-14853.stderr | 4 +-- src/test/ui/issues/issue-18937.rs | 4 +-- src/test/ui/issues/issue-18937.stderr | 10 ++----- 15 files changed, 62 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 89495570375..bcb53b2e437 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -210,12 +210,8 @@ fn compare_predicate_entailment<'tcx>( let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_hir_id); let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing); - let param_env = traits::normalize_param_env_or_error( - tcx, - impl_m.def_id, - param_env, - normalize_cause.clone(), - ); + let param_env = + traits::normalize_param_env_or_error(tcx, impl_m.def_id, param_env, normalize_cause); tcx.infer_ctxt().enter(|infcx| { let inh = Inherited::new(infcx, impl_m.def_id.expect_local()); @@ -226,12 +222,22 @@ fn compare_predicate_entailment<'tcx>( let mut selcx = traits::SelectionContext::new(&infcx); let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); - for predicate in impl_m_own_bounds.predicates { + for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) { + let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id); let traits::Normalized { value: predicate, obligations } = - traits::normalize(&mut selcx, param_env, normalize_cause.clone(), predicate); + traits::normalize(&mut selcx, param_env, normalize_cause, predicate); inh.register_predicates(obligations); - inh.register_predicate(traits::Obligation::new(cause.clone(), param_env, predicate)); + let cause = ObligationCause::new( + span, + impl_m_hir_id, + ObligationCauseCode::CompareImplMethodObligation { + item_name: impl_m.ident.name, + impl_item_def_id: impl_m.def_id, + trait_item_def_id: trait_m.def_id, + }, + ); + inh.register_predicate(traits::Obligation::new(cause, param_env, predicate)); } // We now need to check that the signature of the impl method is @@ -280,6 +286,12 @@ fn compare_predicate_entailment<'tcx>( let sub_result = infcx.at(&cause, param_env).sup(trait_fty, impl_fty).map( |InferOk { obligations, .. }| { + // FIXME: We'd want to keep more accurate spans than "the method signature" when + // processing the comparison between the trait and impl fn, but we sadly lose them + // and point at the whole signature when a trait bound or specific input or output + // type would be more appropriate. In other places we have a `Vec` + // corresponding to their `Vec`, but we don't have that here. + // Fixing this would improve the output of test `issue-83765.rs`. inh.register_predicates(obligations); }, ); diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 536fd43ef75..1e3b071ef92 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -64,13 +64,13 @@ LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { | ^ lifetimes do not match method in trait error[E0276]: impl has stricter requirements than trait - --> $DIR/regions-bound-missing-bound-in-impl.rs:49:5 + --> $DIR/regions-bound-missing-bound-in-impl.rs:49:26 | LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); | ------------------------------------------------------- definition of `another_bound` from trait ... LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't` + | ^^ impl has extra requirement `'x: 't` error: aborting due to 6 previous errors diff --git a/src/test/ui/compare-method/proj-outlives-region.stderr b/src/test/ui/compare-method/proj-outlives-region.stderr index e5f5c5ed20d..797a8167931 100644 --- a/src/test/ui/compare-method/proj-outlives-region.stderr +++ b/src/test/ui/compare-method/proj-outlives-region.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/proj-outlives-region.rs:9:5 + --> $DIR/proj-outlives-region.rs:9:23 | LL | fn foo() where T: 'a; | --------------------- definition of `foo` from trait ... LL | fn foo() where U: 'a { } - | ^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a` + | ^^ impl has extra requirement `U: 'a` error: aborting due to previous error diff --git a/src/test/ui/compare-method/region-extra-2.stderr b/src/test/ui/compare-method/region-extra-2.stderr index 420d99c15ec..f01d7f4710c 100644 --- a/src/test/ui/compare-method/region-extra-2.stderr +++ b/src/test/ui/compare-method/region-extra-2.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/region-extra-2.rs:9:5 + --> $DIR/region-extra-2.rs:9:53 | LL | fn renew<'b: 'a>(self) -> &'b mut [T]; | -------------------------------------- definition of `renew` from trait ... LL | fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b` + | ^^ impl has extra requirement `'a: 'b` error: aborting due to previous error diff --git a/src/test/ui/compare-method/region-extra.stderr b/src/test/ui/compare-method/region-extra.stderr index 5a584c7d6ed..4a3af65e904 100644 --- a/src/test/ui/compare-method/region-extra.stderr +++ b/src/test/ui/compare-method/region-extra.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/region-extra.rs:9:5 + --> $DIR/region-extra.rs:9:24 | LL | fn foo(); | --------- definition of `foo` from trait ... LL | fn foo() where 'a: 'b { } - | ^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b` + | ^^ impl has extra requirement `'a: 'b` error: aborting due to previous error diff --git a/src/test/ui/compare-method/region-unrelated.stderr b/src/test/ui/compare-method/region-unrelated.stderr index fd3576ddcf1..f7ae6f94438 100644 --- a/src/test/ui/compare-method/region-unrelated.stderr +++ b/src/test/ui/compare-method/region-unrelated.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/region-unrelated.rs:9:5 + --> $DIR/region-unrelated.rs:9:23 | LL | fn foo() where T: 'a; | --------------------- definition of `foo` from trait ... LL | fn foo() where V: 'a { } - | ^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `V: 'a` + | ^^ impl has extra requirement `V: 'a` error: aborting due to previous error diff --git a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr index 83a2ae60681..ce6885c1541 100644 --- a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr +++ b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/trait-bound-on-type-parameter.rs:15:5 + --> $DIR/trait-bound-on-type-parameter.rs:15:13 | LL | fn b(&self, x: C) -> C; | ---------------------------- definition of `b` from trait ... LL | fn b(&self, _x: F) -> F { panic!() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `F: Sync` + | ^^^^ impl has extra requirement `F: Sync` error: aborting due to previous error diff --git a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr index da94fc65841..805c04536ca 100644 --- a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr +++ b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr @@ -1,65 +1,65 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:27:5 + --> $DIR/traits-misc-mismatch-1.rs:27:26 | LL | fn test_error1_fn(&self); | -------------------------------- definition of `test_error1_fn` from trait ... LL | fn test_error1_fn(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Ord` + | ^^^ impl has extra requirement `T: Ord` error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:31:5 + --> $DIR/traits-misc-mismatch-1.rs:31:31 | LL | fn test_error2_fn(&self); | -------------------------------------- definition of `test_error2_fn` from trait ... LL | fn test_error2_fn(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: B` + | ^ impl has extra requirement `T: B` error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:35:5 + --> $DIR/traits-misc-mismatch-1.rs:35:26 | LL | fn test_error3_fn(&self); | -------------------------------------- definition of `test_error3_fn` from trait ... LL | fn test_error3_fn(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: B` + | ^ impl has extra requirement `T: B` error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:45:5 + --> $DIR/traits-misc-mismatch-1.rs:45:26 | LL | fn test_error5_fn(&self); | ------------------------------- definition of `test_error5_fn` from trait ... LL | fn test_error5_fn(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: B` + | ^ impl has extra requirement `T: B` error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:51:5 + --> $DIR/traits-misc-mismatch-1.rs:51:30 | LL | fn test_error7_fn(&self); | ------------------------------- definition of `test_error7_fn` from trait ... LL | fn test_error7_fn(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Eq` + | ^^ impl has extra requirement `T: Eq` error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:54:5 + --> $DIR/traits-misc-mismatch-1.rs:54:26 | LL | fn test_error8_fn(&self); | ------------------------------- definition of `test_error8_fn` from trait ... LL | fn test_error8_fn(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: C` + | ^ impl has extra requirement `T: C` error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-1.rs:67:5 + --> $DIR/traits-misc-mismatch-1.rs:67:18 | LL | fn method>(&self); | ---------------------------------- definition of `method` from trait ... LL | fn method>(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `G: Getter` + | ^^^^^^^^^^^^^ impl has extra requirement `G: Getter` error: aborting due to 7 previous errors diff --git a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr index acf94ad32b1..36bb764d40e 100644 --- a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr +++ b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/traits-misc-mismatch-2.rs:13:5 + --> $DIR/traits-misc-mismatch-2.rs:13:18 | LL | fn zip>(self, other: U) -> ZipIterator; | ------------------------------------------------------------------ definition of `zip` from trait ... LL | fn zip>(self, other: U) -> ZipIterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: Iterator` + | ^^^^^^^^^^^ impl has extra requirement `U: Iterator` error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0276.stderr b/src/test/ui/error-codes/E0276.stderr index 8857e1646ee..1013f041bbe 100644 --- a/src/test/ui/error-codes/E0276.stderr +++ b/src/test/ui/error-codes/E0276.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/E0276.rs:6:5 + --> $DIR/E0276.rs:6:30 | LL | fn foo(x: T); | ---------------- definition of `foo` from trait ... LL | fn foo(x: T) where T: Copy {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Copy` + | ^^^^ impl has extra requirement `T: Copy` error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr index f47b5f81e25..1c8a1f09af5 100644 --- a/src/test/ui/generic-associated-types/impl_bounds.stderr +++ b/src/test/ui/generic-associated-types/impl_bounds.stderr @@ -59,10 +59,10 @@ LL | impl Foo for Fooy { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/impl_bounds.rs:22:5 + --> $DIR/impl_bounds.rs:22:24 | LL | fn d() where Self: Copy {} - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` + | ^^^^ the trait `Copy` is not implemented for `T` | note: required because of the requirements on the impl of `Copy` for `Fooy` --> $DIR/impl_bounds.rs:11:10 diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr index e772445a56c..2d1142fd0c5 100644 --- a/src/test/ui/impl-trait/issue-55872-1.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-55872-1.rs:12:5 + --> $DIR/issue-55872-1.rs:12:15 | LL | fn foo() -> Self::E; | ----------------------- definition of `foo` from trait ... LL | fn foo() -> Self::E { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Default` + | ^^^^^^^ impl has extra requirement `T: Default` error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)` --> $DIR/issue-55872-1.rs:12:29 diff --git a/src/test/ui/issues/issue-14853.stderr b/src/test/ui/issues/issue-14853.stderr index 6fc10550492..2adcf55eca9 100644 --- a/src/test/ui/issues/issue-14853.stderr +++ b/src/test/ui/issues/issue-14853.stderr @@ -1,11 +1,11 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-14853.rs:12:5 + --> $DIR/issue-14853.rs:12:15 | LL | fn yay(_: Option, thing: &[T]); | ----------------------------------------------- definition of `yay` from trait ... LL | fn yay(_:Option, thing: &[T]) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Str` + | ^^^ impl has extra requirement `T: Str` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18937.rs b/src/test/ui/issues/issue-18937.rs index ab4c9c736d8..af85e5b2b02 100644 --- a/src/test/ui/issues/issue-18937.rs +++ b/src/test/ui/issues/issue-18937.rs @@ -16,8 +16,8 @@ trait A<'a> { } impl<'a> A<'a> for B { - fn foo(&mut self, f: F) //~ ERROR impl has stricter - where F: fmt::Debug + 'static, + fn foo(&mut self, f: F) + where F: fmt::Debug + 'static, //~ ERROR impl has stricter { self.list.push(Box::new(f)); } diff --git a/src/test/ui/issues/issue-18937.stderr b/src/test/ui/issues/issue-18937.stderr index ac302caecc3..5e2ba0ef4fc 100644 --- a/src/test/ui/issues/issue-18937.stderr +++ b/src/test/ui/issues/issue-18937.stderr @@ -1,17 +1,13 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-18937.rs:19:5 + --> $DIR/issue-18937.rs:20:31 | LL | / fn foo(&mut self, f: F) LL | | where F: fmt::Debug + 'a, LL | | Self: Sized; | |__________________________- definition of `foo` from trait ... -LL | / fn foo(&mut self, f: F) -LL | | where F: fmt::Debug + 'static, -LL | | { -LL | | self.list.push(Box::new(f)); -LL | | } - | |_____^ impl has extra requirement `F: 'static` +LL | where F: fmt::Debug + 'static, + | ^^^^^^^ impl has extra requirement `F: 'static` error: aborting due to previous error