Skip to content

Commit fcc2323

Browse files
committed
Be stricter with binders in method probing.
1 parent 6539cb4 commit fcc2323

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
lines changed

src/librustc/middle/ty.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,12 @@ pub struct FnSig<'tcx> {
10771077

10781078
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
10791079

1080+
impl<'tcx> PolyFnSig<'tcx> {
1081+
pub fn input(&self, index: uint) -> ty::Binder<Ty<'tcx>> {
1082+
ty::Binder(self.0.inputs[index])
1083+
}
1084+
}
1085+
10801086
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
10811087
pub struct ParamTy {
10821088
pub space: subst::ParamSpace,
@@ -1464,10 +1470,12 @@ impl<'tcx> PolyTraitRef<'tcx> {
14641470
}
14651471

14661472
pub fn substs(&self) -> &'tcx Substs<'tcx> {
1473+
// TODO every use of this fn is probably a bug, it should yield Binder<>
14671474
self.0.substs
14681475
}
14691476

14701477
pub fn input_types(&self) -> &[Ty<'tcx>] {
1478+
// TODO every use of this fn is probably a bug, it should yield Binder<>
14711479
self.0.input_types()
14721480
}
14731481

@@ -6950,6 +6958,13 @@ impl<'tcx> RegionEscape for Ty<'tcx> {
69506958
}
69516959
}
69526960

6961+
impl<'tcx> RegionEscape for Substs<'tcx> {
6962+
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6963+
self.types.has_regions_escaping_depth(depth) ||
6964+
self.regions.has_regions_escaping_depth(depth)
6965+
}
6966+
}
6967+
69536968
impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace<T> {
69546969
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
69556970
self.iter_enumerated().any(|(space, _, t)| {

src/librustc_typeck/check/method/probe.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use middle::fast_reject;
1818
use middle::subst;
1919
use middle::subst::Subst;
2020
use middle::traits;
21-
use middle::ty::{self, Ty, ToPolyTraitRef};
21+
use middle::ty::{self, RegionEscape, Ty, ToPolyTraitRef};
2222
use middle::ty_fold::TypeFoldable;
2323
use middle::infer;
2424
use middle::infer::InferCtxt;
@@ -309,18 +309,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
309309
// argument type like `&Trait`.
310310
let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(), self_ty);
311311
self.elaborate_bounds(&[trait_ref.clone()], false, |this, new_trait_ref, m, method_num| {
312+
let new_trait_ref = this.erase_late_bound_regions(&new_trait_ref);
313+
312314
let vtable_index =
313315
traits::get_vtable_index_of_object_method(tcx,
314316
trait_ref.clone(),
315-
new_trait_ref.def_id(),
317+
new_trait_ref.def_id,
316318
method_num);
317319

318-
let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs());
320+
let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs);
319321

320322
this.inherent_candidates.push(Candidate {
321323
xform_self_ty: xform_self_ty,
322324
method_ty: m,
323-
kind: ObjectCandidate(new_trait_ref.def_id(), method_num, vtable_index)
325+
kind: ObjectCandidate(new_trait_ref.def_id, method_num, vtable_index)
324326
});
325327
});
326328
}
@@ -353,34 +355,37 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
353355
})
354356
.collect();
355357

356-
self.elaborate_bounds(bounds.as_slice(), true, |this, trait_ref, m, method_num| {
358+
self.elaborate_bounds(bounds.as_slice(), true, |this, poly_trait_ref, m, method_num| {
359+
let trait_ref =
360+
this.erase_late_bound_regions(&poly_trait_ref);
361+
357362
let xform_self_ty =
358-
this.xform_self_ty(&m, trait_ref.substs());
363+
this.xform_self_ty(&m, trait_ref.substs);
359364

360365
debug!("found match: trait_ref={} substs={} m={}",
361366
trait_ref.repr(this.tcx()),
362-
trait_ref.substs().repr(this.tcx()),
367+
trait_ref.substs.repr(this.tcx()),
363368
m.repr(this.tcx()));
364369
assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
365-
trait_ref.substs().types.get_slice(subst::TypeSpace).len());
370+
trait_ref.substs.types.get_slice(subst::TypeSpace).len());
366371
assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
367-
trait_ref.substs().regions().get_slice(subst::TypeSpace).len());
372+
trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
368373
assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
369-
trait_ref.substs().types.get_slice(subst::SelfSpace).len());
374+
trait_ref.substs.types.get_slice(subst::SelfSpace).len());
370375
assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
371-
trait_ref.substs().regions().get_slice(subst::SelfSpace).len());
376+
trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
372377

