Be stricter with binders in method probing.
This commit is contained in:
parent
6539cb417f
commit
fcc23238fd
2 changed files with 47 additions and 25 deletions
|
|
@ -1077,6 +1077,12 @@ pub struct FnSig<'tcx> {
|
|||
|
||||
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyFnSig<'tcx> {
|
||||
pub fn input(&self, index: uint) -> ty::Binder<Ty<'tcx>> {
|
||||
ty::Binder(self.0.inputs[index])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
|
||||
pub struct ParamTy {
|
||||
pub space: subst::ParamSpace,
|
||||
|
|
@ -1464,10 +1470,12 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
|||
}
|
||||
|
||||
pub fn substs(&self) -> &'tcx Substs<'tcx> {
|
||||
// TODO every use of this fn is probably a bug, it should yield Binder<>
|
||||
self.0.substs
|
||||
}
|
||||
|
||||
pub fn input_types(&self) -> &[Ty<'tcx>] {
|
||||
// TODO every use of this fn is probably a bug, it should yield Binder<>
|
||||
self.0.input_types()
|
||||
}
|
||||
|
||||
|
|
@ -6950,6 +6958,13 @@ impl<'tcx> RegionEscape for Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> RegionEscape for Substs<'tcx> {
|
||||
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
|
||||
self.types.has_regions_escaping_depth(depth) ||
|
||||
self.regions.has_regions_escaping_depth(depth)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace<T> {
|
||||
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
|
||||
self.iter_enumerated().any(|(space, _, t)| {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use middle::fast_reject;
|
|||
use middle::subst;
|
||||
use middle::subst::Subst;
|
||||
use middle::traits;
|
||||
use middle::ty::{self, Ty, ToPolyTraitRef};
|
||||
use middle::ty::{self, RegionEscape, Ty, ToPolyTraitRef};
|
||||
use middle::ty_fold::TypeFoldable;
|
||||
use middle::infer;
|
||||
use middle::infer::InferCtxt;
|
||||
|
|
@ -309,18 +309,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
// argument type like `&Trait`.
|
||||
let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(), self_ty);
|
||||
self.elaborate_bounds(&[trait_ref.clone()], false, |this, new_trait_ref, m, method_num| {
|
||||
let new_trait_ref = this.erase_late_bound_regions(&new_trait_ref);
|
||||
|
||||
let vtable_index =
|
||||
traits::get_vtable_index_of_object_method(tcx,
|
||||
trait_ref.clone(),
|
||||
new_trait_ref.def_id(),
|
||||
new_trait_ref.def_id,
|
||||
method_num);
|
||||
|
||||
let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs());
|
||||
let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs);
|
||||
|
||||
this.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
method_ty: m,
|
||||
kind: ObjectCandidate(new_trait_ref.def_id(), method_num, vtable_index)
|
||||
kind: ObjectCandidate(new_trait_ref.def_id, method_num, vtable_index)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -353,34 +355,37 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
self.elaborate_bounds(bounds.as_slice(), true, |this, trait_ref, m, method_num| {
|
||||
self.elaborate_bounds(bounds.as_slice(), true, |this, poly_trait_ref, m, method_num| {
|
||||
let trait_ref =
|
||||
this.erase_late_bound_regions(&poly_trait_ref);
|
||||
|
||||
let xform_self_ty =
|
||||
this.xform_self_ty(&m, trait_ref.substs());
|
||||
this.xform_self_ty(&m, trait_ref.substs);
|
||||
|
||||
debug!("found match: trait_ref={} substs={} m={}",
|
||||
trait_ref.repr(this.tcx()),
|
||||
trait_ref.substs().repr(this.tcx()),
|
||||
trait_ref.substs.repr(this.tcx()),
|
||||
m.repr(this.tcx()));
|
||||
assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
|
||||
trait_ref.substs().types.get_slice(subst::TypeSpace).len());
|
||||
trait_ref.substs.types.get_slice(subst::TypeSpace).len());
|
||||
assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
|
||||
trait_ref.substs().regions().get_slice(subst::TypeSpace).len());
|
||||
trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
|
||||
assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
|
||||
trait_ref.substs().types.get_slice(subst::SelfSpace).len());
|
||||
trait_ref.substs.types.get_slice(subst::SelfSpace).len());
|
||||
assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
|
||||
trait_ref.substs().regions().get_slice(subst::SelfSpace).len());
|
||||
trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
|
||||
|
||||
// Because this trait derives from a where-clause, it
|
||||
// should not contain any inference variables or other
|
||||
// artifacts. This means it is safe to put into the
|
||||
// `WhereClauseCandidate` and (eventually) into the
|
||||
// `WhereClausePick`.
|
||||
assert!(trait_ref.substs().types.iter().all(|&t| !ty::type_needs_infer(t)));
|
||||
assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
|
||||
|
||||
this.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
method_ty: m,
|
||||
kind: WhereClauseCandidate(trait_ref, method_num)
|
||||
kind: WhereClauseCandidate(poly_trait_ref, method_num)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -614,11 +619,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
// Check whether there are any where-clauses pertaining to this trait.
|
||||
let caller_predicates =
|
||||
self.fcx.inh.param_env.caller_bounds.predicates.as_slice().to_vec();
|
||||
for bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
|
||||
.filter_map(|p| p.to_opt_poly_trait_ref())
|
||||
.filter(|b| b.def_id() == trait_def_id)
|
||||
for poly_bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
|
||||
.filter_map(|p| p.to_opt_poly_trait_ref())
|
||||
.filter(|b| b.def_id() == trait_def_id)
|
||||
{
|
||||
let xform_self_ty = self.xform_self_ty(&method_ty, bound.substs());
|
||||
let bound = self.erase_late_bound_regions(&poly_bound);
|
||||
let xform_self_ty = self.xform_self_ty(&method_ty, bound.substs);
|
||||
|
||||
debug!("assemble_where_clause_candidates: bound={} xform_self_ty={}",
|
||||
bound.repr(self.tcx()),
|
||||
|
|
@ -627,7 +633,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
self.extension_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
method_ty: method_ty.clone(),
|
||||
kind: WhereClauseCandidate(bound, method_index)
|
||||
kind: WhereClauseCandidate(poly_bound, method_index)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -920,6 +926,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
method.fty.sig.0.inputs[0].repr(self.tcx()),
|
||||
substs.repr(self.tcx()));
|
||||
|
||||
assert!(!substs.has_escaping_regions());
|
||||
|
||||
// It is possible for type parameters or early-bound lifetimes
|
||||
// to appear in the signature of `self`. The substitutions we
|
||||
// are given do not include type/lifetime parameters for the
|
||||
|
|
@ -949,14 +957,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
substs = &placeholder;
|
||||
}
|
||||
|
||||
// Replace early-bound regions and types.
|
||||
let xform_self_ty = method.fty.sig.0.inputs[0].subst(self.tcx(), substs);
|
||||
// Erase any late-bound regions from the method and substitute
|
||||
// in the values from the substitution.
|
||||
let xform_self_ty = method.fty.sig.input(0);
|
||||
let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty);
|
||||
let xform_self_ty = xform_self_ty.subst(self.tcx(), substs);
|
||||
|
||||
// Replace late-bound regions bound in the impl or
|
||||
// where-clause (2 levels of binding) and method (1 level of binding).
|
||||
self.erase_late_bound_regions(
|
||||
&self.erase_late_bound_regions(
|
||||
&ty::Binder(ty::Binder(xform_self_ty))))
|
||||
xform_self_ty
|
||||
}
|
||||
|
||||
fn impl_substs(&self,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue