Skip to content

Commit 5ae8e23

Browse files
committed
Mention fn coercion rules (needs to be expanded)
1 parent 153ed09 commit 5ae8e23

27 files changed

+56
-18
lines changed

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

+12
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18651865
self.check_and_note_conflicting_crates(diag, terr);
18661866

18671867
self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
1868+
if let Some(exp_found) = exp_found
1869+
&& let exp_found = TypeError::Sorts(exp_found)
1870+
&& exp_found != terr
1871+
{
1872+
self.note_and_explain_type_err(
1873+
diag,
1874+
exp_found,
1875+
cause,
1876+
span,
1877+
cause.body_id.to_def_id(),
1878+
);
1879+
}
18681880

18691881
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
18701882
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()

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

+7
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ impl<T> Trait<T> for X {
218218
);
219219
}
220220
}
221+
(ty::FnPtr(_), ty::FnDef(def, _))
222+
if let hir::def::DefKind::Fn = tcx.def_kind(def) => {
223+
diag.note(
224+
"when the arguments and return types match, functions can be coerced \
225+
to function pointers",
226+
);
227+
}
221228
_ => {}
222229
}
223230
debug!(

compiler/rustc_middle/src/ty/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl<T> ExpectedFound<T> {
2828
}
2929

3030
// Data structures used in type unification
31-
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
31+
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, PartialEq, Eq)]
3232
#[rustc_pass_by_value]
3333
pub enum TypeError<'tcx> {
3434
Mismatch,

tests/ui/argument-suggestions/two-mismatch-notes.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ LL | foo(f, w);
1111
| ^
1212
= note: expected fn pointer `fn(i32)`
1313
found fn item `fn(u32) {f}`
14+
= note: when the arguments and return types match, functions can be coerced to function pointers
1415
note: expected `Wrapper<i32>`, found `Wrapper<isize>`
1516
--> $DIR/two-mismatch-notes.rs:10:12
1617
|

tests/ui/associated-types/associated-types-eq-hr.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
1+
error[E0271]: type mismatch resolving `<UintStruct as TheTrait<&isize>>::A == &isize`
22
--> $DIR/associated-types-eq-hr.rs:87:11
33
|
44
LL | foo::<UintStruct>();
5-
| ^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
5+
| ^^^^^^^^^^ type mismatch resolving `<UintStruct as TheTrait<&isize>>::A == &isize`
66
|
77
note: expected this to be `&isize`
88
--> $DIR/associated-types-eq-hr.rs:26:14
@@ -20,11 +20,11 @@ LL | where
2020
LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
2121
| ^^^^^^^^^^^^^ required by this bound in `foo`
2222

23-
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
23+
error[E0271]: type mismatch resolving `<IntStruct as TheTrait<&isize>>::A == &usize`
2424
--> $DIR/associated-types-eq-hr.rs:91:11
2525
|
2626
LL | bar::<IntStruct>();
27-
| ^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
27+
| ^^^^^^^^^ type mismatch resolving `<IntStruct as TheTrait<&isize>>::A == &usize`
2828
|
2929
note: expected this to be `&usize`
3030
--> $DIR/associated-types-eq-hr.rs:14:14

tests/ui/associated-types/issue-87261.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ where
7777

