mirror of https://github.com/rust-lang/rust.git
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
|
@ -2408,9 +2408,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
// T -> Trait.
|
// T -> Trait.
|
||||||
(_, &ty::TyTrait(ref data)) => {
|
(_, &ty::TyTrait(ref data)) => {
|
||||||
let object_did = data.principal_def_id();
|
let mut object_dids =
|
||||||
if !object_safety::is_object_safe(tcx, object_did) {
|
data.bounds.builtin_bounds.iter().flat_map(|bound| {
|
||||||
return Err(TraitNotObjectSafe(object_did));
|
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,
|
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,
|
/// is WF. Returns false if `ty0` is an unresolved type variable,
|
||||||
/// in which case we are not able to simplify at all.
|
/// in which case we are not able to simplify at all.
|
||||||
fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
|
fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
|
||||||
|
let tcx = self.infcx.tcx;
|
||||||
let mut subtys = ty0.walk();
|
let mut subtys = ty0.walk();
|
||||||
while let Some(ty) = subtys.next() {
|
while let Some(ty) = subtys.next() {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
|
@ -385,10 +386,20 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> {
|
||||||
// checking those
|
// checking those
|
||||||
|
|
||||||
let cause = self.cause(traits::MiscObligation);
|
let cause = self.cause(traits::MiscObligation);
|
||||||
self.out.push(
|
|
||||||
traits::Obligation::new(
|
let component_traits =
|
||||||
cause,
|
data.bounds.builtin_bounds.iter().flat_map(|bound| {
|
||||||
ty::Predicate::ObjectSafe(data.principal_def_id())));
|
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
|
// 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 `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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// borrowed object types are generally ok
|
||||||
assert_copy::<&'a Dummy>();
|
assert_copy::<&'a Dummy>();
|
||||||
assert_copy::<&'a (Dummy+Copy)>();
|
assert_copy::<&'a (Dummy+Send)>();
|
||||||
assert_copy::<&'static (Dummy+Copy)>();
|
assert_copy::<&'static (Dummy+Send)>();
|
||||||
|
|
||||||
// owned object types are not ok
|
// owned object types are not ok
|
||||||
assert_copy::<Box<Dummy>>(); //~ ERROR : std::marker::Copy` is not satisfied
|
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
|
// 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
|
// unsafe ptrs are ok
|
||||||
assert_copy::<*const isize>();
|
assert_copy::<*const isize>();
|
||||||
|
|
Loading…
Reference in New Issue