Search for implemented kinds recursively on Trait types. Fixes #15155 and #13155.

This commit is contained in:
Ricky Taylor 2014-11-16 18:20:19 +00:00
parent 5ff10d5a23
commit 729bf447ab
2 changed files with 50 additions and 1 deletions

View File

@ -1327,7 +1327,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
match bound {
ty::BoundSized => {
Err(Unimplemented)
@ -1336,6 +1336,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if bounds.builtin_bounds.contains(&bound) {
Ok(If(Vec::new()))
} else {
// Recursively check all supertraits to find out if any further
// bounds are required and thus we must fulfill.
// We have to create a temp trait ref here since TyTraits don't
// have actual self type info (which is required for the
// supertraits iterator).
let tmp_tr = Rc::new(ty::TraitRef {
def_id: principal.def_id,
substs: principal.substs.with_self_ty(ty::mk_err())
});
for tr in util::supertraits(self.tcx(), tmp_tr) {
let td = ty::lookup_trait_def(self.tcx(), tr.def_id);
if td.bounds.builtin_bounds.contains(&bound) {
return Ok(If(Vec::new()))
}
}
Err(Unimplemented)
}
}

View File

@ -0,0 +1,32 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
trait TraitWithSend: Send {}
trait IndirectTraitWithSend: TraitWithSend {}
// Check struct instantiation (Box<TraitWithSend> will only have Send if TraitWithSend has Send)
#[allow(dead_code)]
struct Blah { x: Box<TraitWithSend> }
impl TraitWithSend for Blah {}
// Struct instantiation 2-levels deep
#[allow(dead_code)]
struct IndirectBlah { x: Box<IndirectTraitWithSend> }
impl TraitWithSend for IndirectBlah {}
impl IndirectTraitWithSend for IndirectBlah {}
fn test_trait<Sized? T: Send>() { println!("got here!") }
fn main() {
test_trait::<TraitWithSend>();
test_trait::<IndirectTraitWithSend>();
}