1
Fork 0

Mention fn coercion rules (needs to be expanded)

This commit is contained in:
Esteban Küber 2023-01-06 20:15:10 +00:00
parent 153ed09fb3
commit 5ae8e23816
27 changed files with 56 additions and 18 deletions

View file

@ -1865,6 +1865,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.check_and_note_conflicting_crates(diag, terr); self.check_and_note_conflicting_crates(diag, terr);
self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id()); self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
if let Some(exp_found) = exp_found
&& let exp_found = TypeError::Sorts(exp_found)
&& exp_found != terr
{
self.note_and_explain_type_err(
diag,
exp_found,
cause,
span,
cause.body_id.to_def_id(),
);
}
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() && let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()

View file

@ -218,6 +218,13 @@ impl<T> Trait<T> for X {
); );
} }
} }
(ty::FnPtr(_), ty::FnDef(def, _))
if let hir::def::DefKind::Fn = tcx.def_kind(def) => {
diag.note(
"when the arguments and return types match, functions can be coerced \
to function pointers",
);
}
_ => {} _ => {}
} }
debug!( debug!(

View file

@ -28,7 +28,7 @@ impl<T> ExpectedFound<T> {
} }
// Data structures used in type unification // Data structures used in type unification
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)] #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, PartialEq, Eq)]
#[rustc_pass_by_value] #[rustc_pass_by_value]
pub enum TypeError<'tcx> { pub enum TypeError<'tcx> {
Mismatch, Mismatch,

View file

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

View file

@ -1,8 +1,8 @@
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize` error[E0271]: type mismatch resolving `<UintStruct as TheTrait<&isize>>::A == &isize`
--> $DIR/associated-types-eq-hr.rs:87:11 --> $DIR/associated-types-eq-hr.rs:87:11
| |
LL | foo::<UintStruct>(); LL | foo::<UintStruct>();
| ^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize` | ^^^^^^^^^^ type mismatch resolving `<UintStruct as TheTrait<&isize>>::A == &isize`
| |
note: expected this to be `&isize` note: expected this to be `&isize`
--> $DIR/associated-types-eq-hr.rs:26:14 --> $DIR/associated-types-eq-hr.rs:26:14
@ -20,11 +20,11 @@ LL | where
LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>, LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
| ^^^^^^^^^^^^^ required by this bound in `foo` | ^^^^^^^^^^^^^ required by this bound in `foo`
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize` error[E0271]: type mismatch resolving `<IntStruct as TheTrait<&isize>>::A == &usize`
--> $DIR/associated-types-eq-hr.rs:91:11 --> $DIR/associated-types-eq-hr.rs:91:11
| |
LL | bar::<IntStruct>(); LL | bar::<IntStruct>();
| ^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize` | ^^^^^^^^^ type mismatch resolving `<IntStruct as TheTrait<&isize>>::A == &usize`
| |
note: expected this to be `&usize` note: expected this to be `&usize`
--> $DIR/associated-types-eq-hr.rs:14:14 --> $DIR/associated-types-eq-hr.rs:14:14

View file

@ -77,10 +77,10 @@ where
fn main() { fn main() {
accepts_trait(returns_opaque()); accepts_trait(returns_opaque());
//~^ ERROR type mismatch resolving `<impl Trait + 'static as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl Trait as Trait>::Associated == ()`
accepts_trait(returns_opaque_derived()); accepts_trait(returns_opaque_derived());
//~^ ERROR type mismatch resolving `<impl DerivedTrait + 'static as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
accepts_trait(returns_opaque_foo()); accepts_trait(returns_opaque_foo());
//~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
@ -89,7 +89,7 @@ fn main() {
//~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
accepts_generic_trait(returns_opaque_generic()); accepts_generic_trait(returns_opaque_generic());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + 'static as GenericTrait<()>>::Associated == ()` //~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
accepts_generic_trait(returns_opaque_generic_foo()); accepts_generic_trait(returns_opaque_generic_foo());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()` //~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`

View file

@ -132,7 +132,7 @@ note: required by a bound in `accepts_generic_trait`
LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {} LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
error[E0271]: type mismatch resolving `<impl Trait + 'static as Trait>::Associated == ()` error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
--> $DIR/issue-87261.rs:79:19 --> $DIR/issue-87261.rs:79:19
| |
LL | fn returns_opaque() -> impl Trait + 'static { LL | fn returns_opaque() -> impl Trait + 'static {
@ -155,7 +155,7 @@ help: consider constraining the associated type `<impl Trait + 'static as Trait>
LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static { LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
| +++++++++++++++++ | +++++++++++++++++
error[E0271]: type mismatch resolving `<impl DerivedTrait + 'static as Trait>::Associated == ()` error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
--> $DIR/issue-87261.rs:82:19 --> $DIR/issue-87261.rs:82:19
| |
LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
@ -222,7 +222,7 @@ note: required by a bound in `accepts_trait`
LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {} LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + 'static as GenericTrait<()>>::Associated == ()` error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
--> $DIR/issue-87261.rs:91:27 --> $DIR/issue-87261.rs:91:27
| |
LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static { LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {

View file

@ -46,6 +46,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
| |
= note: expected fn pointer `unsafe extern "C" fn(_, _)` = note: expected fn pointer `unsafe extern "C" fn(_, _)`
found fn item `unsafe extern "C" fn(_, _, ...) {foo}` found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
= note: when the arguments and return types match, functions can be coerced to function pointers
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/variadic-ffi-1.rs:26:54 --> $DIR/variadic-ffi-1.rs:26:54
@ -57,6 +58,7 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar;
| |
= note: expected fn pointer `extern "C" fn(_, _, ...)` = note: expected fn pointer `extern "C" fn(_, _, ...)`
found fn item `extern "C" fn(_, _) {bar}` found fn item `extern "C" fn(_, _) {bar}`
= note: when the arguments and return types match, functions can be coerced to function pointers
error[E0617]: can't pass `f32` to variadic function error[E0617]: can't pass `f32` to variadic function
--> $DIR/variadic-ffi-1.rs:28:19 --> $DIR/variadic-ffi-1.rs:28:19

View file

@ -78,6 +78,7 @@ LL | let e: &fn(u32) -> u32 = &foo;
= note: expected reference `&fn(u32) -> u32` = note: expected reference `&fn(u32) -> u32`
found reference `&fn(u32) -> u32 {foo}` found reference `&fn(u32) -> u32 {foo}`
= note: fn items are distinct from fn pointers = note: fn items are distinct from fn pointers
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -12,4 +12,5 @@ fn main() {
//~| NOTE expected fn pointer, found fn item //~| NOTE expected fn pointer, found fn item
//~| NOTE expected fn pointer `fn(i32, u32)` //~| NOTE expected fn pointer `fn(i32, u32)`
//~| NOTE arguments to this function are incorrect //~| NOTE arguments to this function are incorrect
//~| NOTE when the arguments and return types match, functions can be coerced to function pointers
} }

View file

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

View file

@ -9,6 +9,7 @@ LL | res
| |
= note: expected associated type `<C as Collection<i32>>::Sibling<f32>` = note: expected associated type `<C as Collection<i32>>::Sibling<f32>`
found associated type `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>` found associated type `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>`
= note: an associated type was expected, but a different one was found
error: aborting due to previous error error: aborting due to previous error

View file

@ -14,11 +14,11 @@ help: add missing lifetime argument
LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>; LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
| ++++ | ++++
error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)` error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == dyn RefCont<'_, u8>`
--> $DIR/issue-79422.rs:44:13 --> $DIR/issue-79422.rs:44:13
| |
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new()) LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == dyn RefCont<'_, u8>`
| |
note: expected this to be `(dyn RefCont<'_, u8> + 'static)` note: expected this to be `(dyn RefCont<'_, u8> + 'static)`
--> $DIR/issue-79422.rs:28:25 --> $DIR/issue-79422.rs:28:25

View file

@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `for<'r> <L<[closure@issue-62203-hrtb-ice.rs:42:16]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` error[E0271]: type mismatch resolving `<L<[closure@issue-62203-hrtb-ice.rs:42:16]> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V`
--> $DIR/issue-62203-hrtb-ice.rs:39:9 --> $DIR/issue-62203-hrtb-ice.rs:39:9
| |
LL | let v = Unit2.m( LL | let v = Unit2.m(
@ -10,7 +10,7 @@ LL | | f: |x| {
... | ... |
LL | | }, LL | | },
LL | | }, LL | | },
| |_________^ type mismatch resolving `for<'r> <L<[closure@issue-62203-hrtb-ice.rs:42:16]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` | |_________^ type mismatch resolving `<L<[closure@issue-62203-hrtb-ice.rs:42:16]> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V`
| |
note: expected this to be `<_ as Ty<'_>>::V` note: expected this to be `<_ as Ty<'_>>::V`
--> $DIR/issue-62203-hrtb-ice.rs:21:14 --> $DIR/issue-62203-hrtb-ice.rs:21:14

View file

@ -54,6 +54,7 @@ LL | x = (x.1,
| |
= note: expected opaque type `impl Foo` (`u32`) = note: expected opaque type `impl Foo` (`u32`)
found opaque type `impl Foo` (`i32`) found opaque type `impl Foo` (`i32`)
= note: distinct uses of `impl Trait` result in different opaque types
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/equality2.rs:41:10 --> $DIR/equality2.rs:41:10
@ -69,6 +70,7 @@ LL | x.0);
| |
= note: expected opaque type `impl Foo` (`i32`) = note: expected opaque type `impl Foo` (`i32`)
found opaque type `impl Foo` (`u32`) found opaque type `impl Foo` (`u32`)
= note: distinct uses of `impl Trait` result in different opaque types
error: aborting due to 4 previous errors; 1 warning emitted error: aborting due to 4 previous errors; 1 warning emitted

View file

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

View file

@ -17,5 +17,5 @@ impl Visit for () where
fn main() { fn main() {
<() as Visit>::visit(); <() as Visit>::visit();
//~^ ERROR type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()` //~^ ERROR type mismatch resolving `<() as Array<'a>>::Element == ()`
} }

View file

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

View file

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

View file

@ -6,6 +6,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a;
| |
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)` = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}` found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to previous error error: aborting due to previous error

View file

@ -6,6 +6,7 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| |
= note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)` = note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)`
found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}` found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}`
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to previous error error: aborting due to previous error

