Skip to content

Commit 2f8f256

Browse files
committed
require the existential bounds of an object type to be object-safe
This is required, as Copy and Sized are object-unsafe. As a soundness fix, this is a [breaking-change] Fixes #32963
1 parent 0a6dfc5 commit 2f8f256

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

src/librustc/traits/select.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,9 +2408,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24082408

24092409
// T -> Trait.
24102410
(_, &ty::TyTrait(ref data)) => {
2411-
let object_did = data.principal_def_id();
2412-
if !object_safety::is_object_safe(tcx, object_did) {
2413-
return Err(TraitNotObjectSafe(object_did));
2411+
let mut object_dids =
2412+
data.bounds.builtin_bounds.iter().flat_map(|bound| {
2413+
tcx.lang_items.from_builtin_kind(bound).ok()
2414+
})
2415+
.chain(Some(data.principal_def_id()));
2416+
if let Some(did) = object_dids.find(|did| {
2417+
!object_safety::is_object_safe(tcx, *did)
2418+
}) {
2419+
return Err(TraitNotObjectSafe(did))
24142420
}
24152421

24162422
let cause = ObligationCause::new(obligation.cause.span,

src/librustc/ty/wf.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> {
301301
/// is WF. Returns false if `ty0` is an unresolved type variable,
302302
/// in which case we are not able to simplify at all.
303303
fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
304+
let tcx = self.infcx.tcx;
304305
let mut subtys = ty0.walk();
305306
while let Some(ty) = subtys.next() {
306307
match ty.sty {
@@ -385,10 +386,20 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> {
385386
// checking those
386387

387388
let cause = self.cause(traits::MiscObligation);
388-
self.out.push(
389-
traits::Obligation::new(
390-
cause,
391-
ty::Predicate::ObjectSafe(data.principal_def_id())));
389+
390+
let component_traits =
391+
data.bounds.builtin_bounds.iter().flat_map(|bound| {
392+
tcx.lang_items.from_builtin_kind(bound).ok()
393+
})
394+
.chain(Some(data.principal_def_id()));
395+
self.out.extend(
396+
component_traits.map(|did| {
397+
traits::Obligation::new(
398+
cause.clone(),
399+
ty::Predicate::ObjectSafe(did)
400+
)
401+
})
402+
);
392403
}
393404

394405
// Inference variables are the complicated case, since we don't

src/test/compile-fail/bad-sized.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ pub fn main() {
1515
//~^ ERROR `Trait + Sized: std::marker::Sized` is not satisfied
1616
//~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied
1717
//~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied
18+
//~| ERROR `std::marker::Sized` cannot be made into an object
1819
}

src/test/compile-fail/issue-32963.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::mem;
12+
13+
trait Misc {}
14+
15+
fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
16+
17+
fn main() {
18+
size_of_copy::<Misc+Copy>();
19+
//~^ ERROR `std::marker::Copy` cannot be made into an object
20+
//~| ERROR `Misc + Copy: std::marker::Copy` is not satisfied
21+
}

src/test/compile-fail/kindck-copy.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ fn test<'a,T,U:Copy>(_: &'a isize) {
4545

4646
// borrowed object types are generally ok
4747
assert_copy::<&'a Dummy>();
48-
assert_copy::<&'a (Dummy+Copy)>();
49-
assert_copy::<&'static (Dummy+Copy)>();
48+
assert_copy::<&'a (Dummy+Send)>();
49+
assert_copy::<&'static (Dummy+Send)>();
5050

5151
// owned object types are not ok
5252
assert_copy::<Box<Dummy>>(); //~ ERROR : std::marker::Copy` is not satisfied
53-
assert_copy::<Box<Dummy+Copy>>(); //~ ERROR : std::marker::Copy` is not satisfied
53+
assert_copy::<Box<Dummy+Send>>(); //~ ERROR : std::marker::Copy` is not satisfied
5454

5555
// mutable object types are not ok
56-
assert_copy::<&'a mut (Dummy+Copy)>(); //~ ERROR : std::marker::Copy` is not satisfied
56+
assert_copy::<&'a mut (Dummy+Send)>(); //~ ERROR : std::marker::Copy` is not satisfied
5757

5858
// unsafe ptrs are ok
5959
assert_copy::<*const isize>();

0 commit comments

Comments
 (0)