Skip to content

Commit

Permalink
Search for implemented kinds recursively on Trait types. Fixes #15155
Browse files Browse the repository at this point in the history
…and #13155.
  • Loading branch information
ricky26 committed Nov 23, 2014
1 parent 5ff10d5 commit 729bf44
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/librustc/middle/traits/select.rs
Expand Up @@ -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)
Expand All @@ -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)
}
}
Expand Down
32 changes: 32 additions & 0 deletions src/test/run-pass/issue-15155.rs
@@ -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>();
}


5 comments on commit 729bf44

@bors
Copy link
Contributor

@bors bors commented on 729bf44 Nov 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at ricky26@729bf44

@bors
Copy link
Contributor

@bors bors commented on 729bf44 Nov 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging ricky26/rust/trait_supertraits = 729bf44 into auto

@bors
Copy link
Contributor

@bors bors commented on 729bf44 Nov 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ricky26/rust/trait_supertraits = 729bf44 merged ok, testing candidate = eedfc07

@bors
Copy link
Contributor

@bors bors commented on 729bf44 Nov 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 729bf44 Nov 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = eedfc07

Please sign in to comment.