7878
fn main() {
7979
accepts_trait(returns_opaque());
80-
//~^ ERROR type mismatch resolving `<impl Trait + 'static as Trait>::Associated == ()`
80+
//~^ ERROR type mismatch resolving `<impl Trait as Trait>::Associated == ()`
8181

8282
accepts_trait(returns_opaque_derived());
83-
//~^ ERROR type mismatch resolving `<impl DerivedTrait + 'static as Trait>::Associated == ()`
83+
//~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
8484

8585
accepts_trait(returns_opaque_foo());
8686
//~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
@@ -89,7 +89,7 @@ fn main() {
8989
//~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
9090

9191
accepts_generic_trait(returns_opaque_generic());
92-
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + 'static as GenericTrait<()>>::Associated == ()`
92+
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
9393

9494
accepts_generic_trait(returns_opaque_generic_foo());
9595
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`

tests/ui/associated-types/issue-87261.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ note: required by a bound in `accepts_generic_trait`
132132
LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
133133
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
134134

135-
error[E0271]: type mismatch resolving `<impl Trait + 'static as Trait>::Associated == ()`
135+
error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
136136
--> $DIR/issue-87261.rs:79:19
137137
|
138138
LL | fn returns_opaque() -> impl Trait + 'static {
@@ -155,7 +155,7 @@ help: consider constraining the associated type `<impl Trait + 'static as Trait>
155155
LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
156156
| +++++++++++++++++
157157

158-
error[E0271]: type mismatch resolving `<impl DerivedTrait + 'static as Trait>::Associated == ()`
158+
error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
159159
--> $DIR/issue-87261.rs:82:19
160160
|
161161
LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
@@ -222,7 +222,7 @@ note: required by a bound in `accepts_trait`
222222
LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
223223
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
224224

225-
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + 'static as GenericTrait<()>>::Associated == ()`
225+
error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
226226
--> $DIR/issue-87261.rs:91:27
227227
|
228228
LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {

tests/ui/c-variadic/variadic-ffi-1.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
4646
|
4747
= note: expected fn pointer `unsafe extern "C" fn(_, _)`
4848
found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
49+
= note: when the arguments and return types match, functions can be coerced to function pointers
4950

5051
error[E0308]: mismatched types
5152
--> $DIR/variadic-ffi-1.rs:26:54
@@ -57,6 +58,7 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar;
5758
|
5859
= note: expected fn pointer `extern "C" fn(_, _, ...)`
5960
found fn item `extern "C" fn(_, _) {bar}`
61+
= note: when the arguments and return types match, functions can be coerced to function pointers
6062

6163
error[E0617]: can't pass `f32` to variadic function
6264
--> $DIR/variadic-ffi-1.rs:28:19

tests/ui/fn/fn-pointer-mismatch.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ LL | let e: &fn(u32) -> u32 = &foo;
7878
= note: expected reference `&fn(u32) -> u32`
7979
found reference `&fn(u32) -> u32 {foo}`
8080
= note: fn items are distinct from fn pointers
81+
= note: when the arguments and return types match, functions can be coerced to function pointers
8182

8283
error: aborting due to 6 previous errors
8384

tests/ui/fn/signature-error-reporting-under-verbose.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ fn main() {
1212
//~| NOTE expected fn pointer, found fn item
1313
//~| NOTE expected fn pointer `fn(i32, u32)`
1414
//~| NOTE arguments to this function are incorrect
15+
//~| NOTE when the arguments and return types match, functions can be coerced to function pointers
1516
}

tests/ui/fn/signature-error-reporting-under-verbose.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | needs_ptr(foo);
88
|
99
= note: expected fn pointer `fn(i32, u32)`
1010
found fn item `fn(i32, i32) {foo}`
11+
= note: when the arguments and return types match, functions can be coerced to function pointers
1112
note: function defined here
1213
--> $DIR/signature-error-reporting-under-verbose.rs:5:4
1314
|

tests/ui/generic-associated-types/collections-project-default.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ LL | res
99
|
1010
= note: expected associated type `<C as Collection<i32>>::Sibling<f32>`
1111
found associated type `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>`
12+
= note: an associated type was expected, but a different one was found
1213

1314
error: aborting due to previous error
1415

tests/ui/generic-associated-types/issue-79422.extended.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ help: add missing lifetime argument
1414
LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
1515
| ++++
1616

17-
error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
17+
error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == dyn RefCont<'_, u8>`
1818
--> $DIR/issue-79422.rs:44:13
1919
|
2020
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == dyn RefCont<'_, u8>`
2222
|
2323
note: expected this to be `(dyn RefCont<'_, u8> + 'static)`
2424
--> $DIR/issue-79422.rs:28:25

tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0271]: type mismatch resolving `for<'r> <L<[[email protected]:42:16]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
1+
error[E0271]: type mismatch resolving `<L<[[email protected]:42:16]> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V`
22
--> $DIR/issue-62203-hrtb-ice.rs:39:9
33
|
44
LL | let v = Unit2.m(
@@ -10,7 +10,7 @@ LL | | f: |x| {
1010
... |
1111
LL | | },
1212
LL | | },
13-
| |_________^ type mismatch resolving `for<'r> <L<[[email protected]:42:16]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
13+
| |_________^ type mismatch resolving `<L<[[email protected]:42:16]> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V`
1414
|
1515
note: expected this to be `<_ as Ty<'_>>::V`
1616
--> $DIR/issue-62203-hrtb-ice.rs:21:14

tests/ui/impl-trait/equality2.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ LL | x = (x.1,
5454
|
5555
= note: expected opaque type `impl Foo` (`u32`)
5656
found opaque type `impl Foo` (`i32`)
57+
= note: distinct uses of `impl Trait` result in different opaque types
5758

5859
error[E0308]: mismatched types
5960
--> $DIR/equality2.rs:41:10
@@ -69,6 +70,7 @@ LL | x.0);
6970
|
7071
= note: expected opaque type `impl Foo` (`i32`)
7172
found opaque type `impl Foo` (`u32`)
73+
= note: distinct uses of `impl Trait` result in different opaque types
7274

7375
error: aborting due to 4 previous errors; 1 warning emitted
7476

tests/ui/issues/issue-10764.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | fn main() { f(bar) }
88
|
99
= note: expected fn pointer `fn()`
1010
found fn item `extern "C" fn() {bar}`
11+
= note: when the arguments and return types match, functions can be coerced to function pointers
1112
note: function defined here
1213
--> $DIR/issue-10764.rs:1:4
1314
|

tests/ui/issues/issue-39970.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ impl Visit for () where
1717

1818
fn main() {
1919
<() as Visit>::visit();
20-
//~^ ERROR type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
20+
//~^ ERROR type mismatch resolving `<() as Array<'a>>::Element == ()`
2121
}

tests/ui/issues/issue-39970.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
1+
error[E0271]: type mismatch resolving `<() as Array<'a>>::Element == ()`
22
--> $DIR/issue-39970.rs:19:5
33
|
44
LL | <() as Visit>::visit();
5-
| ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
5+
| ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Array<'a>>::Element == ()`
66
|
77
note: expected this to be `()`
88
--> $DIR/issue-39970.rs:10:20

tests/ui/mismatched_types/normalize-fn-sig.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | needs_i32_ref_fn(foo::<()>);
88
|
99
= note: expected fn pointer `fn(&'static i32, i32)`
1010
found fn item `fn(i32, &'static i32) {foo::<()>}`
11+
= note: when the arguments and return types match, functions can be coerced to function pointers
1112
note: function defined here
1213
--> $DIR/normalize-fn-sig.rs:11:4
1314
|

tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a;
66
|
77
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
88
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
9+
= note: when the arguments and return types match, functions can be coerced to function pointers
910

1011
error: aborting due to previous error
1112

tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
66
|
77
= note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)`
88
found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}`
9+
= note: when the arguments and return types match, functions can be coerced to function pointers
910

1011
error: aborting due to previous error
1112

tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | want_G(baz);
88
|
99
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S`
1010
found fn item `for<'a> fn(&'a S) -> &'a S {baz}`
11+
= note: when the arguments and return types match, functions can be coerced to function pointers
1112
note: function defined here
1213
--> $DIR/regions-fn-subtyping-return-static-fail.rs:20:4
1314
|

