Use the right type when coercing fn items to pointers
This commit is contained in:
parent
850bcbdc2e
commit
5df13af56f
@ -1989,9 +1989,9 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
|
|
||||||
let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
|
let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
|
||||||
|
|
||||||
if let Err(terr) = self.eq_types(
|
if let Err(terr) = self.sub_types(
|
||||||
*ty,
|
|
||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { unsize_to: None },
|
||||||
) {
|
) {
|
||||||
@ -2014,9 +2014,9 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
let ty_fn_ptr_from =
|
let ty_fn_ptr_from =
|
||||||
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
|
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
|
||||||
|
|
||||||
if let Err(terr) = self.eq_types(
|
if let Err(terr) = self.sub_types(
|
||||||
*ty,
|
|
||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { unsize_to: None },
|
||||||
) {
|
) {
|
||||||
|
@ -137,7 +137,7 @@ fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
|
|||||||
at.lub(DefineOpaqueTypes::Yes, b, a)
|
at.lub(DefineOpaqueTypes::Yes, b, a)
|
||||||
} else {
|
} else {
|
||||||
at.sup(DefineOpaqueTypes::Yes, b, a)
|
at.sup(DefineOpaqueTypes::Yes, b, a)
|
||||||
.map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
|
.map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
|
||||||
};
|
};
|
||||||
|
|
||||||
// In the new solver, lazy norm may allow us to shallowly equate
|
// In the new solver, lazy norm may allow us to shallowly equate
|
||||||
|
@ -9,7 +9,7 @@ fn main() -> () {
|
|||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
StorageLive(_1);
|
StorageLive(_1);
|
||||||
_1 = foo as for<'a, 'b> fn(&'a (), &'b ()) (PointerCoercion(ReifyFnPointer));
|
_1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer));
|
||||||
FakeRead(ForLet(None), _1);
|
FakeRead(ForLet(None), _1);
|
||||||
_0 = const ();
|
_0 = const ();
|
||||||
StorageDead(_1);
|
StorageDead(_1);
|
||||||
|
10
tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs
Normal file
10
tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Check that we use subtyping when reifying a closure into a function pointer.
|
||||||
|
|
||||||
|
fn foo(x: &str) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let c = |_: &str| {};
|
||||||
|
let x = c as fn(&'static str);
|
||||||
|
}
|
@ -11,13 +11,13 @@ LL | vec![].append(&mut ice(x.as_ref()));
|
|||||||
= note: `#[warn(unconditional_recursion)]` on by default
|
= note: `#[warn(unconditional_recursion)]` on by default
|
||||||
|
|
||||||
error[E0792]: expected generic type parameter, found `&str`
|
error[E0792]: expected generic type parameter, found `&str`
|
||||||
--> $DIR/recursive-ice-101862.rs:6:5
|
--> $DIR/recursive-ice-101862.rs:6:19
|
||||||
|
|
|
|
||||||
LL | pub fn ice(x: impl AsRef<str>) -> impl IntoIterator<Item = ()> {
|
LL | pub fn ice(x: impl AsRef<str>) -> impl IntoIterator<Item = ()> {
|
||||||
| --------------- this generic parameter must be used with a generic type parameter
|
| --------------- this generic parameter must be used with a generic type parameter
|
||||||
LL |
|
LL |
|
||||||
LL | vec![].append(&mut ice(x.as_ref()));
|
LL | vec![].append(&mut ice(x.as_ref()));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error; 1 warning emitted
|
||||||
|
|
||||||
|
@ -27,5 +27,6 @@ fn main() {
|
|||||||
//~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
|
//~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
|
||||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||||
|
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||||
println!("{x}");
|
println!("{x}");
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,12 @@ LL | drop(<() as Foo>::copy_me(&x));
|
|||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||||
|
--> $DIR/alias-bound-unsound.rs:24:31
|
||||||
|
|
|
||||||
|
LL | drop(<() as Foo>::copy_me(&x));
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0275`.
|
For more information about this error, try `rustc --explain E0275`.
|
||||||
|
Loading…
Reference in New Issue
Block a user