373378
// Because this trait derives from a where-clause, it
374379
// should not contain any inference variables or other
375380
// artifacts. This means it is safe to put into the
376381
// `WhereClauseCandidate` and (eventually) into the
377382
// `WhereClausePick`.
378-
assert!(trait_ref.substs().types.iter().all(|&t| !ty::type_needs_infer(t)));
383+
assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
379384

380385
this.inherent_candidates.push(Candidate {
381386
xform_self_ty: xform_self_ty,
382387
method_ty: m,
383-
kind: WhereClauseCandidate(trait_ref, method_num)
388+
kind: WhereClauseCandidate(poly_trait_ref, method_num)
384389
});
385390
});
386391
}
@@ -614,11 +619,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
614619
// Check whether there are any where-clauses pertaining to this trait.
615620
let caller_predicates =
616621
self.fcx.inh.param_env.caller_bounds.predicates.as_slice().to_vec();
617-
for bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
618-
.filter_map(|p| p.to_opt_poly_trait_ref())
619-
.filter(|b| b.def_id() == trait_def_id)
622+
for poly_bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
623+
.filter_map(|p| p.to_opt_poly_trait_ref())
624+
.filter(|b| b.def_id() == trait_def_id)
620625
{
621-
let xform_self_ty = self.xform_self_ty(&method_ty, bound.substs());
626+
let bound = self.erase_late_bound_regions(&poly_bound);
627+
let xform_self_ty = self.xform_self_ty(&method_ty, bound.substs);
622628

623629
debug!("assemble_where_clause_candidates: bound={} xform_self_ty={}",
624630
bound.repr(self.tcx()),
@@ -627,7 +633,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
627633
self.extension_candidates.push(Candidate {
628634
xform_self_ty: xform_self_ty,
629635
method_ty: method_ty.clone(),
630-
kind: WhereClauseCandidate(bound, method_index)
636+
kind: WhereClauseCandidate(poly_bound, method_index)
631637
});
632638
}
633639
}
@@ -920,6 +926,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
920926
method.fty.sig.0.inputs[0].repr(self.tcx()),
921927
substs.repr(self.tcx()));
922928

929+
assert!(!substs.has_escaping_regions());
930+
923931
// It is possible for type parameters or early-bound lifetimes
924932
// to appear in the signature of `self`. The substitutions we
925933
// are given do not include type/lifetime parameters for the
@@ -949,14 +957,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
949957
substs = &placeholder;
950958
}
951959

952-
// Replace early-bound regions and types.
953-
let xform_self_ty = method.fty.sig.0.inputs[0].subst(self.tcx(), substs);
960+
// Erase any late-bound regions from the method and substitute
961+
// in the values from the substitution.
962+
let xform_self_ty = method.fty.sig.input(0);
963+
let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty);
964+
let xform_self_ty = xform_self_ty.subst(self.tcx(), substs);
954965

955-
// Replace late-bound regions bound in the impl or
956-
// where-clause (2 levels of binding) and method (1 level of binding).
957-
self.erase_late_bound_regions(
958-
&self.erase_late_bound_regions(
959-
&ty::Binder(ty::Binder(xform_self_ty))))
966+
xform_self_ty
960967
}
961968

962969
fn impl_substs(&self,

0 commit comments

Comments
 (0)