Skip to content

Commit 8c19f74

Browse files
committed
leak check when lubbing fndefs
1 parent ae9a3aa commit 8c19f74

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,9 +1156,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11561156
(ty::FnDef(..), ty::FnDef(..)) => {
11571157
// Don't reify if the function types have a LUB, i.e., they
11581158
// are the same function and their parameters have a LUB.
1159-
match self.commit_if_ok(|_| {
1159+
match self.commit_if_ok(|snapshot| {
1160+
let outer_universe = self.infcx.universe();
1161+
11601162
// We need to eagerly handle nested obligations due to lazy norm.
1161-
if self.next_trait_solver() {
1163+
let result = if self.next_trait_solver() {
11621164
let ocx = ObligationCtxt::new(self);
11631165
let value = ocx.lub(cause, self.param_env, prev_ty, new_ty)?;
11641166
if ocx.try_evaluate_obligations().is_empty() {
@@ -1171,7 +1173,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11711173
}
11721174
} else {
11731175
self.at(cause, self.param_env).lub(prev_ty, new_ty)
1174-
}
1176+
};
1177+
1178+
self.leak_check(outer_universe, Some(snapshot))?;
1179+
result
11751180
}) {
11761181
// We have a LUB of prev_ty and new_ty, just return it.
11771182
Ok(ok) => return Ok(self.register_infer_ok_obligations(ok)),
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ check-pass
2+
3+
fn foo<T>() {}
4+
5+
fn fndef_lub_leak_check() {
6+
macro_rules! lub {
7+
($lhs:expr, $rhs:expr) => {
8+
if true { $lhs } else { $rhs }
9+
};
10+
}
11+
12+
// These don't current lub but could in theory one day.
13+
// If that happens this test should be adjusted to use
14+
// fn ptrs that can't be lub'd.
15+
let lhs = foo::<for<'a> fn(&'static (), &'a ())>;
16+
let rhs = foo::<for<'a> fn(&'a (), &'static ())>;
17+
18+
// If we leak check then we know we should coerce these
19+
// to `fn()`, if we don't leak check we may try to keep
20+
// them as `FnDef`s which would result in a borrowck
21+
// error.
22+
let lubbed = lub!(lhs, rhs);
23+
24+
// assert that we coerced lhs/rhs to a fn ptr
25+
is_fnptr(lubbed);
26+
}
27+
28+
trait FnPtr {}
29+
impl FnPtr for fn() {}
30+
fn is_fnptr<T: FnPtr>(_: T) {}
31+
32+
fn main() {}

0 commit comments

Comments
 (0)