Skip to content

Commit 096ae80

Browse files
committed
Don't translate vtable methods with Self: Sized bounds.
1 parent e41cdab commit 096ae80

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/librustc/traits/object_safety.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
228228
/// otherwise ensure that they cannot be used when `Self=Trait`.
229229
pub fn is_vtable_safe_method(self,
230230
trait_def_id: DefId,
231-
method: &ty::Method<'tcx>)
231+
method: &ty::Method<'gcx>)
232232
-> bool
233233
{
234+
// Any method that has a `Self : Sized` requisite can't be called.
235+
if self.generics_require_sized_self(&method.generics, &method.predicates) {
236+
return false;
237+
}
238+
234239
self.virtual_call_violation_for_method(trait_def_id, method).is_none()
235240
}
236241

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2016 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+
trait Future: 'static {
12+
// The requirement for Self: Sized must prevent instantiation of
13+
// Future::forget in vtables, otherwise there's an infinite type
14+
// recursion through <Map<...> as Future>::forget.
15+
fn forget(self) where Self: Sized {
16+
Box::new(Map(self)) as Box<Future>;
17+
}
18+
}
19+
20+
struct Map<A>(A);
21+
impl<A: Future> Future for Map<A> {}
22+
23+
pub struct Promise;
24+
impl Future for Promise {}
25+
26+
fn main() {
27+
Promise.forget();
28+
}

0 commit comments

Comments
 (0)