Use the right type when coercing fn items to pointers

This commit is contained in:
Michael Goulet 2024-08-12 11:59:04 -04:00
parent 850bcbdc2e
commit 5df13af56f
7 changed files with 26 additions and 9 deletions

View File

@ -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 },
) { ) {

View File

@ -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

View File

@ -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);

View 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);
}

View File

@ -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

View File

@ -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}");
} }

View File

@ -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`.