diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-12-31 02:41:19 +0200 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-01-11 00:02:16 +0200 |
| commit | c85fb1933f0924401f89f935f8f0b436bf177b14 (patch) | |
| tree | 7753eb84ca36b9a2d6cc071aba851fd27654bf9e | |
| parent | 4f542f9e4fd3a78018194cd3438a14da6f90a9d2 (diff) | |
| download | rust-c85fb1933f0924401f89f935f8f0b436bf177b14.tar.gz rust-c85fb1933f0924401f89f935f8f0b436bf177b14.zip | |
forbid all self-referencing predicates
Fixes #38604 needs a crater run
| -rw-r--r-- | src/librustc/traits/object_safety.rs | 16 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-38604.rs | 26 |
2 files changed, 38 insertions, 4 deletions
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index df87d624e3a..60808fbc741 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 00000000000..c1939a7707f --- /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 <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 Q<T:?Sized> {} +trait Foo where u32: Q<Self> { + fn foo(&self); +} + +impl Q<()> for u32 {} +impl Foo for () { + fn foo(&self) { + println!("foo!"); + } +} + +fn main() { + let _f: Box<Foo> = //~ ERROR `Foo` cannot be made into an object + Box::new(()); //~ ERROR `Foo` cannot be made into an object +} |
