Skip to content

Commit 446b466

Browse files
committed
Point at bounds when comparing impl items to trait
1 parent d8a3d7d commit 446b466

15 files changed

+62
-54
lines changed

compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,8 @@ fn compare_predicate_entailment<'tcx>(
210210
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_hir_id);
211211
let param_env =
212212
ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing);
213-
let param_env = traits::normalize_param_env_or_error(
214-
tcx,
215-
impl_m.def_id,
216-
param_env,
217-
normalize_cause.clone(),
218-
);
213+
let param_env =
214+
traits::normalize_param_env_or_error(tcx, impl_m.def_id, param_env, normalize_cause);
219215

220216
tcx.infer_ctxt().enter(|infcx| {
221217
let inh = Inherited::new(infcx, impl_m.def_id.expect_local());
@@ -226,12 +222,22 @@ fn compare_predicate_entailment<'tcx>(
226222
let mut selcx = traits::SelectionContext::new(&infcx);
227223

228224
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
229-
for predicate in impl_m_own_bounds.predicates {
225+
for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) {
226+
let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id);
230227
let traits::Normalized { value: predicate, obligations } =
231-
traits::normalize(&mut selcx, param_env, normalize_cause.clone(), predicate);
228+
traits::normalize(&mut selcx, param_env, normalize_cause, predicate);
232229

233230
inh.register_predicates(obligations);
234-
inh.register_predicate(traits::Obligation::new(cause.clone(), param_env, predicate));
231+
let cause = ObligationCause::new(
232+
span,
233+
impl_m_hir_id,
234+
ObligationCauseCode::CompareImplMethodObligation {
235+
item_name: impl_m.ident.name,
236+
impl_item_def_id: impl_m.def_id,
237+
trait_item_def_id: trait_m.def_id,
238+
},
239+
);
240+
inh.register_predicate(traits::Obligation::new(cause, param_env, predicate));
235241
}
236242

237243
// We now need to check that the signature of the impl method is
@@ -280,6 +286,12 @@ fn compare_predicate_entailment<'tcx>(
280286

281287
let sub_result = infcx.at(&cause, param_env).sup(trait_fty, impl_fty).map(
282288
|InferOk { obligations, .. }| {
289+
// FIXME: We'd want to keep more accurate spans than "the method signature" when
290+
// processing the comparison between the trait and impl fn, but we sadly lose them
291+
// and point at the whole signature when a trait bound or specific input or output
292+
// type would be more appropriate. In other places we have a `Vec<Span>`
293+
// corresponding to their `Vec<Predicate>`, but we don't have that here.
294+
// Fixing this would improve the output of test `issue-83765.rs`.
283295
inh.register_predicates(obligations);
284296
},
285297
);

src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
6464
| ^ lifetimes do not match method in trait
6565

6666
error[E0276]: impl has stricter requirements than trait
67-
--> $DIR/regions-bound-missing-bound-in-impl.rs:49:5
67+
--> $DIR/regions-bound-missing-bound-in-impl.rs:49:26
6868
|
6969
LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
7070
| ------------------------------------------------------- definition of `another_bound` from trait
7171
...
7272
LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
73-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't`
73+
| ^^ impl has extra requirement `'x: 't`
7474

7575
error: aborting due to 6 previous errors
7676

src/test/ui/compare-method/proj-outlives-region.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/proj-outlives-region.rs:9:5
2+
--> $DIR/proj-outlives-region.rs:9:23
33
|
44
LL | fn foo() where T: 'a;
55
| --------------------- definition of `foo` from trait
66
...
77
LL | fn foo() where U: 'a { }
8-
| ^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a`
8+
| ^^ impl has extra requirement `U: 'a`
99

1010
error: aborting due to previous error
1111

src/test/ui/compare-method/region-extra-2.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/region-extra-2.rs:9:5
2+
--> $DIR/region-extra-2.rs:9:53
33
|
44
LL | fn renew<'b: 'a>(self) -> &'b mut [T];
55
| -------------------------------------- definition of `renew` from trait
66
...
77
LL | fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
8+
| ^^ impl has extra requirement `'a: 'b`
99

1010
error: aborting due to previous error
1111

src/test/ui/compare-method/region-extra.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/region-extra.rs:9:5
2+
--> $DIR/region-extra.rs:9:24
33
|
44
LL | fn foo();
55
| --------- definition of `foo` from trait
66
...
77
LL | fn foo() where 'a: 'b { }
8-
| ^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
8+
| ^^ impl has extra requirement `'a: 'b`
99

1010
error: aborting due to previous error
1111

src/test/ui/compare-method/region-unrelated.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/region-unrelated.rs:9:5
2+
--> $DIR/region-unrelated.rs:9:23
33
|
44
LL | fn foo() where T: 'a;
55
| --------------------- definition of `foo` from trait
66
...
77
LL | fn foo() where V: 'a { }
8-
| ^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `V: 'a`
8+
| ^^ impl has extra requirement `V: 'a`
99

1010
error: aborting due to previous error
1111

src/test/ui/compare-method/trait-bound-on-type-parameter.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/trait-bound-on-type-parameter.rs:15:5
2+
--> $DIR/trait-bound-on-type-parameter.rs:15:13
33
|
44
LL | fn b<C,D>(&self, x: C) -> C;
55
| ---------------------------- definition of `b` from trait
66
...
77
LL | fn b<F: Sync, G>(&self, _x: F) -> F { panic!() }
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `F: Sync`
8+
| ^^^^ impl has extra requirement `F: Sync`
99

1010
error: aborting due to previous error
1111

src/test/ui/compare-method/traits-misc-mismatch-1.stderr

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,65 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/traits-misc-mismatch-1.rs:27:5
2+
--> $DIR/traits-misc-mismatch-1.rs:27:26
33
|
44
LL | fn test_error1_fn<T: Eq>(&self);
55
| -------------------------------- definition of `test_error1_fn` from trait
66
...
77
LL | fn test_error1_fn<T: Ord>(&self) {}
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Ord`
8+
| ^^^ impl has extra requirement `T: Ord`
99

1010
error[E0276]: impl has stricter requirements than trait
11-
--> $DIR/traits-misc-mismatch-1.rs:31:5
11+
--> $DIR/traits-misc-mismatch-1.rs:31:31
1212
|
1313
LL | fn test_error2_fn<T: Eq + Ord>(&self);
1414
| -------------------------------------- definition of `test_error2_fn` from trait
1515
...
1616
LL | fn test_error2_fn<T: Eq + B>(&self) {}
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: B`
17+
| ^ impl has extra requirement `T: B`
1818

1919
error[E0276]: impl has stricter requirements than trait
20-
--> $DIR/traits-misc-mismatch-1.rs:35:5
20+
--> $DIR/traits-misc-mismatch-1.rs:35:26
2121
|
2222
LL | fn test_error3_fn<T: Eq + Ord>(&self);
2323
| -------------------------------------- definition of `test_error3_fn` from trait
2424
...
2525
LL | fn test_error3_fn<T: B + Eq>(&self) {}
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: B`
26+
| ^ impl has extra requirement `T: B`
2727

2828
error[E0276]: impl has stricter requirements than trait
29-
--> $DIR/traits-misc-mismatch-1.rs:45:5
29+
--> $DIR/traits-misc-mismatch-1.rs:45:26
3030
|
3131
LL | fn test_error5_fn<T: A>(&self);
3232
| ------------------------------- definition of `test_error5_fn` from trait
3333
...
3434
LL | fn test_error5_fn<T: B>(&self) {}
35-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: B`
35+
| ^ impl has extra requirement `T: B`
3636

3737
error[E0276]: impl has stricter requirements than trait
38-
--> $DIR/traits-misc-mismatch-1.rs:51:5
38+
--> $DIR/traits-misc-mismatch-1.rs:51:30
3939
|
4040
LL | fn test_error7_fn<T: A>(&self);
4141
| ------------------------------- definition of `test_error7_fn` from trait
4242
...
4343
LL | fn test_error7_fn<T: A + Eq>(&self) {}
44-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Eq`
44+
| ^^ impl has extra requirement `T: Eq`
4545

4646
error[E0276]: impl has stricter requirements than trait
47-
--> $DIR/traits-misc-mismatch-1.rs:54:5
47+
--> $DIR/traits-misc-mismatch-1.rs:54:26
4848
|
4949
LL | fn test_error8_fn<T: B>(&self);
5050
| ------------------------------- definition of `test_error8_fn` from trait
5151
...
5252
LL | fn test_error8_fn<T: C>(&self) {}
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: C`
53+
| ^ impl has extra requirement `T: C`
5454

5555
error[E0276]: impl has stricter requirements than trait
56-
--> $DIR/traits-misc-mismatch-1.rs:67:5
56+
--> $DIR/traits-misc-mismatch-1.rs:67:18
5757
|
5858
LL | fn method<G:Getter<isize>>(&self);
5959
| ---------------------------------- definition of `method` from trait
6060
...
6161
LL | fn method<G: Getter<usize>>(&self) {}
62-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
62+
| ^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
6363

6464
error: aborting due to 7 previous errors
6565

src/test/ui/compare-method/traits-misc-mismatch-2.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/traits-misc-mismatch-2.rs:13:5
2+
--> $DIR/traits-misc-mismatch-2.rs:13:18
33
|
44
LL | fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>;
55
| ------------------------------------------------------------------ definition of `zip` from trait
66
...
77
LL | fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: Iterator<B>`
8+
| ^^^^^^^^^^^ impl has extra requirement `U: Iterator<B>`
99

1010
error: aborting due to previous error
1111

src/test/ui/error-codes/E0276.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/E0276.rs:6:5
2+
--> $DIR/E0276.rs:6:30
33
|
44
LL | fn foo<T>(x: T);
55
| ---------------- definition of `foo` from trait
66
...
77
LL | fn foo<T>(x: T) where T: Copy {}
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Copy`
8+
| ^^^^ impl has extra requirement `T: Copy`
99

1010
error: aborting due to previous error
1111

src/test/ui/generic-associated-types/impl_bounds.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
5959
| +++++++++++++++++++
6060

6161
error[E0277]: the trait bound `T: Copy` is not satisfied
62-
--> $DIR/impl_bounds.rs:22:5
62+
--> $DIR/impl_bounds.rs:22:24
6363
|
6464
LL | fn d() where Self: Copy {}
65-
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
65+
| ^^^^ the trait `Copy` is not implemented for `T`
6666
|
6767
note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
6868
--> $DIR/impl_bounds.rs:11:10

src/test/ui/impl-trait/issue-55872-1.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/issue-55872-1.rs:12:5
2+
--> $DIR/issue-55872-1.rs:12:15
33
|
44
LL | fn foo<T>() -> Self::E;
55
| ----------------------- definition of `foo` from trait
66
...
77
LL | fn foo<T: Default>() -> Self::E {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Default`
8+
| ^^^^^^^ impl has extra requirement `T: Default`
99

1010
error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)`
1111
--> $DIR/issue-55872-1.rs:12:29

src/test/ui/issues/issue-14853.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/issue-14853.rs:12:5
2+
--> $DIR/issue-14853.rs:12:15
33
|
44
LL | fn yay<T: Debug>(_: Option<Self>, thing: &[T]);
55
| ----------------------------------------------- definition of `yay` from trait
66
...
77
LL | fn yay<T: Str>(_:Option<X>, thing: &[T]) {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Str`
8+
| ^^^ impl has extra requirement `T: Str`
99

1010
error: aborting due to previous error
1111

src/test/ui/issues/issue-18937.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ trait A<'a> {
1616
}
1717

1818
impl<'a> A<'a> for B {
19-
fn foo<F>(&mut self, f: F) //~ ERROR impl has stricter
20-
where F: fmt::Debug + 'static,
19+
fn foo<F>(&mut self, f: F)
20+
where F: fmt::Debug + 'static, //~ ERROR impl has stricter
2121
{
2222
self.list.push(Box::new(f));
2323
}

src/test/ui/issues/issue-18937.stderr

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
error[E0276]: impl has stricter requirements than trait
2-
--> $DIR/issue-18937.rs:19:5
2+
--> $DIR/issue-18937.rs:20:31
33
|
44
LL | / fn foo<F>(&mut self, f: F)
55
LL | | where F: fmt::Debug + 'a,
66
LL | | Self: Sized;
77
| |__________________________- definition of `foo` from trait
88
...
9-
LL | / fn foo<F>(&mut self, f: F)
10-
LL | | where F: fmt::Debug + 'static,
11-
LL | | {
12-
LL | | self.list.push(Box::new(f));
13-
LL | | }
14-
| |_____^ impl has extra requirement `F: 'static`
9+
LL | where F: fmt::Debug + 'static,
10+
| ^^^^^^^ impl has extra requirement `F: 'static`
1511

1612
error: aborting due to previous error
1713

0 commit comments

Comments
 (0)