Skip to content

Commit 2200910

Browse files
authored
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
2 parents 049b3e5 + 5df13af commit 2200910

File tree

8 files changed

+55
-8
lines changed

8 files changed

+55
-8
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1989,9 +1989,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19891989

19901990
let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
19911991

1992-
if let Err(terr) = self.eq_types(
1993-
*ty,
1992+
if let Err(terr) = self.sub_types(
19941993
ty_fn_ptr_from,
1994+
*ty,
19951995
location.to_locations(),
19961996
ConstraintCategory::Cast { unsize_to: None },
19971997
) {
@@ -2014,9 +2014,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20142014
let ty_fn_ptr_from =
20152015
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
20162016

2017-
if let Err(terr) = self.eq_types(
2018-
*ty,
2017+
if let Err(terr) = self.sub_types(
20192018
ty_fn_ptr_from,
2019+
*ty,
20202020
location.to_locations(),
20212021
ConstraintCategory::Cast { unsize_to: None },
20222022
) {

compiler/rustc_hir_typeck/src/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
137137
at.lub(DefineOpaqueTypes::Yes, b, a)
138138
} else {
139139
at.sup(DefineOpaqueTypes::Yes, b, a)
140-
.map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
140+
.map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
141141
};
142142

143143
// In the new solver, lazy norm may allow us to shallowly equate
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// MIR for `main` after built
2+
3+
fn main() -> () {
4+
let mut _0: ();
5+
let _1: for<'a> fn(&'a (), &'a ());
6+
scope 1 {
7+
debug x => _1;
8+
}
9+
10+
bb0: {
11+
StorageLive(_1);
12+
_1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer));
13+
FakeRead(ForLet(None), _1);
14+
_0 = const ();
15+
StorageDead(_1);
16+
return;
17+
}
18+
}

tests/mir-opt/build_correct_coerce.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// skip-filecheck
2+
3+
// Validate that we record the target for the `as` coercion as `for<'a> fn(&'a (), &'a ())`,
4+
// and not `for<'a, 'b>(&'a (), &'b ())`. We previously did the latter due to a bug in
5+
// the code that records adjustments in HIR typeck.
6+
7+
fn foo<'a, 'b>(_: &'a (), _: &'b ()) {}
8+
9+
// EMIT_MIR build_correct_coerce.main.built.after.mir
10+
fn main() {
11+
let x = foo as for<'a> fn(&'a (), &'a ());
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ check-pass
2+
3+
// Check that we use subtyping when reifying a closure into a function pointer.
4+
5+
fn foo(x: &str) {}
6+
7+
fn main() {
8+
let c = |_: &str| {};
9+
let x = c as fn(&'static str);
10+
}

tests/ui/impl-trait/recursive-ice-101862.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ LL | vec![].append(&mut ice(x.as_ref()));
1111
= note: `#[warn(unconditional_recursion)]` on by default
1212

1313
error[E0792]: expected generic type parameter, found `&str`
14-
--> $DIR/recursive-ice-101862.rs:6:5
14+
--> $DIR/recursive-ice-101862.rs:6:19
1515
|
1616
LL | pub fn ice(x: impl AsRef<str>) -> impl IntoIterator<Item = ()> {
1717
| --------------- this generic parameter must be used with a generic type parameter
1818
LL |
1919
LL | vec![].append(&mut ice(x.as_ref()));
20-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
| ^^^^^^^^^^^^^^^^^^^^
2121

2222
error: aborting due to 1 previous error; 1 warning emitted
2323

tests/ui/traits/next-solver/alias-bound-unsound.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ fn main() {
2727
//~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
2828
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
2929
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
30+
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
3031
println!("{x}");
3132
}

tests/ui/traits/next-solver/alias-bound-unsound.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ LL | drop(<() as Foo>::copy_me(&x));
4444
|
4545
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
4646

47-
error: aborting due to 6 previous errors
47+
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
48+
--> $DIR/alias-bound-unsound.rs:24:31
49+
|
50+
LL | drop(<() as Foo>::copy_me(&x));
51+
| ^^
52+
53+
error: aborting due to 7 previous errors
4854

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

0 commit comments

Comments
 (0)