Skip to content

Commit d318235

Browse files
committed
---
yaml --- r: 274926 b: refs/heads/stable c: 36c00f8 h: refs/heads/master
1 parent c0b8912 commit d318235

File tree

10 files changed

+173
-104
lines changed

10 files changed

+173
-104
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: c0221c8897db309a79990367476177b1230bb264
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 6ba5d9cfd5a76deae0adc1e28260d9821a94a3a7
32+
refs/heads/stable: 36c00f810722b2e6aebe0c4db3d3d90ade7a32d3
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/doc/book/strings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ The second, with a `\`, trims the spaces and the newline:
3939

4040
```rust
4141
let s = "foo\
42-
bar";
42+
bar";
4343

4444
assert_eq!("foobar", s);
4545
```
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python2
2+
3+
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
4+
# file at the top-level directory of this distribution and at
5+
# http://rust-lang.org/COPYRIGHT.
6+
#
7+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10+
# option. This file may not be copied, modified, or distributed
11+
# except according to those terms.
12+
13+
from __future__ import absolute_import, division, print_function
14+
import argparse
15+
import datetime
16+
import os.path as path
17+
18+
19+
def print_tests(tests):
20+
print('\n'.join([test_tostr(t) for t in tests]))
21+
22+
23+
def read_tests(f):
24+
basename, _ = path.splitext(path.basename(f))
25+
tests = []
26+
for lineno, line in enumerate(open(f), 1):
27+
fields = filter(None, map(str.strip, line.split('\t')))
28+
if not (4 <= len(fields) <= 5) \
29+
or 'E' not in fields[0] or fields[0][0] == '#':
30+
continue
31+
32+
opts, pat, text, sgroups = fields[0:4]
33+
groups = [] # groups as integer ranges
34+
if sgroups == 'NOMATCH':
35+
groups = [None]
36+
elif ',' in sgroups:
37+
noparen = map(lambda s: s.strip('()'), sgroups.split(')('))
38+
for g in noparen:
39+
s, e = map(str.strip, g.split(','))
40+
if s == '?' and e == '?':
41+
groups.append(None)
42+
else:
43+
groups.append((int(s), int(e)))
44+
else:
45+
# This skips tests that should result in an error.
46+
# There aren't many, so I think we can just capture those
47+
# manually. Possibly fix this in future.
48+
continue
49+
50+
if pat == 'SAME':
51+
pat = tests[-1][1]
52+
if '$' in opts:
53+
pat = pat.decode('string_escape')
54+
text = text.decode('string_escape')
55+
if 'i' in opts:
56+
pat = '(?i)%s' % pat
57+
58+
name = '%s_%d' % (basename, lineno)
59+
tests.append((name, pat, text, groups))
60+
return tests
61+
62+
63+
def test_tostr(t):
64+
lineno, pat, text, groups = t
65+
options = map(group_tostr, groups)
66+
return 'mat!{match_%s, r"%s", r"%s", %s}' \
67+
% (lineno, pat, '' if text == "NULL" else text, ', '.join(options))
68+
69+
70+
def group_tostr(g):
71+
if g is None:
72+
return 'None'
73+
else:
74+
return 'Some((%d, %d))' % (g[0], g[1])
75+
76+
77+
if __name__ == '__main__':
78+
parser = argparse.ArgumentParser(
79+
description='Generate match tests from an AT&T POSIX test file.')
80+
aa = parser.add_argument
81+
aa('files', nargs='+',
82+
help='A list of dat AT&T POSIX test files. See src/libregexp/testdata')
83+
args = parser.parse_args()
84+
85+
tests = []
86+
for f in args.files:
87+
tests += read_tests(f)
88+
89+
tpl = '''// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
90+
// file at the top-level directory of this distribution and at
91+
// http://rust-lang.org/COPYRIGHT.
92+
//
93+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
94+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
95+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
96+
// option. This file may not be copied, modified, or distributed
97+
// except according to those terms.
98+
99+
// ignore-tidy-linelength
100+
101+
// DO NOT EDIT. Automatically generated by 'src/etc/regexp-match-tests'
102+
// on {date}.
103+
'''
104+
print(tpl.format(date=str(datetime.datetime.now())))
105+
106+
for f in args.files:
107+
print('// Tests from %s' % path.basename(f))
108+
print_tests(read_tests(f))
109+
print('')

branches/stable/src/libcore/num/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ macro_rules! int_impl {
479479
}
480480
}
481481

482-
/// Checked negation. Computes `!self`, returning `None` if `self ==
482+
/// Checked negation. Computes `-self`, returning `None` if `self ==
483483
/// MIN`.
484484
///
485485
/// # Examples

branches/stable/src/libcore/ptr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ pub unsafe fn read<T>(src: *const T) -> T {
127127
tmp
128128
}
129129

