From 729bf447ab51887a8775ebc544b51f5549424b73 Mon Sep 17 00:00:00 2001 From: Ricky Taylor Date: Sun, 16 Nov 2014 18:20:19 +0000 Subject: [PATCH] Search for implemented kinds recursively on Trait types. Fixes #15155 and #13155. --- src/librustc/middle/traits/select.rs | 19 ++++++++++++++++- src/test/run-pass/issue-15155.rs | 32 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-15155.rs 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 or the MIT license +// , 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 will only have Send if TraitWithSend has Send) +#[allow(dead_code)] +struct Blah { x: Box } +impl TraitWithSend for Blah {} + +// Struct instantiation 2-levels deep +#[allow(dead_code)] +struct IndirectBlah { x: Box } +impl TraitWithSend for IndirectBlah {} +impl IndirectTraitWithSend for IndirectBlah {} + +fn test_trait() { println!("got here!") } + +fn main() { + test_trait::(); + test_trait::(); +} + +