提交 558f8d8e 编写于 作者: B bors

auto merge of #19539 : cmr/rust/18959, r=nikomatsakis

Closes #18959

Technically, this causes code that once compiled to no longer compile, but
that code probably never ran.

[breaking-change]

------------

Not quite sure the error message is good enough, I feel like it ought to tell you "because it inherits from non-object-safe trait Foo", so I've opened up a follow-up issue #19538
......@@ -1747,8 +1747,7 @@ fn register_unsize_obligations(&self,
self.register_unsize_obligations(span, &**u)
}
ty::UnsizeVtable(ref ty_trait, self_ty) => {
vtable::check_object_safety(self.tcx(), ty_trait, span);
vtable::check_object_safety(self.tcx(), &ty_trait.principal, span);
// If the type is `Foo+'a`, ensures that the type
// being cast to `Foo+'a` implements `Foo`:
vtable::register_object_cast_obligations(self,
......
......@@ -45,7 +45,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// Ensure that if ~T is cast to ~Trait, then T : Trait
push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
check_object_safety(fcx.tcx(), object_trait, source_expr.span);
check_object_safety(fcx.tcx(), &object_trait.principal, source_expr.span);
}
(&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty,
......@@ -69,7 +69,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
target_region,
referent_region);
check_object_safety(fcx.tcx(), object_trait, source_expr.span);
check_object_safety(fcx.tcx(), &object_trait.principal, source_expr.span);
}
}
......@@ -133,17 +133,32 @@ fn push_cast_obligation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// self by value, has no type parameters and does not use the `Self` type, except
// in self position.
pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
object_trait: &ty::TyTrait<'tcx>,
object_trait: &ty::TraitRef<'tcx>,
span: Span) {
let mut object = object_trait.clone();
if object.substs.types.len(SelfSpace) == 0 {
object.substs.types.push(SelfSpace, ty::mk_err());
}
let object = Rc::new(object);
for tr in traits::supertraits(tcx, object) {
check_object_safety_inner(tcx, &*tr, span);
}
}
fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
object_trait: &ty::TraitRef<'tcx>,
span: Span) {
// Skip the fn_once lang item trait since only the compiler should call
// `call_once` which is the method which takes self by value. What could go
// wrong?
match tcx.lang_items.fn_once_trait() {
Some(def_id) if def_id == object_trait.principal.def_id => return,
Some(def_id) if def_id == object_trait.def_id => return,
_ => {}
}
let trait_items = ty::trait_items(tcx, object_trait.principal.def_id);
let trait_items = ty::trait_items(tcx, object_trait.def_id);
let mut errors = Vec::new();
for item in trait_items.iter() {
......@@ -157,7 +172,7 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
let mut errors = errors.iter().flat_map(|x| x.iter()).peekable();
if errors.peek().is_some() {
let trait_name = ty::item_path_str(tcx, object_trait.principal.def_id);
let trait_name = ty::item_path_str(tcx, object_trait.def_id);
span_err!(tcx.sess, span, E0038,
"cannot convert to a trait object because trait `{}` is not object-safe",
trait_name);
......
// Copyright 2014 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.
pub trait Foo for Sized? { fn foo<T>(&self, ext_thing: &T); }
pub trait Bar for Sized?: Foo { }
impl<T: Foo> Bar for T { }
pub struct Thing;
impl Foo for Thing {
fn foo<T>(&self, _: &T) {}
}
#[inline(never)] fn foo(b: &Bar) { b.foo(&0u) }
fn main() {
let mut thing = Thing;
let test: &Bar = &mut thing; //~ ERROR cannot convert to a trait object because trait `Foo`
foo(test);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册