View file

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

View file

@ -6,6 +6,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a;
| |
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)` = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}` found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to previous error error: aborting due to previous error

View file

@ -8,6 +8,7 @@ LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr
| |
= note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize` = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize`
found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
= note: when the arguments and return types match, functions can be coerced to function pointers
error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
--> $DIR/reify-intrinsic.rs:11:13 --> $DIR/reify-intrinsic.rs:11:13

View file

@ -15,6 +15,7 @@ LL | let foo: fn() = foo;
found fn item `fn() {foo}` found fn item `fn() {foo}`
= note: fn items are distinct from fn pointers = note: fn items are distinct from fn pointers
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to previous error error: aborting due to previous error

View file

@ -15,6 +15,7 @@ LL | let foo: fn() = foo;
found fn item `fn() {foo}` found fn item `fn() {foo}`
= note: fn items are distinct from fn pointers = note: fn items are distinct from fn pointers
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to previous error error: aborting due to previous error

View file

@ -10,6 +10,7 @@ LL | func: &foo,
= note: expected reference `&fn() -> Option<isize>` = note: expected reference `&fn() -> Option<isize>`
found reference `&fn() -> Option<isize> {foo}` found reference `&fn() -> Option<isize> {foo}`
= note: fn items are distinct from fn pointers = note: fn items are distinct from fn pointers
= note: when the arguments and return types match, functions can be coerced to function pointers
error: aborting due to previous error error: aborting due to previous error