Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow coercions from [T, ..n] to &[T] #18645

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions src/librustc/middle/typeck/infer/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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]
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
}

Expand Down Expand Up @@ -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());
}
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/rand/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]) {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/rt/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/windows/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/sys/windows/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/sys/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
);
}
Expand Down
15 changes: 15 additions & 0 deletions src/test/compile-fail/coercion-slice.rs
Original file line number Diff line number Diff line change
@@ -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]`
}
6 changes: 3 additions & 3 deletions src/test/run-pass/tcp-stress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn main() {
}
};
stream.read_byte();
stream.write([2]);
stream.write(&[2]);
}
});
let addr = rx.recv();
Expand All @@ -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)
}
Expand Down