mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-20 02:43:45 +00:00
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:
commit
d058520f06
@ -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 => {}
|
||||
|
26
src/test/compile-fail/trait-object-safety.rs
Normal file
26
src/test/compile-fail/trait-object-safety.rs
Normal 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
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user