Rollup merge of #129059 - compiler-errors:subtyping-correct-type, r=lcnr
Record the correct target type when coercing fn items/closures to pointers Self-explanatory. We were previously not recording the *target* type of a coercion as the output of an adjustment. This should remedy that. We must also modify the function pointer casts in MIR typeck to use subtyping, since those broke since #118247. r? lcnr
This commit is contained in:
commit
2200910659
8 changed files with 55 additions and 8 deletions
|
@ -1989,9 +1989,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
|
||||
let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
|
||||
|
||||
if let Err(terr) = self.eq_types(
|
||||
*ty,
|
||||
if let Err(terr) = self.sub_types(
|
||||
ty_fn_ptr_from,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
) {
|
||||
|
@ -2014,9 +2014,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
let ty_fn_ptr_from =
|
||||
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
|
||||
|
||||
if let Err(terr) = self.eq_types(
|
||||
*ty,
|
||||
if let Err(terr) = self.sub_types(
|
||||
ty_fn_ptr_from,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
) {
|
||||
|
|
|
@ -137,7 +137,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
at.lub(DefineOpaqueTypes::Yes, b, a)
|
||||
} else {
|
||||
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
|
||||
|
|
18
tests/mir-opt/build_correct_coerce.main.built.after.mir
Normal file
18
tests/mir-opt/build_correct_coerce.main.built.after.mir
Normal file
|
@ -0,0 +1,18 @@
|
|||
// MIR for `main` after built
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: for<'a> fn(&'a (), &'a ());
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer));
|
||||
FakeRead(ForLet(None), _1);
|
||||
_0 = const ();
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
12
tests/mir-opt/build_correct_coerce.rs
Normal file
12
tests/mir-opt/build_correct_coerce.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// skip-filecheck
|
||||
|
||||
// Validate that we record the target for the `as` coercion as `for<'a> fn(&'a (), &'a ())`,
|
||||
// and not `for<'a, 'b>(&'a (), &'b ())`. We previously did the latter due to a bug in
|
||||
// the code that records adjustments in HIR typeck.
|
||||
|
||||
fn foo<'a, 'b>(_: &'a (), _: &'b ()) {}
|
||||
|
||||
// EMIT_MIR build_correct_coerce.main.built.after.mir
|
||||
fn main() {
|
||||
let x = foo as for<'a> fn(&'a (), &'a ());
|
||||
}
|
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
|
||||
|
||||
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 = ()> {
|
||||
| --------------- this generic parameter must be used with a generic type parameter
|
||||
LL |
|
||||
LL | vec![].append(&mut ice(x.as_ref()));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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 == _`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
|
||||
println!("{x}");
|
||||
}
|
||||
|
|
|
@ -44,6 +44,12 @@ LL | drop(<() as Foo>::copy_me(&x));
|
|||
|
|
||||
= 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`.
|
||||
|
|
Loading…
Add table
Reference in a new issue