Skip to content

Commit 729bf44

Browse files
committed
Search for implemented kinds recursively on Trait types. Fixes #15155 and #13155.
1 parent 5ff10d5 commit 729bf44

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

src/librustc/middle/traits/select.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13271327
}
13281328
}
13291329

1330-
ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
1330+
ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
13311331
match bound {
13321332
ty::BoundSized => {
13331333
Err(Unimplemented)
@@ -1336,6 +1336,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13361336
if bounds.builtin_bounds.contains(&bound) {
13371337
Ok(If(Vec::new()))
13381338
} else {
1339+
// Recursively check all supertraits to find out if any further
1340+
// bounds are required and thus we must fulfill.
1341+
// We have to create a temp trait ref here since TyTraits don't
1342+
// have actual self type info (which is required for the
1343+
// supertraits iterator).
1344+
let tmp_tr = Rc::new(ty::TraitRef {
1345+
def_id: principal.def_id,
1346+
substs: principal.substs.with_self_ty(ty::mk_err())
1347+
});
1348+
for tr in util::supertraits(self.tcx(), tmp_tr) {
1349+
let td = ty::lookup_trait_def(self.tcx(), tr.def_id);
1350+
1351+
if td.bounds.builtin_bounds.contains(&bound) {
1352+
return Ok(If(Vec::new()))
1353+
}
1354+
}
1355+
13391356
Err(Unimplemented)
13401357
}
13411358
}

src/test/run-pass/issue-15155.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait TraitWithSend: Send {}
12+
trait IndirectTraitWithSend: TraitWithSend {}
13+
14+
// Check struct instantiation (Box<TraitWithSend> will only have Send if TraitWithSend has Send)
15+
#[allow(dead_code)]
16+
struct Blah { x: Box<TraitWithSend> }
17+
impl TraitWithSend for Blah {}
18+
19+
// Struct instantiation 2-levels deep
20+
#[allow(dead_code)]
21+
struct IndirectBlah { x: Box<IndirectTraitWithSend> }
22+
impl TraitWithSend for IndirectBlah {}
23+
impl IndirectTraitWithSend for IndirectBlah {}
24+
25+
fn test_trait<Sized? T: Send>() { println!("got here!") }
26+
27+
fn main() {
28+
test_trait::<TraitWithSend>();
29+
test_trait::<IndirectTraitWithSend>();
30+
}
31+
32+

0 commit comments

Comments
 (0)