tests/ui/regions/regions-lifetime-bounds-on-fns.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a;
66
|
77
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
88
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
9+
= note: when the arguments and return types match, functions can be coerced to function pointers
910

1011
error: aborting due to previous error
1112

tests/ui/reify-intrinsic.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr
88
|
99
= note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize`
1010
found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
11+
= note: when the arguments and return types match, functions can be coerced to function pointers
1112

1213
error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
1314
--> $DIR/reify-intrinsic.rs:11:13

tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ LL | let foo: fn() = foo;
1515
found fn item `fn() {foo}`
1616
= note: fn items are distinct from fn pointers
1717
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
18+
= note: when the arguments and return types match, functions can be coerced to function pointers
1819

1920
error: aborting due to previous error
2021

tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ LL | let foo: fn() = foo;
1515
found fn item `fn() {foo}`
1616
= note: fn items are distinct from fn pointers
1717
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
18+
= note: when the arguments and return types match, functions can be coerced to function pointers
1819

1920
error: aborting due to previous error
2021

tests/ui/static/static-reference-to-fn-1.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ LL | func: &foo,
1010
= note: expected reference `&fn() -> Option<isize>`
1111
found reference `&fn() -> Option<isize> {foo}`
1212
= note: fn items are distinct from fn pointers
13+
= note: when the arguments and return types match, functions can be coerced to function pointers
1314

1415
error: aborting due to previous error
1516

0 commit comments

Comments
 (0)