Skip to content

Commit 623f16e

Browse files
committed
leak check when lubbing fndefs
1 parent 50a11d1 commit 623f16e

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
@@ -1181,9 +1181,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11811181
(ty::FnDef(..), ty::FnDef(..)) => {
11821182
// Don't reify if the function types have a LUB, i.e., they
11831183
// are the same function and their parameters have a LUB.
1184-
match self.commit_if_ok(|_| {
1184+
match self.commit_if_ok(|snapshot| {
1185+
let outer_universe = self.infcx.universe();
1186+
11851187
// We need to eagerly handle nested obligations due to lazy norm.
1186-
if self.next_trait_solver() {
1188+
let result = if self.next_trait_solver() {
11871189
let ocx = ObligationCtxt::new(self);
11881190
let value = ocx.lub(cause, self.param_env, prev_ty, new_ty)?;
11891191
if ocx.try_evaluate_obligations().is_empty() {
@@ -1196,7 +1198,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11961198
}
11971199
} else {
11981200
self.at(cause, self.param_env).lub(prev_ty, new_ty)
1199-
}
1201+
};
1202+
1203+
self.leak_check(outer_universe, Some(snapshot))?;
1204+
result
12001205
}) {
12011206
// We have a LUB of prev_ty and new_ty, just return it.
12021207
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)