Skip to content

Commit 31bb4ab

Browse files
committed
Fix binder skipping
1 parent 5d4cce6 commit 31bb4ab

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

src/librustc/middle/traits/select.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -1369,9 +1369,28 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13691369
fn assemble_candidates_for_unsizing(&mut self,
13701370
obligation: &TraitObligation<'tcx>,
13711371
candidates: &mut SelectionCandidateSet<'tcx>) {
1372-
// It is ok to skip past the higher-ranked binders here because the `match`
1373-
// below does not consider regions at all.
1374-
let source = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
1372+
// We currently never consider higher-ranked obligations e.g.
1373+
// `for<'a> &'a T: Unsize<Trait+'a>` to be implemented. This is not
1374+
// because they are a priori invalid, and we could potentially add support
1375+
// for them later, it's just that there isn't really a strong need for it.
1376+
// A `T: Unsize<U>` obligation is always used as part of a `T: CoerceUnsize<U>`
1377+
// impl, and those are generally applied to concrete types.
1378+
//
1379+
// That said, one might try to write a fn with a where clause like
1380+
// for<'a> Foo<'a, T>: Unsize<Foo<'a, Trait>>
1381+
// where the `'a` is kind of orthogonal to the relevant part of the `Unsize`.
1382+
// Still, you'd be more likely to write that where clause as
1383+
// T: Trait
1384+
// so it seems ok if we (conservatively) fail to accept that `Unsize`
1385+
// obligation above. Should be possible to extend this in the future.
1386+
let self_ty = match ty::no_late_bound_regions(self.tcx(), &obligation.self_ty()) {
1387+
Some(t) => t,
1388+
None => {
1389+
// Don't add any candidates if there are bound regions.
1390+
return;
1391+
}
1392+
};
1393+
let source = self.infcx.shallow_resolve(self_ty);
13751394
let target = self.infcx.shallow_resolve(obligation.predicate.0.input_types()[0]);
13761395

13771396
debug!("assemble_candidates_for_unsizing(source={}, target={})",
@@ -2403,8 +2422,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24032422
SelectionError<'tcx>> {
24042423
let tcx = self.tcx();
24052424

2406-
// TODO is this skip_binder Ok?
2407-
let source = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
2425+
// assemble_candidates_for_unsizing should ensure there are no late bound
2426+
// regions here. See the comment there for more details.
2427+
let source = self.infcx.shallow_resolve(
2428+
ty::no_late_bound_regions(tcx, &obligation.self_ty()).unwrap());
24082429
let target = self.infcx.shallow_resolve(obligation.predicate.0.input_types()[0]);
24092430

24102431
debug!("confirm_builtin_unsize_candidate(source={}, target={})",

0 commit comments

Comments
 (0)