Skip to content

Commit fd9f7da

Browse files
committed
Make traits with by-value-self be considered object safe.
1 parent fe512da commit fd9f7da

File tree

5 files changed

+44
-35
lines changed

5 files changed

+44
-35
lines changed

src/librustc/middle/traits/object_safety.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ pub enum ObjectSafetyViolation<'tcx> {
4242
/// Reasons a method might not be object-safe.
4343
#[derive(Copy,Clone,Debug)]
4444
pub enum MethodViolationCode {
45-
/// e.g., `fn(self)`
46-
ByValueSelf,
47-
4845
/// e.g., `fn foo()`
4946
StaticMethod,
5047

@@ -204,17 +201,15 @@ fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
204201
return None;
205202
}
206203

207-
// The method's first parameter must be something that derefs to
208-
// `&self`. For now, we only accept `&self` and `Box<Self>`.
204+
// The method's first parameter must be something that derefs (or
205+
// autorefs) to `&self`. For now, we only accept `self`, `&self`
206+
// and `Box<Self>`.
209207
match method.explicit_self {
210-
ty::ByValueExplicitSelfCategory => {
211-
return Some(MethodViolationCode::ByValueSelf);
212-
}
213-
214208
ty::StaticExplicitSelfCategory => {
215209
return Some(MethodViolationCode::StaticMethod);
216210
}
217211

212+
ty::ByValueExplicitSelfCategory |
218213
ty::ByReferenceExplicitSelfCategory(..) |
219214
ty::ByBoxExplicitSelfCategory => {
220215
}

src/librustc_typeck/check/vtable.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,6 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
133133
in the supertrait listing");
134134
}
135135

136-
ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
137-
tcx.sess.span_note(
138-
span,
139-
&format!("method `{}` has a receiver type of `Self`, \
140-
which cannot be used with a trait object",
141-
method.name.user_string(tcx)));
142-
}
143-
144136
ObjectSafetyViolation::Method(method, MethodViolationCode::StaticMethod) => {
145137
tcx.sess.span_note(
146138
span,

src/test/compile-fail/fn-trait-formatting.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
1515

1616
fn main() {
1717
let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
18-
//~^ ERROR object-safe
19-
//~| ERROR mismatched types
18+
//~^ ERROR mismatched types
2019
//~| expected `()`
2120
//~| found `Box<core::ops::FnOnce(isize)>`
2221
//~| expected ()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that while a trait with by-value self is object-safe, we
12+
// can't actually invoke it from an object (yet...?).
13+
14+
#![feature(rustc_attrs)]
15+
16+
trait Bar {
17+
fn bar(self);
18+
}
19+
20+
trait Baz {
21+
fn baz(self: Self);
22+
}
23+
24+
fn use_bar(t: Box<Bar>) {
25+
t.bar() //~ ERROR cannot move a value of type Bar
26+
}
27+
28+
fn main() { }
29+

src/test/compile-fail/object-safety-by-value-self.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Check that we correctly prevent users from making trait objects
12-
// from traits with a `fn(self)` method, unless `where Self : Sized`
13-
// is present on the method.
11+
// Check that a trait with by-value self is considered object-safe.
12+
13+
#![feature(rustc_attrs)]
14+
#![allow(dead_code)]
1415

1516
trait Bar {
1617
fn bar(self);
@@ -26,27 +27,19 @@ trait Quux {
2627
}
2728

2829
fn make_bar<T:Bar>(t: &T) -> &Bar {
29-
t
30-
//~^ ERROR `Bar` is not object-safe
31-
//~| NOTE method `bar` has a receiver type of `Self`
30+
t // legal
3231
}
3332

3433
fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
35-
t as &Bar
36-
//~^ ERROR `Bar` is not object-safe
37-
//~| NOTE method `bar` has a receiver type of `Self`
34+
t as &Bar // legal
3835
}
3936

4037
fn make_baz<T:Baz>(t: &T) -> &Baz {
41-
t
42-
//~^ ERROR `Baz` is not object-safe
43-
//~| NOTE method `baz` has a receiver type of `Self`
38+
t // legal
4439
}
4540

4641
fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
47-
t as &Baz
48-
//~^ ERROR `Baz` is not object-safe
49-
//~| NOTE method `baz` has a receiver type of `Self`
42+
t as &Baz // legal
5043
}
5144

5245
fn make_quux<T:Quux>(t: &T) -> &Quux {
@@ -57,5 +50,6 @@ fn make_quux_explicit<T:Quux>(t: &T) -> &Quux {
5750
t as &Quux
5851
}
5952

60-
fn main() {
53+
#[rustc_error]
54+
fn main() { //~ ERROR compilation successful
6155
}

0 commit comments

Comments
 (0)