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
This commit is contained in:
parent
0a6dfc5177
commit
2f8f256cef
5 changed files with 50 additions and 11 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
21
src/test/compile-fail/issue-32963.rs
Normal file
21
src/test/compile-fail/issue-32963.rs
Normal file
|
@ -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 <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.
|
||||
|
||||
use std::mem;
|
||||
|
||||
trait Misc {}
|
||||
|
||||
fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
|
||||
|
||||
fn main() {
|
||||
size_of_copy::<Misc+Copy>();
|
||||
//~^ ERROR `std::marker::Copy` cannot be made into an object
|
||||
//~| ERROR `Misc + Copy: std::marker::Copy` is not satisfied
|
||||
}
|
|
@ -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::<Box<Dummy>>(); //~ ERROR : std::marker::Copy` is not satisfied
|
||||
assert_copy::<Box<Dummy+Copy>>(); //~ ERROR : std::marker::Copy` is not satisfied
|
||||
assert_copy::<Box<Dummy+Send>>(); //~ 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>();
|
||||
|
|
Loading…
Add table
Reference in a new issue