about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/traits/select.rs19
-rw-r--r--src/test/run-pass/issue-15155.rs32
2 files changed, 50 insertions, 1 deletions
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 9cb7023e1b5..d1cc851c41f 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -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)
                         }
                     }
diff --git a/src/test/run-pass/issue-15155.rs b/src/test/run-pass/issue-15155.rs
new file mode 100644
index 00000000000..053a4916e22
--- /dev/null
+++ b/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>();
+}
+
+