auto merge of #18645 : nick29581/rust/coercions-1, r=alexcrichton
r? (I realise this needs a rebase, but I will probably have to chop it up in order to land and I'd like to get r+ first so I can do that quicker)
This commit is contained in:
commit
516ece6ee4
10 changed files with 37 additions and 72 deletions
|
@ -93,27 +93,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
a.repr(self.get_ref().infcx.tcx),
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
// Special case: if the subtype is a sized array literal (`[T, ..n]`),
|
||||
// then it would get auto-borrowed to `&[T, ..n]` and then DST-ified
|
||||
// to `&[T]`. Doing it all at once makes the target code a bit more
|
||||
// efficient and spares us from having to handle multiple coercions.
|
||||
match ty::get(b).sty {
|
||||
ty::ty_ptr(mt_b) | ty::ty_rptr(_, mt_b) => {
|
||||
match ty::get(mt_b.ty).sty {
|
||||
ty::ty_vec(_, None) => {
|
||||
let unsize_and_ref = self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_unsized_with_borrow(a, sty_a, b, mt_b.mutbl)
|
||||
});
|
||||
if unsize_and_ref.is_ok() {
|
||||
return unsize_and_ref;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Consider coercing the subtype to a DST
|
||||
let unsize = self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_unsized(a, sty_a, b)
|
||||
|
@ -274,35 +253,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
})))
|
||||
}
|
||||
|
||||
// [T, ..n] -> &[T] or &mut [T]
|
||||
fn coerce_unsized_with_borrow(&self,
|
||||
a: ty::t,
|
||||
sty_a: &ty::sty,
|
||||
b: ty::t,
|
||||
mutbl_b: ast::Mutability)
|
||||
-> CoerceResult {
|
||||
debug!("coerce_unsized_with_borrow(a={}, sty_a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), sty_a,
|
||||
b.repr(self.get_ref().infcx.tcx));
|
||||
|
||||
match *sty_a {
|
||||
ty::ty_vec(t_a, Some(len)) => {
|
||||
let sub = Sub(self.get_ref().clone());
|
||||
let coercion = Coercion(self.get_ref().trace.clone());
|
||||
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
|
||||
let unsized_ty = ty::mk_slice(self.get_ref().infcx.tcx, r_borrow,
|
||||
mt {ty: t_a, mutbl: mutbl_b});
|
||||
try!(self.get_ref().infcx.try(|| sub.tys(unsized_ty, b)));
|
||||
Ok(Some(AdjustDerefRef(AutoDerefRef {
|
||||
autoderefs: 0,
|
||||
autoref: Some(ty::AutoPtr(r_borrow,
|
||||
mutbl_b,
|
||||
Some(box AutoUnsize(ty::UnsizeLength(len)))))
|
||||
})))
|
||||
}
|
||||
_ => Err(ty::terr_mismatch)
|
||||
}
|
||||
}
|
||||
|
||||
// &[T, ..n] or &mut [T, ..n] -> &[T]
|
||||
// or &mut [T, ..n] -> &mut [T]
|
||||
|
|
|
@ -140,7 +140,7 @@ pub fn getcwd() -> Path {
|
|||
panic!();
|
||||
}
|
||||
}
|
||||
Path::new(String::from_utf16(::str::truncate_utf16_at_nul(buf))
|
||||
Path::new(String::from_utf16(::str::truncate_utf16_at_nul(&buf))
|
||||
.expect("GetCurrentDirectoryW returned invalid UTF-16"))
|
||||
}
|
||||
|
||||
|
@ -2065,12 +2065,12 @@ mod tests {
|
|||
join_paths(input).unwrap().as_slice() == output.as_bytes()
|
||||
}
|
||||
|
||||
assert!(test_eq([], ""));
|
||||
assert!(test_eq([r"c:\windows", r"c:\"],
|
||||
assert!(test_eq(&[], ""));
|
||||
assert!(test_eq(&[r"c:\windows", r"c:\"],
|
||||
r"c:\windows;c:\"));
|
||||
assert!(test_eq(["", r"c:\windows", "", "", r"c:\", ""],
|
||||
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""],
|
||||
r";c:\windows;;;c:\;"));
|
||||
assert!(test_eq([r"c:\te;st", r"c:\"],
|
||||
assert!(test_eq(&[r"c:\te;st", r"c:\"],
|
||||
r#""c:\te;st";c:\"#));
|
||||
assert!(join_paths(&[r#"c:\te"st"#]).is_err());
|
||||
}
|
||||
|
|
|
@ -298,12 +298,12 @@ mod imp {
|
|||
impl Rng for OsRng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
let mut v = [0u8, .. 4];
|
||||
self.fill_bytes(v);
|
||||
self.fill_bytes(&mut v);
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
let mut v = [0u8, .. 8];
|
||||
self.fill_bytes(v);
|
||||
self.fill_bytes(&mut v);
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
|
|
|
@ -999,7 +999,7 @@ mod imp {
|
|||
None => try!(w.write(bytes[..bytes.len()-1])),
|
||||
}
|
||||
}
|
||||
try!(w.write(['\n' as u8]));
|
||||
try!(w.write(&['\n' as u8]));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -263,7 +263,7 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
|
|||
let mut more_files = 1 as libc::BOOL;
|
||||
while more_files != 0 {
|
||||
{
|
||||
let filename = str::truncate_utf16_at_nul(wfd.cFileName);
|
||||
let filename = str::truncate_utf16_at_nul(&wfd.cFileName);
|
||||
match String::from_utf16(filename) {
|
||||
Some(filename) => paths.push(Path::new(filename)),
|
||||
None => {
|
||||
|
|
|
@ -76,7 +76,7 @@ pub fn error_string(errnum: i32) -> String {
|
|||
return format!("OS Error {} (FormatMessageW() returned error {})", errnum, fm_err);
|
||||
}
|
||||
|
||||
let msg = String::from_utf16(::str::truncate_utf16_at_nul(buf));
|
||||
let msg = String::from_utf16(::str::truncate_utf16_at_nul(&buf));
|
||||
match msg {
|
||||
Some(msg) => format!("OS Error {}: {}", errnum, msg),
|
||||
None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum),
|
||||
|
|
|
@ -395,7 +395,7 @@ impl UnixStream {
|
|||
loop {
|
||||
// Process a timeout if one is pending
|
||||
let wait_succeeded = await(self.handle(), self.read_deadline,
|
||||
[overlapped.hEvent]);
|
||||
&[overlapped.hEvent]);
|
||||
|
||||
let ret = unsafe {
|
||||
libc::GetOverlappedResult(self.handle(),
|
||||
|
@ -459,7 +459,7 @@ impl UnixStream {
|
|||
}
|
||||
// Process a timeout if one is pending
|
||||
let wait_succeeded = await(self.handle(), self.write_deadline,
|
||||
[overlapped.hEvent]);
|
||||
&[overlapped.hEvent]);
|
||||
let ret = unsafe {
|
||||
libc::GetOverlappedResult(self.handle(),
|
||||
&mut overlapped,
|
||||
|
@ -660,8 +660,8 @@ impl UnixAcceptor {
|
|||
if err == libc::ERROR_IO_PENDING as libc::DWORD {
|
||||
// Process a timeout if one is pending
|
||||
let wait_succeeded = await(handle, self.deadline,
|
||||
[self.inner.abort.handle(),
|
||||
overlapped.hEvent]);
|
||||
&[self.inner.abort.handle(),
|
||||
overlapped.hEvent]);
|
||||
|
||||
// This will block until the overlapped I/O is completed. The
|
||||
// timeout was previously handled, so this will either block in
|
||||
|
|
|
@ -487,24 +487,24 @@ mod tests {
|
|||
}
|
||||
|
||||
assert_eq!(
|
||||
test_wrapper("prog", ["aaa", "bbb", "ccc"]),
|
||||
test_wrapper("prog", &["aaa", "bbb", "ccc"]),
|
||||
"prog aaa bbb ccc".to_string()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
test_wrapper("C:\\Program Files\\blah\\blah.exe", ["aaa"]),
|
||||
test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]),
|
||||
"\"C:\\Program Files\\blah\\blah.exe\" aaa".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
test_wrapper("C:\\Program Files\\test", ["aa\"bb"]),
|
||||
test_wrapper("C:\\Program Files\\test", &["aa\"bb"]),
|
||||
"\"C:\\Program Files\\test\" aa\\\"bb".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
test_wrapper("echo", ["a b c"]),
|
||||
test_wrapper("echo", &["a b c"]),
|
||||
"echo \"a b c\"".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
test_wrapper("\u03c0\u042f\u97f3\u00e6\u221e", []),
|
||||
test_wrapper("\u03c0\u042f\u97f3\u00e6\u221e", &[]),
|
||||
"\u03c0\u042f\u97f3\u00e6\u221e".to_string()
|
||||
);
|
||||
}
|
||||
|
|
15
src/test/compile-fail/coercion-slice.rs
Normal file
15
src/test/compile-fail/coercion-slice.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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.
|
||||
|
||||
// Tests that we forbid coercion from `[T, ..n]` to `&[T]`
|
||||
|
||||
fn main() {
|
||||
let _: &[int] = [0i]; //~ERROR: mismatched types: expected `&[int]`, found `[int, ..1]`
|
||||
}
|
|
@ -45,7 +45,7 @@ fn main() {
|
|||
}
|
||||
};
|
||||
stream.read_byte();
|
||||
stream.write([2]);
|
||||
stream.write(&[2]);
|
||||
}
|
||||
});
|
||||
let addr = rx.recv();
|
||||
|
@ -57,9 +57,9 @@ fn main() {
|
|||
match TcpStream::connect(addr) {
|
||||
Ok(stream) => {
|
||||
let mut stream = stream;
|
||||
stream.write([1]);
|
||||
stream.write(&[1]);
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(&mut buf);
|
||||
},
|
||||
Err(e) => debug!("{}", e)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue