diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index df87d624e3a66..60808fbc741fb 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -82,7 +82,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let mut violations = vec![]; for def_id in traits::supertrait_def_ids(self, trait_def_id) { - if self.supertraits_reference_self(def_id) { + if self.predicates_reference_self(def_id, true) { violations.push(ObjectSafetyViolation::SupertraitSelf); } } @@ -117,7 +117,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if self.trait_has_sized_self(trait_def_id) { violations.push(ObjectSafetyViolation::SizedSelf); } - if self.supertraits_reference_self(trait_def_id) { + if self.predicates_reference_self(trait_def_id, false) { violations.push(ObjectSafetyViolation::SupertraitSelf); } @@ -128,12 +128,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { violations } - fn supertraits_reference_self(self, trait_def_id: DefId) -> bool { + fn predicates_reference_self( + self, + trait_def_id: DefId, + supertraits_only: bool) -> bool + { let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_def_id, substs: Substs::identity_for_item(self, trait_def_id) }); - let predicates = self.item_super_predicates(trait_def_id); + let predicates = if supertraits_only { + self.item_super_predicates(trait_def_id) + } else { + self.item_predicates(trait_def_id) + }; predicates .predicates .into_iter() diff --git a/src/test/compile-fail/issue-38604.rs b/src/test/compile-fail/issue-38604.rs new file mode 100644 index 0000000000000..c1939a7707f39 --- /dev/null +++ b/src/test/compile-fail/issue-38604.rs @@ -0,0 +1,26 @@ +// 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. + +trait Q {} +trait Foo where u32: Q { + fn foo(&self); +} + +impl Q<()> for u32 {} +impl Foo for () { + fn foo(&self) { + println!("foo!"); + } +} + +fn main() { + let _f: Box = //~ ERROR `Foo` cannot be made into an object + Box::new(()); //~ ERROR `Foo` cannot be made into an object +}