rollup merge of #20325: nick29581/obj-safety-static

Closes #19949 and rust-lang/rfcs#428

[breaking change]

If you have traits used with objects with static methods, you'll need to move
the static methods to a different trait.

r? @cmr
This commit is contained in:
Alex Crichton 2014-12-30 16:26:11 -08:00
commit d058520f06
3 changed files with 40 additions and 11 deletions

View File

@ -190,11 +190,13 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
}
}
/// Returns a vec of error messages. If hte vec is empty - no errors!
/// Returns a vec of error messages. If the vec is empty - no errors!
///
/// There are some limitations to calling functions through an object, because (a) the self
/// type is not known (that's the whole point of a trait instance, after all, to obscure the
/// self type) and (b) the call must go through a vtable and hence cannot be monomorphized.
/// self type), (b) the call must go through a vtable and hence cannot be monomorphized and
/// (c) the trait contains static methods which can't be called because we don't know the
/// concrete type.
fn check_object_safety_of_method<'tcx>(tcx: &ty::ctxt<'tcx>,
object_trait: &ty::PolyTraitRef<'tcx>,
method: &ty::Method<'tcx>)
@ -210,9 +212,11 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
}
ty::StaticExplicitSelfCategory => {
// Static methods are always object-safe since they
// can't be called through a trait object
return msgs
// Static methods are never object safe (reason (c)).
msgs.push(format!("cannot call a static method (`{}`) \
through a trait object",
method_name));
return msgs;
}
ty::ByReferenceExplicitSelfCategory(..) |
ty::ByBoxExplicitSelfCategory => {}

View File

@ -0,0 +1,26 @@
// 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.
// Check that static methods are not object-safe.
trait Tr {
fn foo();
}
struct St;
impl Tr for St {
fn foo() {}
}
fn main() {
let _: &Tr = &St; //~ ERROR cannot convert to a trait object because trait `Tr` is not
//~^ NOTE cannot call a static method (`foo`) through a trait object
}

View File

@ -8,20 +8,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that object-safe methods are identified as such. Also
// acts as a regression test for #18490
// Check that object-safe methods are identified as such.
trait Tr {
// Static methods are always safe regardless of other rules
fn new() -> Self;
fn foo(&self);
}
struct St;
impl Tr for St {
fn new() -> St { St }
fn foo(&self) {}
}
fn main() {
&St as &Tr;
let s: &Tr = &St;
s.foo();
}