Skip to content

Commit

Permalink
Add regression test
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Apr 23, 2024
1 parent ad07aa1 commit a18f043
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
57 changes: 57 additions & 0 deletions tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//! Test that coercing between function items of different functions works,
//! as long as their signatures match. The resulting value is a function pointer.

#![feature(type_alias_impl_trait)]

fn foo<T>(t: T) -> T {
t
}

fn bar<T>(t: T) -> T {
t
}

type F = impl Sized;

fn f(a: F) {
let mut x = bar::<F>;
x = foo::<()>; //~ ERROR: mismatched types
x(a);
x(());
}

type I = impl Sized;

fn i(a: I) {
let mut x = bar::<()>;
x = foo::<I>; //~ ERROR: mismatched types
x(a);
x(());
}

type J = impl Sized;

fn j(a: J) {
let x = match true {
true => bar::<J>,
false => foo::<()>, //~ ERROR: incompatible types
};
x(a);
x(());
}

fn k() -> impl Sized {
fn bind<T, F: FnOnce(T) -> T>(_: T, f: F) -> F {
f
}
let x = match true {
true => {
let f = foo;
bind(k(), f)
}
false => bar::<()>, //~ ERROR: incompatible types
};
todo!()
}

fn main() {}
77 changes: 77 additions & 0 deletions tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
error[E0308]: mismatched types
--> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:18:9
|
LL | type F = impl Sized;
| ---------- the expected opaque type
...
LL | let mut x = bar::<F>;
| -------- expected due to this value
LL | x = foo::<()>;
| ^^^^^^^^^ expected fn item, found a different fn item
|
= note: expected fn item `fn(F) -> F {bar::<F>}`
found fn item `fn(()) {foo::<()>}`

error[E0308]: mismatched types
--> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:27:9
|
LL | fn foo<T>(t: T) -> T {
| -------------------- function `foo` defined here
...
LL | type I = impl Sized;
| ---------- the found opaque type
...
LL | let mut x = bar::<()>;
| --------- expected due to this value
LL | x = foo::<I>;
| ^^^^^^^^ expected fn item, found a different fn item
|
= note: expected fn item `fn(()) {bar::<()>}`
found fn item `fn(I) -> I {foo::<I>}`
help: use parentheses to call this function
|
LL | x = foo::<I>(/* I */);
| +++++++++

error[E0308]: `match` arms have incompatible types
--> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:37:18
|
LL | type J = impl Sized;
| ---------- the expected opaque type
...
LL | let x = match true {
| _____________-
LL | | true => bar::<J>,
| | -------- this is found to be of type `fn(J) -> J {bar::<J>}`
LL | | false => foo::<()>,
| | ^^^^^^^^^ expected opaque type, found `()`
LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected fn item `fn(J) -> J {bar::<J>}`
found fn item `fn(()) {foo::<()>}`

error[E0308]: `match` arms have incompatible types
--> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:52:18
|
LL | fn k() -> impl Sized {
| ---------- the expected opaque type
...
LL | let x = match true {
| _____________-
LL | | true => {
LL | | let f = foo;
LL | | bind(k(), f)
| | ------------ this is found to be of type `fn(impl Sized) -> impl Sized {foo::<impl Sized>}`
LL | | }
LL | | false => bar::<()>,
| | ^^^^^^^^^ expected opaque type, found `()`
LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected fn item `fn(impl Sized) -> impl Sized {foo::<impl Sized>}`
found fn item `fn(()) {bar::<()>}`

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0308`.

0 comments on commit a18f043

Please sign in to comment.