Point at bounds when comparing impl items to trait

This commit is contained in:
Esteban Kuber 2021-10-06 12:27:42 +00:00
parent d8a3d7d0b8
commit 446b46673d
15 changed files with 62 additions and 54 deletions

View File

@ -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<Span>`
// corresponding to their `Vec<Predicate>`, but we don't have that here.
// Fixing this would improve the output of test `issue-83765.rs`.
inh.register_predicates(obligations);
},
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<C,D>(&self, x: C) -> C;
| ---------------------------- definition of `b` from trait
...
LL | fn b<F: Sync, G>(&self, _x: F) -> F { panic!() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `F: Sync`
| ^^^^ impl has extra requirement `F: Sync`
error: aborting due to previous error

View File

@ -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<T: Eq>(&self);
| -------------------------------- definition of `test_error1_fn` from trait
...
LL | fn test_error1_fn<T: Ord>(&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<T: Eq + Ord>(&self);
| -------------------------------------- definition of `test_error2_fn` from trait
...
LL | fn test_error2_fn<T: Eq + B>(&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<T: Eq + Ord>(&self);
| -------------------------------------- definition of `test_error3_fn` from trait
...
LL | fn test_error3_fn<T: B + Eq>(&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<T: A>(&self);
| ------------------------------- definition of `test_error5_fn` from trait
...
LL | fn test_error5_fn<T: B>(&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<T: A>(&self);
| ------------------------------- definition of `test_error7_fn` from trait
...
LL | fn test_error7_fn<T: A + Eq>(&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<T: B>(&self);
| ------------------------------- definition of `test_error8_fn` from trait
...
LL | fn test_error8_fn<T: C>(&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<G:Getter<isize>>(&self);
| ---------------------------------- definition of `method` from trait
...
LL | fn method<G: Getter<usize>>(&self) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
| ^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
error: aborting due to 7 previous errors

View File

@ -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<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>;
| ------------------------------------------------------------------ definition of `zip` from trait
...
LL | fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: Iterator<B>`
| ^^^^^^^^^^^ impl has extra requirement `U: Iterator<B>`
error: aborting due to previous error

View File

@ -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<T>(x: T);
| ---------------- definition of `foo` from trait
...
LL | fn foo<T>(x: T) where T: Copy {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Copy`
| ^^^^ impl has extra requirement `T: Copy`
error: aborting due to previous error

View File

@ -59,10 +59,10 @@ LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
| +++++++++++++++++++
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<T>`
--> $DIR/impl_bounds.rs:11:10

View File

@ -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<T>() -> Self::E;
| ----------------------- definition of `foo` from trait
...
LL | fn foo<T: Default>() -> 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

View File

@ -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<T: Debug>(_: Option<Self>, thing: &[T]);
| ----------------------------------------------- definition of `yay` from trait
...
LL | fn yay<T: Str>(_:Option<X>, thing: &[T]) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Str`
| ^^^ impl has extra requirement `T: Str`
error: aborting due to previous error

View File

@ -16,8 +16,8 @@ trait A<'a> {
}
impl<'a> A<'a> for B {
fn foo<F>(&mut self, f: F) //~ ERROR impl has stricter
where F: fmt::Debug + 'static,
fn foo<F>(&mut self, f: F)
where F: fmt::Debug + 'static, //~ ERROR impl has stricter
{
self.list.push(Box::new(f));
}

View File

@ -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<F>(&mut self, f: F)
LL | | where F: fmt::Debug + 'a,
LL | | Self: Sized;
| |__________________________- definition of `foo` from trait
...
LL | / fn foo<F>(&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