Skip to content

Commit

Permalink
Rollup merge of rust-lang#129059 - compiler-errors:subtyping-correct-…
Browse files Browse the repository at this point in the history
…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 rust-lang#118247.

r? lcnr
  • Loading branch information
jieyouxu authored Aug 14, 2024
2 parents 049b3e5 + 5df13af commit 2200910
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 8 deletions.
8 changes: 4 additions & 4 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
) {
Expand All @@ -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 },
) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions tests/mir-opt/build_correct_coerce.main.built.after.mir
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions tests/mir-opt/build_correct_coerce.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions tests/ui/higher-ranked/subtyping-fn-ptr-coercion.rs
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/recursive-ice-101862.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions tests/ui/traits/next-solver/alias-bound-unsound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}");
}
8 changes: 7 additions & 1 deletion tests/ui/traits/next-solver/alias-bound-unsound.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

0 comments on commit 2200910

Please sign in to comment.