diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 08a996c142d..738ed85ae6d 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2408,9 +2408,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // T -> Trait. (_, &ty::TyTrait(ref data)) => { - let object_did = data.principal_def_id(); - if !object_safety::is_object_safe(tcx, object_did) { - return Err(TraitNotObjectSafe(object_did)); + let mut object_dids = + data.bounds.builtin_bounds.iter().flat_map(|bound| { + tcx.lang_items.from_builtin_kind(bound).ok() + }) + .chain(Some(data.principal_def_id())); + if let Some(did) = object_dids.find(|did| { + !object_safety::is_object_safe(tcx, *did) + }) { + return Err(TraitNotObjectSafe(did)) } let cause = ObligationCause::new(obligation.cause.span, diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 2dda63802e0..316a81e8f62 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -301,6 +301,7 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> { /// is WF. Returns false if `ty0` is an unresolved type variable, /// in which case we are not able to simplify at all. fn compute(&mut self, ty0: Ty<'tcx>) -> bool { + let tcx = self.infcx.tcx; let mut subtys = ty0.walk(); while let Some(ty) = subtys.next() { match ty.sty { @@ -385,10 +386,20 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> { // checking those let cause = self.cause(traits::MiscObligation); - self.out.push( - traits::Obligation::new( - cause, - ty::Predicate::ObjectSafe(data.principal_def_id()))); + + let component_traits = + data.bounds.builtin_bounds.iter().flat_map(|bound| { + tcx.lang_items.from_builtin_kind(bound).ok() + }) + .chain(Some(data.principal_def_id())); + self.out.extend( + component_traits.map(|did| { + traits::Obligation::new( + cause.clone(), + ty::Predicate::ObjectSafe(did) + ) + }) + ); } // Inference variables are the complicated case, since we don't diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs index f62404e60e6..ba0a6f19f07 100644 --- a/src/test/compile-fail/bad-sized.rs +++ b/src/test/compile-fail/bad-sized.rs @@ -15,4 +15,5 @@ pub fn main() { //~^ ERROR `Trait + Sized: std::marker::Sized` is not satisfied //~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied //~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied + //~| ERROR `std::marker::Sized` cannot be made into an object } diff --git a/src/test/compile-fail/issue-32963.rs b/src/test/compile-fail/issue-32963.rs new file mode 100644 index 00000000000..d0434384cd0 --- /dev/null +++ b/src/test/compile-fail/issue-32963.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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. + +use std::mem; + +trait Misc {} + +fn size_of_copy() -> usize { mem::size_of::() } + +fn main() { + size_of_copy::(); + //~^ ERROR `std::marker::Copy` cannot be made into an object + //~| ERROR `Misc + Copy: std::marker::Copy` is not satisfied +} diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs index 08b4e1a45f3..747fe2d2046 100644 --- a/src/test/compile-fail/kindck-copy.rs +++ b/src/test/compile-fail/kindck-copy.rs @@ -45,15 +45,15 @@ fn test<'a,T,U:Copy>(_: &'a isize) { // borrowed object types are generally ok assert_copy::<&'a Dummy>(); - assert_copy::<&'a (Dummy+Copy)>(); - assert_copy::<&'static (Dummy+Copy)>(); + assert_copy::<&'a (Dummy+Send)>(); + assert_copy::<&'static (Dummy+Send)>(); // owned object types are not ok assert_copy::>(); //~ ERROR : std::marker::Copy` is not satisfied - assert_copy::>(); //~ ERROR : std::marker::Copy` is not satisfied + assert_copy::>(); //~ ERROR : std::marker::Copy` is not satisfied // mutable object types are not ok - assert_copy::<&'a mut (Dummy+Copy)>(); //~ ERROR : std::marker::Copy` is not satisfied + assert_copy::<&'a mut (Dummy+Send)>(); //~ ERROR : std::marker::Copy` is not satisfied // unsafe ptrs are ok assert_copy::<*const isize>();