130-
#[allow(missing_docs)]
130+
/// Variant of read_and_zero that writes the specific drop-flag byte
131+
/// (which may be more appropriate than zero).
131132
#[inline(always)]
132133
#[unstable(feature = "filling_drop",
133134
reason = "may play a larger role in std::ptr future extensions",

branches/stable/src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3828,7 +3828,7 @@ impl<'tcx> Expectation<'tcx> {
38283828
/// for examples of where this comes up,.
38293829
fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
38303830
match tcx.struct_tail(ty).sty {
3831-
ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3831+
ty::TySlice(_) | ty::TyTrait(..) => {
38323832
ExpectRvalueLikeUnsized(ty)
38333833
}
38343834
_ => ExpectHasType(ty)

branches/stable/src/libstd/fs.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,26 +2151,6 @@ mod tests {
21512151
"foo");
21522152
}
21532153

2154-
#[test]
2155-
fn read_link() {
2156-
if cfg!(windows) {
2157-
// directory symlink
2158-
assert_eq!(check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(),
2159-
r"C:\ProgramData");
2160-
// junction
2161-
assert_eq!(check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(),
2162-
r"C:\Users\Default");
2163-
// junction with special permissions
2164-
assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(),
2165-
r"C:\Users");
2166-
}
2167-
let tmpdir = tmpdir();
2168-
let link = tmpdir.join("link");
2169-
if !got_symlink_permission(&tmpdir) { return };
2170-
check!(symlink_file(&"foo", &link));
2171-
assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo");
2172-
}
2173-
21742154
#[test]
21752155
fn readlink_not_symlink() {
21762156
let tmpdir = tmpdir();

branches/stable/src/libstd/sys/windows/c.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
240240
pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
241241
pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
242242
pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
243-
pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
244243
pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
245244
pub const FSCTL_DELETE_REPARSE_POINT: DWORD = 0x900ac;
246245

@@ -534,15 +533,6 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
534533
pub PathBuffer: WCHAR,
535534
}
536535

537-
#[repr(C)]
538-
pub struct MOUNT_POINT_REPARSE_BUFFER {
539-
pub SubstituteNameOffset: c_ushort,
540-
pub SubstituteNameLength: c_ushort,
541-
pub PrintNameOffset: c_ushort,
542-
pub PrintNameLength: c_ushort,
543-
pub PathBuffer: WCHAR,
544-
}
545-
546536
pub type LPPROGRESS_ROUTINE = ::option::Option<unsafe extern "system" fn(
547537
TotalFileSize: LARGE_INTEGER,
548538
TotalBytesTransferred: LARGE_INTEGER,

branches/stable/src/libstd/sys/windows/fs.rs

Lines changed: 58 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,7 @@ impl DirEntry {
150150
nFileSizeHigh: self.data.nFileSizeHigh,
151151
nFileSizeLow: self.data.nFileSizeLow,
152152
},
153-
reparse_tag: if self.data.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
154-
// reserved unless this is a reparse point
155-
self.data.dwReserved0
156-
} else {
157-
0
158-
},
153+
reparse_tag: self.data.dwReserved0,
159154
})
160155
}
161156
}
@@ -245,6 +240,15 @@ impl OpenOptions {
245240
}
246241

247242
impl File {
243+
fn open_reparse_point(path: &Path, write: bool) -> io::Result<File> {
244+
let mut opts = OpenOptions::new();
245+
opts.read(!write);
246+
opts.write(write);
247+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
248+
c::FILE_FLAG_BACKUP_SEMANTICS);
249+
File::open(path, &opts)
250+
}
251+
248252
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
249253
let path = try!(to_u16s(path));
250254
let handle = unsafe {
@@ -367,34 +371,19 @@ impl File {
367371
fn readlink(&self) -> io::Result<PathBuf> {
368372
let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
369373
let (_bytes, buf) = try!(self.reparse_point(&mut space));
374+
if buf.ReparseTag != c::IO_REPARSE_TAG_SYMLINK {
375+
return Err(io::Error::new(io::ErrorKind::Other, "not a symlink"))
376+
}
377+
370378
unsafe {
371-
let (path_buffer, subst_off, subst_len, relative) = match buf.ReparseTag {
372-
c::IO_REPARSE_TAG_SYMLINK => {
373-
let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
374-
&buf.rest as *const _ as *const _;
375-
(&(*info).PathBuffer as *const _ as *const u16,
376-
(*info).SubstituteNameOffset / 2,
377-
(*info).SubstituteNameLength / 2,
378-
(*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0)
379-
},
380-
c::IO_REPARSE_TAG_MOUNT_POINT => {
381-
let info: *const c::MOUNT_POINT_REPARSE_BUFFER =
382-
&buf.rest as *const _ as *const _;
383-
(&(*info).PathBuffer as *const _ as *const u16,
384-
(*info).SubstituteNameOffset / 2,
385-
(*info).SubstituteNameLength / 2,
386-
false)
387-
},
388-
_ => return Err(io::Error::new(io::ErrorKind::Other,
389-
"Unsupported reparse point type"))
390-
};
379+
let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
380+
&buf.rest as *const _ as *const _;
381+
let path_buffer = &(*info).PathBuffer as *const _ as *const u16;
382+
let subst_off = (*info).SubstituteNameOffset / 2;
391383
let subst_ptr = path_buffer.offset(subst_off as isize);
392-
let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
393-
// Absolute paths start with an NT internal namespace prefix `\??\`
394-
// We should not let it leak through.
395-
if !relative && subst.starts_with(&[92u16, 63u16, 63u16, 92u16]) {
396-
subst = &subst[4..];
397-
}
384+
let subst_len = (*info).SubstituteNameLength / 2;
385+
let subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
386+
398387
Ok(PathBuf::from(OsString::from_wide(subst)))
399388
}
400389
}
@@ -588,15 +577,8 @@ fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
588577
rmdir(path)
589578
}
590579

591-
pub fn readlink(path: &Path) -> io::Result<PathBuf> {
592-
// Open the link with no access mode, instead of generic read.
593-
// By default FILE_LIST_DIRECTORY is denied for the junction "C:\Documents and Settings", so
594-
// this is needed for a common case.
595-
let mut opts = OpenOptions::new();
596-
opts.access_mode(0);
597-
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
598-
c::FILE_FLAG_BACKUP_SEMANTICS);
599-
let file = try!(File::open(&path, &opts));
580+
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
581+
let file = try!(File::open_reparse_point(p, false));
600582
file.readlink()
601583
}
602584

@@ -623,23 +605,42 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
623605
Ok(())
624606
}
625607

