auto merge of #19884 : nikomatsakis/rust/issue-19730-perfect-forwarding, r=pnkfelix

Rewrite how the HRTB algorithm matches impls against obligations. Instead of impls providing higher-ranked trait-references, impls now once again only have early-bound regions. The skolemization checks are thus moved out into trait matching itself. This allows to implement "perfect forwarding" impls like those described in #19730. This PR builds on a previous PR that was already reviewed by @pnkfelix.

r? @pnkfelix 

Fixes #19730
This commit is contained in:
bors 2014-12-19 13:22:10 +00:00
commit bd90b936d7
84 changed files with 3195 additions and 2414 deletions

View file

@ -575,6 +575,12 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
}
}
impl<'tcx> Clean<TyParamBound> for ty::PolyTraitRef<'tcx> {
fn clean(&self, cx: &DocContext) -> TyParamBound {
self.0.clean(cx)
}
}
impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
fn clean(&self, cx: &DocContext) -> TyParamBound {
let tcx = match cx.tcx_opt() {
@ -913,7 +919,7 @@ impl<'tcx> Clean<Type> for ty::FnOutput<'tcx> {
}
}
impl<'a, 'tcx> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig<'tcx>) {
impl<'a, 'tcx> Clean<FnDecl> for (ast::DefId, &'a ty::PolyFnSig<'tcx>) {
fn clean(&self, cx: &DocContext) -> FnDecl {
let (did, sig) = *self;
let mut names = if did.node != 0 {
@ -925,10 +931,10 @@ impl<'a, 'tcx> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig<'tcx>) {
let _ = names.next();
}
FnDecl {
output: Return(sig.output.clean(cx)),
output: Return(sig.0.output.clean(cx)),
attrs: Vec::new(),
inputs: Arguments {
values: sig.inputs.iter().map(|t| {
values: sig.0.inputs.iter().map(|t| {
Argument {
type_: t.clean(cx),
id: 0,
@ -1082,14 +1088,14 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(cx),
self.fty.sig.clone()),
s => {
let sig = ty::FnSig {
inputs: self.fty.sig.inputs[1..].to_vec(),
..self.fty.sig.clone()
};
let sig = ty::Binder(ty::FnSig {
inputs: self.fty.sig.0.inputs[1..].to_vec(),
..self.fty.sig.0.clone()
});
let s = match s {
ty::ByValueExplicitSelfCategory => SelfValue,
ty::ByReferenceExplicitSelfCategory(..) => {
match self.fty.sig.inputs[0].sty {
match self.fty.sig.0.inputs[0].sty {
ty::ty_rptr(r, mt) => {
SelfBorrowed(r.clean(cx), mt.mutbl.clean(cx))
}
@ -1097,7 +1103,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
}
}
ty::ByBoxExplicitSelfCategory => {
SelfExplicit(self.fty.sig.inputs[0].clean(cx))
SelfExplicit(self.fty.sig.0.inputs[0].clean(cx))
}
ty::StaticExplicitSelfCategory => unreachable!(),
};
@ -1391,8 +1397,10 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
}
ty::ty_struct(did, ref substs) |
ty::ty_enum(did, ref substs) |
ty::ty_trait(box ty::TyTrait { principal: ty::TraitRef { def_id: did, ref substs },
.. }) => {
ty::ty_trait(box ty::TyTrait {
principal: ty::Binder(ty::TraitRef { def_id: did, ref substs }),
.. }) =>
{
let fqn = csearch::get_item_path(cx.tcx(), did);
let fqn: Vec<String> = fqn.into_iter().map(|i| {
i.to_string()