Skip to content

Commit 6afd161

Browse files
Rollup merge of #106131 - compiler-errors:not-ptrs, r=davidtwco
Mention "signature" rather than "fn pointer" when impl/trait methods are incompatible Fixes #80929 Fixes #67296
2 parents db87e27 + 49f849a commit 6afd161

39 files changed

+169
-142
lines changed

compiler/rustc_error_messages/locales/en-US/infer.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,8 @@ infer_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not ge
253253
infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signature
254254
.found = found `{$found}`
255255
.expected = expected `{$expected}`
256-
.expected_found = expected `{$expected}`
257-
{" "}found `{$found}`
256+
.expected_found = expected signature `{$expected}`
257+
{" "}found signature `{$found}`
258258
259259
infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
260260
infer_tid_consider_borrowing = consider borrowing this type parameter in the trait

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+14-22
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ fn compare_method_predicate_entailment<'tcx>(
270270
let unnormalized_impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig));
271271

272272
let norm_cause = ObligationCause::misc(impl_m_span, impl_m_hir_id);
273-
let impl_fty = ocx.normalize(&norm_cause, param_env, unnormalized_impl_fty);
274-
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
273+
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
274+
debug!("compare_impl_method: impl_fty={:?}", impl_sig);
275275

276276
let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
277277
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
@@ -294,18 +294,17 @@ fn compare_method_predicate_entailment<'tcx>(
294294
// type would be more appropriate. In other places we have a `Vec<Span>`
295295
// corresponding to their `Vec<Predicate>`, but we don't have that here.
296296
// Fixing this would improve the output of test `issue-83765.rs`.
297-
let result = ocx.sup(&cause, param_env, trait_fty, impl_fty);
297+
let result = ocx.sup(&cause, param_env, trait_sig, impl_sig);
298298

299299
if let Err(terr) = result {
300-
debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
300+
debug!(?impl_sig, ?trait_sig, ?terr, "sub_types failed");
301301

302302
let emitted = report_trait_method_mismatch(
303303
&infcx,
304304
cause,
305305
terr,
306-
(trait_m, trait_fty),
307-
(impl_m, impl_fty),
308-
trait_sig,
306+
(trait_m, trait_sig),
307+
(impl_m, impl_sig),
309308
impl_trait_ref,
310309
);
311310
return Err(emitted);
@@ -484,7 +483,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
484483
let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
485484
let param_env = tcx.param_env(def_id);
486485

487-
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
486+
// First, check a few of the same things as `compare_impl_method`,
487+
// just so we don't ICE during substitution later.
488488
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
489489
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
490490
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
@@ -577,14 +577,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
577577

578578
debug!(?trait_sig, ?impl_sig, "equating function signatures");
579579

580-
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
581-
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
582-
583580
// Unify the whole function signature. We need to do this to fully infer
584581
// the lifetimes of the return type, but do this after unifying just the
585582
// return types, since we want to avoid duplicating errors from
586583
// `compare_method_predicate_entailment`.
587-
match ocx.eq(&cause, param_env, trait_fty, impl_fty) {
584+
match ocx.eq(&cause, param_env, trait_sig, impl_sig) {
588585
Ok(()) => {}
589586
Err(terr) => {
590587
// This function gets called during `compare_method_predicate_entailment` when normalizing a
@@ -595,9 +592,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
595592
infcx,
596593
cause,
597594
terr,
598-
(trait_m, trait_fty),
599-
(impl_m, impl_fty),
600-
trait_sig,
595+
(trait_m, trait_sig),
596+
(impl_m, impl_sig),
601597
impl_trait_ref,
602598
);
603599
return Err(emitted);
@@ -771,9 +767,8 @@ fn report_trait_method_mismatch<'tcx>(
771767
infcx: &InferCtxt<'tcx>,
772768
mut cause: ObligationCause<'tcx>,
773769
terr: TypeError<'tcx>,
774-
(trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>),
775-
(impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>),
776-
trait_sig: ty::FnSig<'tcx>,
770+
(trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
771+
(impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
777772
impl_trait_ref: ty::TraitRef<'tcx>,
778773
) -> ErrorGuaranteed {
779774
let tcx = infcx.tcx;
@@ -858,10 +853,7 @@ fn report_trait_method_mismatch<'tcx>(
858853
&mut diag,
859854
&cause,
860855
trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
861-
Some(infer::ValuePairs::Terms(ExpectedFound {
862-
expected: trait_fty.into(),
863-
found: impl_fty.into(),
864-
})),
856+
Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })),
865857
terr,
866858
false,
867859
false,

compiler/rustc_infer/src/infer/at.rs

+12
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,15 @@ impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
427427
}
428428
}
429429
}
430+
431+
impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
432+
fn to_trace(
433+
_: TyCtxt<'tcx>,
434+
cause: &ObligationCause<'tcx>,
435+
a_is_expected: bool,
436+
a: Self,
437+
b: Self,
438+
) -> TypeTrace<'tcx> {
439+
TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) }
440+
}
441+
}

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -1428,8 +1428,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14281428
impl<'tcx> OpaqueTypesVisitor<'tcx> {
14291429
fn visit_expected_found(
14301430
tcx: TyCtxt<'tcx>,
1431-
expected: Ty<'tcx>,
1432-
found: Ty<'tcx>,
1431+
expected: impl TypeVisitable<'tcx>,
1432+
found: impl TypeVisitable<'tcx>,
14331433
ignore_span: Span,
14341434
) -> Self {
14351435
let mut types_visitor = OpaqueTypesVisitor {
@@ -1569,6 +1569,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
15691569
_ => (false, Mismatch::Fixed("type")),
15701570
}
15711571
}
1572+
ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => {
1573+
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
1574+
.report(diag);
1575+
(false, Mismatch::Fixed("signature"))
1576+
}
15721577
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
15731578
(false, Mismatch::Fixed("trait"))
15741579
}
@@ -2040,6 +2045,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20402045
ret => ret,
20412046
}
20422047
}
2048+
infer::Sigs(exp_found) => {
2049+
let exp_found = self.resolve_vars_if_possible(exp_found);
2050+
if exp_found.references_error() {
2051+
return None;
2052+
}
2053+
let (exp, fnd) = self.cmp_fn_sig(
2054+
&ty::Binder::dummy(exp_found.expected),
2055+
&ty::Binder::dummy(exp_found.found),
2056+
);
2057+
Some((exp, fnd, None, None))
2058+
}
20432059
}
20442060
}
20452061

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff};
44
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
55
use crate::infer::lexical_region_resolve::RegionResolutionError;
6-
use crate::infer::Subtype;
6+
use crate::infer::{Subtype, ValuePairs};
77
use crate::traits::ObligationCauseCode::CompareImplItemObligation;
88
use rustc_errors::ErrorGuaranteed;
99
use rustc_hir as hir;
1010
use rustc_hir::def::Res;
1111
use rustc_hir::def_id::DefId;
1212
use rustc_hir::intravisit::Visitor;
1313
use rustc_middle::hir::nested_filter;
14+
use rustc_middle::ty::error::ExpectedFound;
1415
use rustc_middle::ty::print::RegionHighlightMode;
1516
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
1617
use rustc_span::Span;
@@ -23,22 +24,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
2324
let error = self.error.as_ref()?;
2425
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
2526
if let RegionResolutionError::SubSupConflict(
26-
_,
27-
var_origin,
28-
sub_origin,
29-
_sub,
30-
sup_origin,
31-
_sup,
32-
_,
33-
) = error.clone()
27+
_,
28+
var_origin,
29+
sub_origin,
30+
_sub,
31+
sup_origin,
32+
_sup,
33+
_,
34+
) = error.clone()
3435
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
35-
&& let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty()
36-
&& let sup_expected_found @ Some(_) = sup_trace.values.ty()
3736
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
38-
&& sup_expected_found == sub_expected_found
37+
&& sub_trace.values == sup_trace.values
38+
&& let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values
3939
{
40-
let guar =
41-
self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id);
40+
// FIXME(compiler-errors): Don't like that this needs `Ty`s, but
41+
// all of the region highlighting machinery only deals with those.
42+
let guar = self.emit_err(
43+
var_origin.span(),
44+
self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(expected)),
45+
self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(found)),
46+
*trait_item_def_id,
47+
);
4248
return Some(guar);
4349
}
4450
None

