提交 7a372e23 编写于 作者: N Niko Matsakis

Require that objects can only be made from Sized types. Fixes #18333.

上级 dd5ce5ae
......@@ -94,6 +94,9 @@ pub enum ObligationCauseCode<'tcx> {
// Types of fields (other than the last) in a struct must be sized.
FieldSized,
// Only Sized types can be made into objects
ObjectSized,
}
pub type Obligations<'tcx> = subst::VecPerParamSpace<Obligation<'tcx>>;
......
......@@ -1771,12 +1771,13 @@ fn register_unsize_obligations(&self,
}
ty::UnsizeVtable(ref ty_trait, self_ty) => {
vtable::check_object_safety(self.tcx(), ty_trait, span);
// If the type is `Foo+'a`, ensures that the type
// being cast to `Foo+'a` implements `Foo`:
vtable::register_object_cast_obligations(self,
span,
ty_trait,
self_ty);
span,
ty_trait,
self_ty);
// If the type is `Foo+'a`, ensures that the type
// being cast to `Foo+'a` outlives `'a`:
......
......@@ -21,6 +21,7 @@
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::Span;
use util::common::ErrorReported;
use util::ppaux::{UserString, Repr, ty_to_string};
pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
......@@ -238,6 +239,20 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
referent_ty: Ty<'tcx>)
-> Rc<ty::TraitRef<'tcx>>
{
// We can only make objects from sized types.
let sized_obligation =
traits::obligation_for_builtin_bound(
fcx.tcx(),
traits::ObligationCause::new(span, traits::ObjectSized),
referent_ty,
ty::BoundSized);
match sized_obligation {
Ok(sized_obligation) => {
fcx.register_obligation(sized_obligation);
}
Err(ErrorReported) => { }
}
// This is just for better error reporting. Kinda goofy. The object type stuff
// needs some refactoring so there is a more convenient type to pass around.
let object_trait_ty =
......@@ -543,5 +558,9 @@ fn note_obligation_cause<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
"only the last field of a struct or enum variant \
may have a dynamically sized type")
}
traits::ObjectSized => {
span_note!(tcx.sess, obligation.cause.span,
"only sized types can be made into objects");
}
}
}
......@@ -20,7 +20,8 @@
use syntax::visit;
use syntax::visit::Visitor;
// An error has already been reported to the user, so no need to continue checking.
// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[deriving(Clone,Show)]
pub struct ErrorReported;
......
// 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.
// Test that we cannot create objects from unsized types.
trait Foo for Sized? {}
impl Foo for str {}
fn test<Sized? T: Foo>(t: &T) {
let u: &Foo = t;
//~^ ERROR `core::kinds::Sized` is not implemented for the type `T`
let v: &Foo = t as &Foo;
//~^ ERROR `core::kinds::Sized` is not implemented for the type `T`
}
fn main() {
let _: &[&Foo] = &["hi"];
//~^ ERROR `core::kinds::Sized` is not implemented for the type `str`
let _: &Foo = "hi" as &Foo;
//~^ ERROR `core::kinds::Sized` is not implemented for the type `str`
}
......@@ -11,5 +11,5 @@
fn main() {
let _x = "test" as &::std::any::Any;
//~^ ERROR the trait `core::kinds::Sized` is not implemented for the type `str`
//~^^ NOTE the trait `core::kinds::Sized` must be implemented for the cast to the object type
//~^^ ERROR the trait `core::kinds::Sized` is not implemented for the type `str`
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册