626-
pub fn stat(path: &Path) -> io::Result<FileAttr> {
627-
let mut opts = OpenOptions::new();
628-
// No read or write permissions are necessary
629-
opts.access_mode(0);
630-
// This flag is so we can open directories too
631-
opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
632-
let file = try!(File::open(path, &opts));
633-
file.file_attr()
608+
pub fn stat(p: &Path) -> io::Result<FileAttr> {
609+
let attr = try!(lstat(p));
610+
611+
// If this is a reparse point, then we need to reopen the file to get the
612+
// actual destination. We also pass the FILE_FLAG_BACKUP_SEMANTICS flag to
613+
// ensure that we can open directories (this path may be a directory
614+
// junction). Once the file is opened we ask the opened handle what its
615+
// metadata information is.
616+
if attr.is_reparse_point() {
617+
let mut opts = OpenOptions::new();
618+
// No read or write permissions are necessary
619+
opts.access_mode(0);
620+
// This flag is so we can open directories too
621+
opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
622+
let file = try!(File::open(p, &opts));
623+
file.file_attr()
624+
} else {
625+
Ok(attr)
626+
}
634627
}
635628

636-
pub fn lstat(path: &Path) -> io::Result<FileAttr> {
637-
let mut opts = OpenOptions::new();
638-
// No read or write permissions are necessary
639-
opts.access_mode(0);
640-
opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT);
641-
let file = try!(File::open(path, &opts));
642-
file.file_attr()
629+
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
630+
let u16s = try!(to_u16s(p));
631+
unsafe {
632+
let mut attr: FileAttr = mem::zeroed();
633+
try!(cvt(c::GetFileAttributesExW(u16s.as_ptr(),
634+
c::GetFileExInfoStandard,
635+
&mut attr.data as *mut _ as *mut _)));
636+
if attr.is_reparse_point() {
637+
attr.reparse_tag = File::open_reparse_point(p, false).and_then(|f| {
638+
let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
639+
f.reparse_point(&mut b).map(|(_, b)| b.ReparseTag)
640+
}).unwrap_or(0);
641+
}
642+
Ok(attr)
643+
}
643644
}
644645

645646
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
@@ -708,12 +709,7 @@ pub fn symlink_junction<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::R
708709
fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
709710
let d = DirBuilder::new();
710711
try!(d.mkdir(&junction));
711-
712-
let mut opts = OpenOptions::new();
713-
opts.write(true);
714-
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
715-
c::FILE_FLAG_BACKUP_SEMANTICS);
716-
let f = try!(File::open(junction, &opts));
712+
let f = try!(File::open_reparse_point(junction, true));
717713
let h = f.handle().raw();
718714

719715
unsafe {

branches/stable/src/test/run-pass/coerce-expect-unsized.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,6 @@ pub fn main() {
4444
let _: &Debug = &if true { false } else { true };
4545
let _: &Debug = &match true { true => 'a', false => 'b' };
4646

47-
let _: &str = &{ String::new() };
48-
let _: &str = &if true { String::from("...") } else { 5.to_string() };
49-
let _: &str = &match true {
50-
true => format!("{}", false),
51-
false => ["x", "y"].join("+")
52-
};
53-
5447
let _: Box<[isize]> = Box::new([1, 2, 3]);
5548
let _: Box<Fn(isize) -> _> = Box::new(|x| (x as u8));
5649

0 commit comments

Comments
 (0)