From cd31e6ff3987a1e0f94c64f31d6068c459126667 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 30 Dec 2014 18:30:53 +1300 Subject: [PATCH] Forbid static methods in object safe traits 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. --- src/librustc_typeck/check/vtable.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index ff16568aa63fc..8371247263987 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -166,11 +166,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>, method: &ty::Method<'tcx>) -> Vec { @@ -185,9 +187,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 => {}