compiler/rustc_infer/src/infer/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ pub enum ValuePairs<'tcx> {
361361
Terms(ExpectedFound<ty::Term<'tcx>>),
362362
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
363363
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
364+
Sigs(ExpectedFound<ty::FnSig<'tcx>>),
364365
}
365366

366367
impl<'tcx> ValuePairs<'tcx> {

src/test/ui/associated-types/defaults-specialization.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ note: type in trait
2222
|
2323
LL | fn make() -> Self::Ty {
2424
| ^^^^^^^^
25-
= note: expected fn pointer `fn() -> <A<T> as Tr>::Ty`
26-
found fn pointer `fn() -> u8`
25+
= note: expected signature `fn() -> <A<T> as Tr>::Ty`
26+
found signature `fn() -> u8`
2727

2828
error[E0053]: method `make` has an incompatible type for trait
2929
--> $DIR/defaults-specialization.rs:35:18
@@ -42,8 +42,8 @@ note: type in trait
4242
|
4343
LL | fn make() -> Self::Ty {
4444
| ^^^^^^^^
45-
= note: expected fn pointer `fn() -> <B<T> as Tr>::Ty`
46-
found fn pointer `fn() -> bool`
45+
= note: expected signature `fn() -> <B<T> as Tr>::Ty`
46+
found signature `fn() -> bool`
4747

4848
error[E0308]: mismatched types
4949
--> $DIR/defaults-specialization.rs:10:9

src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ note: type in trait
99
|
1010
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
= note: expected fn pointer `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
13-
found fn pointer `fn(&i32) -> impl Future<Output = i32>`
12+
= note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
13+
found signature `fn(&i32) -> impl Future<Output = i32>`
1414

1515
error: aborting due to previous error
1616

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ error[E0308]: method not compatible with trait
2222
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
2424
|
25-
= note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
26-
found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
25+
= note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
26+
found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
2727
note: the lifetime `'c` as defined here...
2828
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
2929
|
@@ -41,8 +41,8 @@ error[E0308]: method not compatible with trait
4141
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
4242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
4343
|
44-
= note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
45-
found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
44+
= note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
45+
found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
4646
note: the lifetime `'c` as defined here...
4747
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
4848
|

src/test/ui/compare-method/bad-self-type.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> {
77
| expected struct `Pin`, found struct `MyFuture`
88
| help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>`
99
|
10-
= note: expected fn pointer `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
11-
found fn pointer `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
10+
= note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
11+
found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
1212

1313
error[E0053]: method `foo` has an incompatible type for trait
1414
--> $DIR/bad-self-type.rs:22:18
@@ -24,8 +24,8 @@ note: type in trait
2424
|
2525
LL | fn foo(self);
2626
| ^^^^
27-
= note: expected fn pointer `fn(MyFuture)`
28-
found fn pointer `fn(Box<MyFuture>)`
27+
= note: expected signature `fn(MyFuture)`
28+
found signature `fn(Box<MyFuture>)`
2929

3030
error[E0053]: method `bar` has an incompatible type for trait
3131
--> $DIR/bad-self-type.rs:24:18
@@ -38,8 +38,8 @@ note: type in trait
3838
|
3939
LL | fn bar(self) -> Option<()>;
4040
| ^^^^^^^^^^
41-
= note: expected fn pointer `fn(MyFuture) -> Option<()>`
42-
found fn pointer `fn(MyFuture)`
41+
= note: expected signature `fn(MyFuture) -> Option<()>`
42+
found signature `fn(MyFuture)`
4343
help: change the output type to match the trait
4444
|
4545
LL | fn bar(self) -> Option<()> {}

src/test/ui/compare-method/issue-90444.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | fn from(_: fn((), (), &mut ())) -> Self {
77
| types differ in mutability
88
| help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())`
99
|
10-
= note: expected fn pointer `fn(for<'a> fn((), (), &'a ())) -> A`
11-
found fn pointer `fn(for<'a> fn((), (), &'a mut ())) -> A`
10+
= note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A`
11+
found signature `fn(for<'a> fn((), (), &'a mut ())) -> A`
1212

1313
error[E0053]: method `from` has an incompatible type for trait
1414
--> $DIR/issue-90444.rs:11:16
@@ -19,8 +19,8 @@ LL | fn from(_: fn((), (), u64)) -> Self {
1919
| expected `u32`, found `u64`
2020
| help: change the parameter type to match the trait: `fn((), (), u32)`
2121
|
22-
= note: expected fn pointer `fn(fn((), (), u32)) -> B`
23-
found fn pointer `fn(fn((), (), u64)) -> B`
22+
= note: expected signature `fn(fn((), (), u32)) -> B`
23+
found signature `fn(fn((), (), u64)) -> B`
2424

2525
error: aborting due to 2 previous errors
2626

src/test/ui/compare-method/reordered-type-param.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ note: type in trait
1414
|
1515
LL | fn b<C:Clone,D>(&self, x: C) -> C;
1616
| ^
17-
= note: expected fn pointer `fn(&E, F) -> F`
18-
found fn pointer `fn(&E, G) -> G`
17+
= note: expected signature `fn(&E, F) -> F`
18+
found signature `fn(&E, G) -> G`
1919
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
2020
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
2121

src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ note: type in trait
1313
|
1414
LL | fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
1515
| ^^
16-
= note: expected fn pointer `fn(&(), &B, &impl Debug)`
17-
found fn pointer `fn(&(), &impl Debug, &B)`
16+
= note: expected signature `fn(&(), &B, &impl Debug)`
17+
found signature `fn(&(), &impl Debug, &B)`
1818
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
1919
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
2020

src/test/ui/impl-trait/in-trait/method-signature-matches.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ note: type in trait
1212
|
1313
LL | fn owo(x: ()) -> impl Sized;
1414
| ^^
15-
= note: expected fn pointer `fn(())`
16-
found fn pointer `fn(u8)`
15+
= note: expected signature `fn(())`
16+
found signature `fn(u8)`
1717

1818
error[E0053]: method `owo` has an incompatible type for trait
1919
--> $DIR/method-signature-matches.rs:20:21
@@ -39,8 +39,8 @@ note: type in trait
3939
|
4040
LL | async fn owo(x: ()) {}
4141
| ^^
42-
= note: expected fn pointer `fn(()) -> _`
43-
found fn pointer `fn(u8) -> _`
42+
= note: expected signature `fn(()) -> _`
43+
found signature `fn(u8) -> _`
4444

4545
error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0
4646
--> $DIR/method-signature-matches.rs:29:28
@@ -75,8 +75,8 @@ note: type in trait
7575
|
7676
LL | fn early<'early, T>(x: &'early T) -> impl Sized;
7777
| ^^^^^^^^^
78-
= note: expected fn pointer `fn(&'early T)`
79-
found fn pointer `fn(&())`
78+
= note: expected signature `fn(&'early T)`
79+
found signature `fn(&())`
8080

8181
error: aborting due to 5 previous errors
8282

0 commit comments

Comments
 (0)