Skip to content

Commit 2bf46ac

Browse files
committed
for<..> fn(..) lub fn(..) should lub to fn(..)
1 parent bfd1f3b commit 2bf46ac

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

compiler/rustc_infer/src/infer/relate/lattice.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ use tracing::{debug, instrument};
2626

2727
use super::StructurallyRelateAliases;
2828
use super::combine::PredicateEmittingRelation;
29-
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace};
29+
use crate::infer::{
30+
BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace,
31+
};
3032
use crate::traits::{Obligation, PredicateObligations};
3133

3234
#[derive(Clone, Copy)]
@@ -209,15 +211,38 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
209211
}
210212

211213
debug!("binders(a={:?}, b={:?})", a, b);
212-
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
214+
215+
let instantiate_with_infer = |binder| {
216+
self.infcx.instantiate_binder_with_fresh_vars(
217+
self.span(),
218+
BoundRegionConversionTime::HigherRankedType,
219+
binder,
220+
)
221+
};
222+
let r = match (a.no_bound_vars(), b.no_bound_vars()) {
213223
// When higher-ranked types are involved, computing the GLB/LUB is
214224
// very challenging, switch to invariance. This is obviously
215225
// overly conservative but works ok in practice.
216-
self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
217-
Ok(a)
218-
} else {
219-
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
220-
}
226+
(None, None) => {
227+
self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
228+
return Ok(a);
229+
}
230+
231+
// If we only have one type with bound vars then we convert
232+
// it to a non higher-ranked signature, This should always
233+
// be correct assuming we do not support subtyping of the form:
234+
// `fn(&'smallest ()) <: for<'a> fn(&'a ())`
235+
// but I don't think we currently do so or intend to start doing so.
236+
//
237+
// This is a bit of a special case but it was necessary for backwards
238+
// compatibility when starting to properly leak checking in coercions.
239+
(Some(a), None) => self.relate(a, instantiate_with_infer(b))?,
240+
(None, Some(b)) => self.relate(instantiate_with_infer(a), b)?,
241+
242+
(Some(a), Some(b)) => self.relate(a, b)?,
243+
};
244+
245+
Ok(ty::Binder::dummy(r))
221246
}
222247
}
223248

0 commit comments

Comments
 (0)