auto merge of #16917 : nick29581/rust/cross-trait, r=pcwalton
Closes #15349 r? @pcwalton (or anyone else)
This commit is contained in:
commit
f7ec95efbb
@ -640,7 +640,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
|
|||||||
while !popped_scopes.is_empty() {
|
while !popped_scopes.is_empty() {
|
||||||
let mut scope = popped_scopes.pop().unwrap();
|
let mut scope = popped_scopes.pop().unwrap();
|
||||||
|
|
||||||
if scope.cleanups.iter().any(|c| cleanup_is_suitable_for(*c, label))
|
if scope.cleanups.iter().any(|c| cleanup_is_suitable_for(&**c, label))
|
||||||
{
|
{
|
||||||
let name = scope.block_name("clean");
|
let name = scope.block_name("clean");
|
||||||
debug!("generating cleanups for {}", name);
|
debug!("generating cleanups for {}", name);
|
||||||
@ -649,7 +649,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
|
|||||||
None);
|
None);
|
||||||
let mut bcx_out = bcx_in;
|
let mut bcx_out = bcx_in;
|
||||||
for cleanup in scope.cleanups.iter().rev() {
|
for cleanup in scope.cleanups.iter().rev() {
|
||||||
if cleanup_is_suitable_for(*cleanup, label) {
|
if cleanup_is_suitable_for(&**cleanup, label) {
|
||||||
bcx_out = cleanup.trans(bcx_out);
|
bcx_out = cleanup.trans(bcx_out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,6 +451,8 @@ impl Datum<Expr> {
|
|||||||
name: &str,
|
name: &str,
|
||||||
expr_id: ast::NodeId)
|
expr_id: ast::NodeId)
|
||||||
-> DatumBlock<'a, Lvalue> {
|
-> DatumBlock<'a, Lvalue> {
|
||||||
|
debug!("to_lvalue_datum self: {}", self.to_string(bcx.ccx()));
|
||||||
|
|
||||||
assert!(ty::lltype_is_sized(bcx.tcx(), self.ty),
|
assert!(ty::lltype_is_sized(bcx.tcx(), self.ty),
|
||||||
"Trying to convert unsized value to lval");
|
"Trying to convert unsized value to lval");
|
||||||
self.match_kind(
|
self.match_kind(
|
||||||
|
@ -2061,11 +2061,17 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
|
|||||||
if ty::type_is_sized(bcx.tcx(), content_ty) {
|
if ty::type_is_sized(bcx.tcx(), content_ty) {
|
||||||
deref_owned_pointer(bcx, expr, datum, content_ty)
|
deref_owned_pointer(bcx, expr, datum, content_ty)
|
||||||
} else {
|
} else {
|
||||||
// A fat pointer and an opened DST value have the same represenation
|
// A fat pointer and an opened DST value have the same
|
||||||
// just different types.
|
// represenation just different types. Since there is no
|
||||||
DatumBlock::new(bcx, Datum::new(datum.val,
|
// temporary for `*e` here (because it is unsized), we cannot
|
||||||
ty::mk_open(bcx.tcx(), content_ty),
|
// emulate the sized object code path for running drop glue and
|
||||||
datum.kind))
|
// free. Instead, we schedule cleanup for `e`, turning it into
|
||||||
|
// an lvalue.
|
||||||
|
let datum = unpack_datum!(
|
||||||
|
bcx, datum.to_lvalue_datum(bcx, "deref", expr.id));
|
||||||
|
|
||||||
|
let datum = Datum::new(datum.val, ty::mk_open(bcx.tcx(), content_ty), LvalueExpr);
|
||||||
|
DatumBlock::new(bcx, datum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2094,7 +2100,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
|
|||||||
// just different types.
|
// just different types.
|
||||||
DatumBlock::new(bcx, Datum::new(datum.val,
|
DatumBlock::new(bcx, Datum::new(datum.val,
|
||||||
ty::mk_open(bcx.tcx(), content_ty),
|
ty::mk_open(bcx.tcx(), content_ty),
|
||||||
datum.kind))
|
LvalueExpr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,6 @@ impl<'f> Coerce<'f> {
|
|||||||
|
|
||||||
let sty_b = &ty::get(b).sty;
|
let sty_b = &ty::get(b).sty;
|
||||||
match (sty_a, sty_b) {
|
match (sty_a, sty_b) {
|
||||||
(&ty::ty_uniq(_), &ty::ty_rptr(..)) => Err(ty::terr_mismatch),
|
|
||||||
(&ty::ty_rptr(_, ty::mt{ty: t_a, ..}), &ty::ty_rptr(_, mt_b)) => {
|
(&ty::ty_rptr(_, ty::mt{ty: t_a, ..}), &ty::ty_rptr(_, mt_b)) => {
|
||||||
self.unpack_actual_value(t_a, |sty_a| {
|
self.unpack_actual_value(t_a, |sty_a| {
|
||||||
match self.unsize_ty(sty_a, mt_b.ty) {
|
match self.unsize_ty(sty_a, mt_b.ty) {
|
||||||
@ -511,7 +510,7 @@ impl<'f> Coerce<'f> {
|
|||||||
let tcx = self.get_ref().infcx.tcx;
|
let tcx = self.get_ref().infcx.tcx;
|
||||||
|
|
||||||
match *sty_a {
|
match *sty_a {
|
||||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
|
ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
|
||||||
ty::ty_trait(box ty::TyTrait {
|
ty::ty_trait(box ty::TyTrait {
|
||||||
def_id,
|
def_id,
|
||||||
ref substs,
|
ref substs,
|
||||||
|
@ -570,7 +570,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
|
|||||||
n => {
|
n => {
|
||||||
let f: Callback = unsafe { mem::transmute(n) };
|
let f: Callback = unsafe { mem::transmute(n) };
|
||||||
let (file, line) = *file_line;
|
let (file, line) = *file_line;
|
||||||
f(msg, file, line);
|
f(&*msg, file, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -81,7 +81,7 @@ pub fn on_fail(obj: &Any + Send, file: &'static str, line: uint) {
|
|||||||
"task '{}' failed at '{}', {}:{}\n",
|
"task '{}' failed at '{}', {}:{}\n",
|
||||||
n, msg, file, line);
|
n, msg, file, line);
|
||||||
if backtrace::log_enabled() {
|
if backtrace::log_enabled() {
|
||||||
let _ = backtrace::write(stderr);
|
let _ = backtrace::write(&mut *stderr);
|
||||||
}
|
}
|
||||||
local_stderr.replace(Some(stderr));
|
local_stderr.replace(Some(stderr));
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) {
|
|||||||
let mut my_stdout = local_stdout.replace(None).unwrap_or_else(|| {
|
let mut my_stdout = local_stdout.replace(None).unwrap_or_else(|| {
|
||||||
box stdout() as Box<Writer + Send>
|
box stdout() as Box<Writer + Send>
|
||||||
});
|
});
|
||||||
let result = f(my_stdout);
|
let result = f(&mut *my_stdout);
|
||||||
local_stdout.replace(Some(my_stdout));
|
local_stdout.replace(Some(my_stdout));
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
|
@ -351,7 +351,7 @@ impl<'a> Parser<'a> {
|
|||||||
mut rdr: Box<Reader+'a>)
|
mut rdr: Box<Reader+'a>)
|
||||||
-> Parser<'a>
|
-> Parser<'a>
|
||||||
{
|
{
|
||||||
let tok0 = real_token(rdr);
|
let tok0 = real_token(&mut *rdr);
|
||||||
let span = tok0.sp;
|
let span = tok0.sp;
|
||||||
let placeholder = TokenAndSpan {
|
let placeholder = TokenAndSpan {
|
||||||
tok: token::UNDERSCORE,
|
tok: token::UNDERSCORE,
|
||||||
@ -899,7 +899,7 @@ impl<'a> Parser<'a> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
let next = if self.buffer_start == self.buffer_end {
|
let next = if self.buffer_start == self.buffer_end {
|
||||||
real_token(self.reader)
|
real_token(&mut *self.reader)
|
||||||
} else {
|
} else {
|
||||||
// Avoid token copies with `replace`.
|
// Avoid token copies with `replace`.
|
||||||
let buffer_start = self.buffer_start as uint;
|
let buffer_start = self.buffer_start as uint;
|
||||||
@ -943,7 +943,7 @@ impl<'a> Parser<'a> {
|
|||||||
-> R {
|
-> R {
|
||||||
let dist = distance as int;
|
let dist = distance as int;
|
||||||
while self.buffer_length() < dist {
|
while self.buffer_length() < dist {
|
||||||
self.buffer[self.buffer_end as uint] = real_token(self.reader);
|
self.buffer[self.buffer_end as uint] = real_token(&mut *self.reader);
|
||||||
self.buffer_end = (self.buffer_end + 1) & 3;
|
self.buffer_end = (self.buffer_end + 1) & 3;
|
||||||
}
|
}
|
||||||
f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
|
f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
|
||||||
|
22
src/test/compile-fail/cross-borrow-trait.rs
Normal file
22
src/test/compile-fail/cross-borrow-trait.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2012-2013-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.
|
||||||
|
|
||||||
|
// Test that cross-borrowing (implicitly converting from `Box<T>` to `&T`) is
|
||||||
|
// forbidden when `T` is a trait.
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
trait Trait {}
|
||||||
|
impl Trait for Foo {}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let x: Box<Trait> = box Foo;
|
||||||
|
let _y: &Trait = x; //~ ERROR mismatched types: expected `&Trait`, found `Box<Trait>`
|
||||||
|
}
|
||||||
|
|
@ -16,19 +16,19 @@ trait X {}
|
|||||||
impl<'a, T> X for B<'a, T> {}
|
impl<'a, T> X for B<'a, T> {}
|
||||||
|
|
||||||
fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
|
fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
|
||||||
box B(v) as Box<X>
|
box B(&*v) as Box<X>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn g<'a, T: 'static>(v: Box<A<T>>) -> Box<X+'static> {
|
fn g<'a, T: 'static>(v: Box<A<T>>) -> Box<X+'static> {
|
||||||
box B(v) as Box<X> //~ ERROR cannot infer
|
box B(&*v) as Box<X> //~ ERROR cannot infer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
|
fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
|
||||||
box B(v) as Box<X>
|
box B(&*v) as Box<X>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn i<'a, T, U>(v: Box<A<U>>) -> Box<X+'static> {
|
fn i<'a, T, U>(v: Box<A<U>>) -> Box<X+'static> {
|
||||||
box B(v) as Box<X> //~ ERROR cannot infer
|
box B(&*v) as Box<X> //~ ERROR cannot infer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -29,7 +29,7 @@ impl Trait for Foo {}
|
|||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
{
|
{
|
||||||
let _x: &Trait = box Foo as Box<Trait>;
|
let _x: &Trait = &*(box Foo as Box<Trait>);
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(DROP_RAN);
|
assert!(DROP_RAN);
|
||||||
|
@ -36,5 +36,5 @@ pub fn main() {
|
|||||||
let s: Box<S> = box S { s: 5 };
|
let s: Box<S> = box S { s: 5 };
|
||||||
print_s(&*s);
|
print_s(&*s);
|
||||||
let t: Box<T> = s as Box<T>;
|
let t: Box<T> = s as Box<T>;
|
||||||
print_t(t);
|
print_t(&*t);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ impl Trait for Struct {
|
|||||||
|
|
||||||
fn g(x: Box<Trait>) {
|
fn g(x: Box<Trait>) {
|
||||||
x.printme();
|
x.printme();
|
||||||
let y: &Trait = x;
|
let y: &Trait = &*x;
|
||||||
y.printme();
|
y.printme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ pub fn main() {
|
|||||||
assert_eq!(field_invoke2(&s2), 3);
|
assert_eq!(field_invoke2(&s2), 3);
|
||||||
|
|
||||||
let m : Box<Trait> = make_val();
|
let m : Box<Trait> = make_val();
|
||||||
assert_eq!(object_invoke1(m), (4,5));
|
assert_eq!(object_invoke1(&*m), (4,5));
|
||||||
assert_eq!(object_invoke2(m), 5);
|
assert_eq!(object_invoke2(&*m), 5);
|
||||||
|
|
||||||
// The RefMakerTrait above is pretty strange (i.e. it is strange
|
// The RefMakerTrait above is pretty strange (i.e. it is strange
|
||||||
// to consume a value of type T and return a &T). Easiest thing
|
// to consume a value of type T and return a &T). Easiest thing
|
||||||
|
Loading…
Reference in New Issue
Block a user