There is more that could be done, but this was the low hanging fruit.
ifdef CFG_WINDOWSY_$(CFG_BUILD)
-dist: dist-win
+dist: dist-win dist-tar-bins
distcheck: distcheck-win
$(Q)rm -Rf tmp/distcheck
for c in exitcode_out.as_slice().chars() {
if !c.is_digit() { break; }
exitcode = exitcode * 10 + match c {
- '0' .. '9' => c as int - ('0' as int),
+ '0' ... '9' => c as int - ('0' as int),
_ => 101,
}
}
}
```
-You can match a range of values with `..`:
+You can match a range of values with `...`:
```{rust}
let x = 1i;
match x {
- 1 .. 5 => println!("one through five"),
+ 1 ... 5 => println!("one through five"),
_ => println!("anything"),
}
```
Ranges are mostly used with integers and single characters.
-If you're matching multiple things, via a `|` or a `..`, you can bind
+If you're matching multiple things, via a `|` or a `...`, you can bind
the value to a name with `@`:
```{rust}
let x = 1i;
match x {
- x @ 1 .. 5 => println!("got {}", x),
+ x @ 1 ... 5 => println!("got {}", x),
_ => println!("anything"),
}
```
* `default_type_params` - Allows use of default type parameters. The future of
this feature is uncertain.
+* `if_let` - Allows use of the `if let` syntax.
+
* `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics
are inherently unstable and no promise about them is made.
if_expr : "if" no_struct_literal_expr '{' block '}'
else_tail ? ;
-else_tail : "else" [ if_expr
+else_tail : "else" [ if_expr | if_let_expr
| '{' block '}' ] ;
```
let message = match x {
0 | 1 => "not many",
- 2 .. 9 => "a few",
+ 2 ... 9 => "a few",
_ => "lots"
};
```
};
```
+### If let expressions
+
+```{.ebnf .gram}
+if_let_expr : "if" "let" pat '=' expr '{' block '}'
+ else_tail ? ;
+else_tail : "else" [ if_expr | if_let_expr | '{' block '}' ] ;
+```
+
+An `if let` expression is semantically identical to an `if` expression but in place
+of a condition expression it expects a refutable let statement. If the value of the
+expression on the right hand side of the let statement matches the pattern, the corresponding
+block will execute, otherwise flow proceeds to the first `else` block that follows.
+
### Return expressions
```{.ebnf .gram}
(move-to-column column)
(point))))
-;;; TODO: Maybe add an ERT explainer function (something that shows the
+;;; FIXME: Maybe add an ERT explainer function (something that shows the
;;; surrounding code of the final point, not just the position).
(defun rust-test-motion (source-code init-pos final-pos manip-func &optional &rest args)
"Test that MANIP-FUNC moves point from INIT-POS to FINAL-POS.
if [ -z "${CFG_UNINSTALL}" ]
then
msg "verifying platform can run binaries"
- export $CFG_LD_PATH_VAR="${CFG_SRC_DIR}/lib":$CFG_OLD_LD_PATH_VAR
+ export $CFG_LD_PATH_VAR="${CFG_SRC_DIR}/lib:$CFG_OLD_LD_PATH_VAR"
"${CFG_SRC_DIR}/bin/rustc" --version > /dev/null
if [ $? -ne 0 ]
then
"${CFG_PREFIX}/bin/rustc" --version 2> /dev/null 1> /dev/null
if [ $? -ne 0 ]
then
- export $CFG_LD_PATH_VAR="${CFG_PREFIX}/lib":$CFG_OLD_LD_PATH_VAR
+ export $CFG_LD_PATH_VAR="${CFG_PREFIX}/lib:$CFG_OLD_LD_PATH_VAR"
"${CFG_PREFIX}/bin/rustc" --version > /dev/null
if [ $? -ne 0 ]
then
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
[
- <!-- TODO: Kate's regex engine has very limited support for
+ <!-- FIXME: Kate's regex engine has very limited support for
predefined char classes, so making rustIdent consistent with actual
Rust identifiers will be a bit difficult -->
<!ENTITY rustIdent "[a-zA-Z_][a-zA-Z_0-9]*">
"target_os = \"" + os + "\"",
]
- f.write("#[cfg(" + ', '.join(cfg) + ")]\n")
+ f.write("#[cfg(all(" + ', '.join(cfg) + "))]\n")
version = run([llconfig, '--version']).strip()
" Folding rules {{{2
" Trivial folding rules to begin with.
-" TODO: use the AST to make really good folding
+" FIXME: use the AST to make really good folding
syn region rustFoldBraces start="{" end="}" transparent fold
" Default highlighting {{{1
// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
-#[cfg(target_arch = "arm")]
-#[cfg(target_arch = "mips")]
-#[cfg(target_arch = "mipsel")]
+#[cfg(any(target_arch = "arm",
+ target_arch = "mips",
+ target_arch = "mipsel"))]
static MIN_ALIGN: uint = 8;
-#[cfg(target_arch = "x86")]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86",
+ target_arch = "x86_64"))]
static MIN_ALIGN: uint = 16;
#[cfg(jemalloc)]
}
// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough
- #[cfg(not(windows), not(target_os = "android"))]
+ #[cfg(all(not(windows), not(target_os = "android")))]
#[link(name = "pthread")]
extern {}
}
}
-#[cfg(not(jemalloc), unix)]
+#[cfg(all(not(jemalloc), unix))]
mod imp {
use core::cmp;
use core::ptr;
pub fn stats_print() {}
}
-#[cfg(not(jemalloc), windows)]
+#[cfg(all(not(jemalloc), windows))]
mod imp {
use libc::{c_void, size_t};
use libc;
}
3 => {
match (byte, safe_get(v, i, total)) {
- (0xE0 , 0xA0 .. 0xBF) => (),
- (0xE1 .. 0xEC, 0x80 .. 0xBF) => (),
- (0xED , 0x80 .. 0x9F) => (),
- (0xEE .. 0xEF, 0x80 .. 0xBF) => (),
+ (0xE0 , 0xA0 ... 0xBF) => (),
+ (0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
+ (0xED , 0x80 ... 0x9F) => (),
+ (0xEE ... 0xEF, 0x80 ... 0xBF) => (),
_ => {
error!();
continue;
}
4 => {
match (byte, safe_get(v, i, total)) {
- (0xF0 , 0x90 .. 0xBF) => (),
- (0xF1 .. 0xF3, 0x80 .. 0xBF) => (),
- (0xF4 , 0x80 .. 0x8F) => (),
+ (0xF0 , 0x90 ... 0xBF) => (),
+ (0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
+ (0xF4 , 0x80 ... 0x8F) => (),
_ => {
error!();
continue;
/// Every type with no non-`'static` references implements `Any`, so `Any` can
/// be used as a trait object to emulate the effects dynamic typing.
#[stable]
-pub trait Any: AnyPrivate {}
+pub trait Any: AnyPrivate + 'static {}
/// An inner trait to ensure that only this module can call `get_type_id()`.
pub trait AnyPrivate {
}
#[stable]
-impl<'a> AnyRefExt<'a> for &'a Any+'a {
+impl<'a> AnyRefExt<'a> for &'a Any {
#[inline]
#[stable]
fn is<T: 'static>(self) -> bool {
}
#[stable]
-impl<'a> AnyMutRefExt<'a> for &'a mut Any+'a {
+impl<'a> AnyMutRefExt<'a> for &'a mut Any {
#[inline]
#[unstable = "naming conventions around acquiring references may change"]
fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
fail!("to_digit: radix is too high (maximum 36)");
}
let val = match c {
- '0' .. '9' => c as uint - ('0' as uint),
- 'a' .. 'z' => c as uint + 10u - ('a' as uint),
- 'A' .. 'Z' => c as uint + 10u - ('A' as uint),
+ '0' ... '9' => c as uint - ('0' as uint),
+ 'a' ... 'z' => c as uint + 10u - ('a' as uint),
+ 'A' ... 'Z' => c as uint + 10u - ('A' as uint),
_ => return None,
};
if val < radix { Some(val) }
let offset = offset as uint;
unsafe {
match ((c as i32) >> offset) & 0xf {
- i @ 0 .. 9 => { f(transmute('0' as i32 + i)); }
+ i @ 0 ... 9 => { f(transmute('0' as i32 + i)); }
i => { f(transmute('a' as i32 + (i - 10))); }
}
}
'\\' => { f('\\'); f('\\'); }
'\'' => { f('\\'); f('\''); }
'"' => { f('\\'); f('"'); }
- '\x20' .. '\x7e' => { f(c); }
+ '\x20' ... '\x7e' => { f(c); }
_ => c.escape_unicode(f),
}
}
}
}
-radix!(Binary, 2, "0b", x @ 0 .. 2 => b'0' + x)
-radix!(Octal, 8, "0o", x @ 0 .. 7 => b'0' + x)
-radix!(Decimal, 10, "", x @ 0 .. 9 => b'0' + x)
-radix!(LowerHex, 16, "0x", x @ 0 .. 9 => b'0' + x,
- x @ 10 ..15 => b'a' + (x - 10))
-radix!(UpperHex, 16, "0x", x @ 0 .. 9 => b'0' + x,
- x @ 10 ..15 => b'A' + (x - 10))
+radix!(Binary, 2, "0b", x @ 0 ... 2 => b'0' + x)
+radix!(Octal, 8, "0o", x @ 0 ... 7 => b'0' + x)
+radix!(Decimal, 10, "", x @ 0 ... 9 => b'0' + x)
+radix!(LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x,
+ x @ 10 ... 15 => b'a' + (x - 10))
+radix!(UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x,
+ x @ 10 ... 15 => b'A' + (x - 10))
/// A radix with in the range of `2..36`.
#[deriving(Clone, PartialEq)]
fn base(&self) -> u8 { self.base }
fn digit(&self, x: u8) -> u8 {
match x {
- x @ 0 ..9 => b'0' + x,
+ x @ 0 ... 9 => b'0' + x,
x if x < self.base() => b'a' + (x - 10),
x => fail!("number not in the range 0..{}: {}", self.base() - 1, x),
}
2 => if second & !CONT_MASK != TAG_CONT_U8 {err!()},
3 => {
match (first, second, next!() & !CONT_MASK) {
- (0xE0 , 0xA0 .. 0xBF, TAG_CONT_U8) |
- (0xE1 .. 0xEC, 0x80 .. 0xBF, TAG_CONT_U8) |
- (0xED , 0x80 .. 0x9F, TAG_CONT_U8) |
- (0xEE .. 0xEF, 0x80 .. 0xBF, TAG_CONT_U8) => {}
+ (0xE0 , 0xA0 ... 0xBF, TAG_CONT_U8) |
+ (0xE1 ... 0xEC, 0x80 ... 0xBF, TAG_CONT_U8) |
+ (0xED , 0x80 ... 0x9F, TAG_CONT_U8) |
+ (0xEE ... 0xEF, 0x80 ... 0xBF, TAG_CONT_U8) => {}
_ => err!()
}
}
4 => {
match (first, second, next!() & !CONT_MASK, next!() & !CONT_MASK) {
- (0xF0 , 0x90 .. 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
- (0xF1 .. 0xF3, 0x80 .. 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
- (0xF4 , 0x80 .. 0x8F, TAG_CONT_U8, TAG_CONT_U8) => {}
+ (0xF0 , 0x90 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
+ (0xF1 ... 0xF3, 0x80 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
+ (0xF4 , 0x80 ... 0x8F, TAG_CONT_U8, TAG_CONT_U8) => {}
_ => err!()
}
}
self.writer.write("\"".as_bytes())
}
}
- '\x20'..'\x7e' => self.writer.write([ch as u8]),
+ '\x20'...'\x7e' => self.writer.write([ch as u8]),
_ => {
char::escape_unicode(ch, |c| {
let _ = self.writer.write([c as u8]);
}
unsafe {
- let mut messages = self.messages.lock();
+ let messages = self.messages.lock();
// We block here if we have no messages to process and we may
// receive a message at a later date
if self.remotes.len() > 0 && messages.len() == 0 &&
// windows requires saving more registers (both general and XMM), so the windows
// register context must be larger.
-#[cfg(windows, target_arch = "x86_64")]
+#[cfg(all(windows, target_arch = "x86_64"))]
#[repr(C)]
struct Registers {
gpr:[libc::uintptr_t, ..14],
_xmm:[simd::u32x4, ..10]
}
-#[cfg(not(windows), target_arch = "x86_64")]
+#[cfg(all(not(windows), target_arch = "x86_64"))]
#[repr(C)]
struct Registers {
gpr:[libc::uintptr_t, ..10],
_xmm:[simd::u32x4, ..6]
}
-#[cfg(windows, target_arch = "x86_64")]
+#[cfg(all(windows, target_arch = "x86_64"))]
fn new_regs() -> Box<Registers> {
box() Registers {
gpr:[0,..14],
_xmm:[simd::u32x4(0,0,0,0),..10]
}
}
-#[cfg(not(windows), target_arch = "x86_64")]
+#[cfg(all(not(windows), target_arch = "x86_64"))]
fn new_regs() -> Box<Registers> {
box() Registers {
gpr:[0,..10],
regs[14] = rust_bootstrap_green_task as libc::uintptr_t; // #56 pc, r14 --> lr
}
-#[cfg(target_arch = "mips")]
-#[cfg(target_arch = "mipsel")]
+#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
type Registers = [libc::uintptr_t, ..32];
-#[cfg(target_arch = "mips")]
-#[cfg(target_arch = "mipsel")]
+#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
fn new_regs() -> Box<Registers> { box {[0, .. 32]} }
-#[cfg(target_arch = "mips")]
-#[cfg(target_arch = "mipsel")]
+#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
procedure: raw::Procedure, sp: *mut uint) {
let sp = align_down(sp);
//
// DragonFly BSD also seems to suffer from the same problem. When MAP_STACK is
// used, it returns the same `ptr` multiple times.
-#[cfg(not(windows), not(target_os = "freebsd"), not(target_os = "dragonfly"))]
+#[cfg(not(any(windows, target_os = "freebsd", target_os = "dragonfly")))]
static STACK_FLAGS: libc::c_int = libc::MAP_STACK | libc::MAP_PRIVATE |
libc::MAP_ANON;
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
static STACK_FLAGS: libc::c_int = libc::MAP_PRIVATE | libc::MAP_ANON;
#[cfg(windows)]
static STACK_FLAGS: libc::c_int = 0;
#[cfg(windows)] pub use funcs::extra::msvcrt::{get_osfhandle, open_osfhandle};
#[cfg(windows)] pub use funcs::extra::winsock::{ioctlsocket};
-#[cfg(target_os = "linux")] #[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")] #[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub use consts::os::posix01::{CLOCK_REALTIME, CLOCK_MONOTONIC};
-#[cfg(target_os = "linux")] #[cfg(target_os = "android")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub use funcs::posix01::unistd::{fdatasync};
-#[cfg(target_os = "linux")] #[cfg(target_os = "android")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub use types::os::arch::extra::{sockaddr_ll};
-#[cfg(target_os = "linux")] #[cfg(target_os = "android")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub use consts::os::extra::{AF_PACKET};
-#[cfg(unix, not(target_os = "freebsd"))]
+#[cfg(all(unix, not(target_os = "freebsd")))]
pub use consts::os::extra::{MAP_STACK};
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
pub use consts::os::bsd44::{TCP_KEEPIDLE};
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
+#[cfg(any(target_os = "macos", target_os = "ios"))]
pub use consts::os::bsd44::{TCP_KEEPALIVE};
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
+#[cfg(any(target_os = "macos", target_os = "ios"))]
pub use consts::os::extra::{F_FULLFSYNC};
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
pub use types::os::arch::extra::{mach_timebase_info};
// Standard types that are scalar but vary by OS and arch.
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub mod os {
pub mod common {
pub mod posix01 {
}
}
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "arm")]
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
+ #[cfg(any(target_arch = "x86",
+ target_arch = "arm",
+ target_arch = "mips",
+ target_arch = "mipsel"))]
pub mod arch {
pub mod c95 {
pub type c_char = i8;
pub type intptr_t = i32;
pub type uintptr_t = u32;
}
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
+ #[cfg(any(target_arch = "x86",
+ target_arch = "mips",
+ target_arch = "mipsel"))]
pub mod posix88 {
pub type off_t = i32;
pub type dev_t = u64;
pub __size: [u32, ..9]
}
}
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
+ #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
pub mod posix01 {
use types::os::arch::c95::{c_long, c_ulong, time_t};
use types::os::arch::posix88::{gid_t, ino_t};
}
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
pub mod os {
pub mod common {
pub mod posix01 {
}
}
- #[cfg(target_arch = "arm")]
- #[cfg(target_arch = "x86")]
+ #[cfg(any(target_arch = "arm", target_arch = "x86"))]
pub mod arch {
pub mod c95 {
pub type c_char = i8;
}
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub mod os {
pub mod c95 {
use types::os::arch::c95::{c_int, c_uint};
}
pub mod c99 {
}
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "x86_64")]
- #[cfg(target_arch = "arm")]
+ #[cfg(any(target_arch = "x86",
+ target_arch = "x86_64",
+ target_arch = "arm"))]
pub mod posix88 {
use types::os::arch::c95::c_int;
use types::common::c95::c_void;
pub static EHWPOISON: c_int = 133;
}
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
+ #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
pub mod posix88 {
use types::os::arch::c95::c_int;
use types::common::c95::c_void;
#[cfg(target_os = "android")]
pub static PTHREAD_STACK_MIN: size_t = 8192;
- #[cfg(target_arch = "arm", target_os = "linux")]
- #[cfg(target_arch = "x86", target_os = "linux")]
- #[cfg(target_arch = "x86_64", target_os = "linux")]
+ #[cfg(all(target_os = "linux",
+ any(target_arch = "arm",
+ target_arch = "x86",
+ target_arch = "x86_64")))]
pub static PTHREAD_STACK_MIN: size_t = 16384;
- #[cfg(target_arch = "mips", target_os = "linux")]
- #[cfg(target_arch = "mipsel", target_os = "linux")]
+ #[cfg(all(target_os = "linux",
+ any(target_arch = "mips", target_arch = "mipsel")))]
pub static PTHREAD_STACK_MIN: size_t = 131072;
pub static CLOCK_REALTIME: c_int = 0;
}
pub mod posix08 {
}
- #[cfg(target_arch = "arm")]
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "x86_64")]
+ #[cfg(any(target_arch = "arm",
+ target_arch = "x86",
+ target_arch = "x86_64"))]
pub mod bsd44 {
use types::os::arch::c95::c_int;
pub static SHUT_WR: c_int = 1;
pub static SHUT_RDWR: c_int = 2;
}
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
+ #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
pub mod bsd44 {
use types::os::arch::c95::c_int;
pub static SHUT_WR: c_int = 1;
pub static SHUT_RDWR: c_int = 2;
}
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "x86_64")]
- #[cfg(target_arch = "arm")]
+ #[cfg(any(target_arch = "x86",
+ target_arch = "x86_64",
+ target_arch = "arm"))]
pub mod extra {
use types::os::arch::c95::c_int;
pub static MAP_NONBLOCK : c_int = 0x010000;
pub static MAP_STACK : c_int = 0x020000;
}
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
+ #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
pub mod extra {
use types::os::arch::c95::c_int;
}
}
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
pub mod os {
pub mod c95 {
use types::os::arch::c95::{c_int, c_uint};
#[cfg(target_arch = "arm")]
pub static PTHREAD_STACK_MIN: size_t = 4096;
- #[cfg(target_os = "freebsd", target_arch = "mips")]
- #[cfg(target_os = "freebsd", target_arch = "mipsel")]
- #[cfg(target_os = "freebsd", target_arch = "x86")]
- #[cfg(target_os = "freebsd", target_arch = "x86_64")]
+ #[cfg(all(target_os = "freebsd",
+ any(target_arch = "mips",
+ target_arch = "mipsel",
+ target_arch = "x86",
+ target_arch = "x86_64")))]
pub static PTHREAD_STACK_MIN: size_t = 2048;
#[cfg(target_os = "dragonfly")]
}
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
pub mod os {
pub mod c95 {
use types::os::arch::c95::{c_int, c_uint};
}
}
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub mod posix88 {
pub mod stat_ {
use types::os::arch::c95::{c_char, c_int};
pub fn chmod(path: *const c_char, mode: mode_t) -> c_int;
pub fn fchmod(fd: c_int, mode: mode_t) -> c_int;
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "linux",
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "android",
+ target_os = "ios"))]
pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int;
pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int;
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "linux",
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "android",
+ target_os = "ios"))]
pub fn stat(path: *const c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
}
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub mod posix01 {
pub mod stat_ {
use types::os::arch::c95::{c_char, c_int};
use types::os::arch::posix01::stat;
extern {
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "linux",
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "android",
+ target_os = "ios"))]
pub fn lstat(path: *const c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
pub fn fsync(fd: c_int) -> c_int;
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub fn fdatasync(fd: c_int) -> c_int;
pub fn setenv(name: *const c_char, val: *const c_char,
}
- #[cfg(target_os = "windows")]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "windows",
+ target_os = "linux",
+ target_os = "android",
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub mod posix08 {
pub mod unistd {
}
}
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub mod bsd44 {
use types::common::c95::{c_void};
use types::os::arch::c95::{c_char, c_uchar, c_int, c_uint, c_ulong, size_t};
}
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub mod bsd44 {
use types::common::c95::{c_void};
use types::os::arch::c95::{c_uchar, c_int, size_t};
pub mod bsd44 {
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
pub mod extra {
use types::os::arch::c95::{c_char, c_int};
}
}
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
pub mod extra {
}
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub mod extra {
}
use libc;
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub static FIONBIO: libc::c_ulong = 0x8004667e;
-#[cfg(target_os = "linux", target_arch = "x86")]
-#[cfg(target_os = "linux", target_arch = "x86_64")]
-#[cfg(target_os = "linux", target_arch = "arm")]
-#[cfg(target_os = "android")]
+#[cfg(any(all(target_os = "linux",
+ any(target_arch = "x86",
+ target_arch = "x86_64",
+ target_arch = "arm")),
+ target_os = "android"))]
pub static FIONBIO: libc::c_ulong = 0x5421;
-#[cfg(target_os = "linux", target_arch = "mips")]
-#[cfg(target_os = "linux", target_arch = "mipsel")]
+#[cfg(all(target_os = "linux",
+ any(target_arch = "mips", target_arch = "mipsel")))]
pub static FIONBIO: libc::c_ulong = 0x667e;
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub static FIOCLEX: libc::c_ulong = 0x20006601;
-#[cfg(target_os = "linux", target_arch = "x86")]
-#[cfg(target_os = "linux", target_arch = "x86_64")]
-#[cfg(target_os = "linux", target_arch = "arm")]
-#[cfg(target_os = "android")]
+#[cfg(any(all(target_os = "linux",
+ any(target_arch = "x86",
+ target_arch = "x86_64",
+ target_arch = "arm")),
+ target_os = "android"))]
pub static FIOCLEX: libc::c_ulong = 0x5451;
-#[cfg(target_os = "linux", target_arch = "mips")]
-#[cfg(target_os = "linux", target_arch = "mipsel")]
+#[cfg(all(target_os = "linux",
+ any(target_arch = "mips", target_arch = "mipsel")))]
pub static FIOCLEX: libc::c_ulong = 0x6601;
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub static MSG_DONTWAIT: libc::c_int = 0x80;
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub static MSG_DONTWAIT: libc::c_int = 0x40;
pub static WNOHANG: libc::c_int = 1;
pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
}
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
+#[cfg(any(target_os = "macos", target_os = "ios"))]
mod select {
pub static FD_SETSIZE: uint = 1024;
}
}
-#[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "android",
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "linux"))]
mod select {
use std::uint;
use libc;
}
}
-#[cfg(target_os = "linux", target_arch = "x86")]
-#[cfg(target_os = "linux", target_arch = "x86_64")]
-#[cfg(target_os = "linux", target_arch = "arm")]
-#[cfg(target_os = "android")]
+#[cfg(any(all(target_os = "linux",
+ any(target_arch = "x86",
+ target_arch = "x86_64",
+ target_arch = "arm")),
+ target_os = "android"))]
mod signal {
use libc;
}
}
-#[cfg(target_os = "linux", target_arch = "mips")]
-#[cfg(target_os = "linux", target_arch = "mipsel")]
+#[cfg(all(target_os = "linux",
+ any(target_arch = "mips", target_arch = "mipsel")))]
mod signal {
use libc;
}
}
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
mod signal {
use libc;
fn datasync(&mut self) -> IoResult<()> {
return super::mkerr_libc(os_datasync(self.fd()));
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
fn os_datasync(fd: c_int) -> c_int {
unsafe { libc::fcntl(fd, libc::F_FULLFSYNC) }
}
fn os_datasync(fd: c_int) -> c_int {
retry(|| unsafe { libc::fdatasync(fd) })
}
- #[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "linux"))]
+ #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "linux")))]
fn os_datasync(fd: c_int) -> c_int {
retry(|| unsafe { libc::fsync(fd) })
}
// FileStat times are in milliseconds
fn mktime(secs: u64, nsecs: u64) -> u64 { secs * 1000 + nsecs / 1000000 }
- #[cfg(not(target_os = "linux"), not(target_os = "android"))]
+ #[cfg(not(any(target_os = "linux", target_os = "android")))]
fn flags(stat: &libc::stat) -> u64 { stat.st_flags as u64 }
- #[cfg(target_os = "linux")] #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
fn flags(_stat: &libc::stat) -> u64 { 0 }
- #[cfg(not(target_os = "linux"), not(target_os = "android"))]
+ #[cfg(not(any(target_os = "linux", target_os = "android")))]
fn gen(stat: &libc::stat) -> u64 { stat.st_gen as u64 }
- #[cfg(target_os = "linux")] #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
fn gen(_stat: &libc::stat) -> u64 { 0 }
rtio::FileStat {
#[path = "file_windows.rs"]
pub mod file;
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "android",
+ target_os = "linux"))]
#[path = "timer_unix.rs"]
pub mod timer;
}
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
seconds as libc::c_int)
}
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
seconds as libc::c_int)
}
- #[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "freebsd"),
- not(target_os = "dragonfly"))]
+ #[cfg(not(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly")))]
fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
Ok(())
}
#[cfg(unix)]
fn translate_status(status: c_int) -> rtio::ProcessExit {
#![allow(non_snake_case)]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
mod imp {
pub fn WIFEXITED(status: i32) -> bool { (status & 0xff) == 0 }
pub fn WEXITSTATUS(status: i32) -> i32 { (status >> 8) & 0xff }
pub fn WTERMSIG(status: i32) -> i32 { status & 0x7f }
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
mod imp {
pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
pub fn WEXITSTATUS(status: i32) -> i32 { status >> 8 }
// If the file descriptor is one of stdin, stderr, or stdout
// then it should not be closed by us
let closeme = match fd {
- 0..2 => false,
+ 0...2 => false,
_ => true,
};
let handle = unsafe { get_osfhandle(fd) as HANDLE };
pub mod io;
pub mod task;
-#[cfg(windows)]
-#[cfg(android)]
+#[cfg(any(windows, android))]
static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
-#[cfg(unix, not(android))]
+#[cfg(all(unix, not(android)))]
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
#[lang = "start"]
assert!(scale > 0.0, "Gamma::new called with scale <= 0");
let repr = match shape {
- 1.0 => One(Exp::new(1.0 / scale)),
- 0.0 .. 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
- _ => Large(GammaLargeShape::new_raw(shape, scale))
+ 1.0 => One(Exp::new(1.0 / scale)),
+ 0.0 ... 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
+ _ => Large(GammaLargeShape::new_raw(shape, scale))
};
Gamma { repr: repr }
}
};
// Try the common ASCII case before invoking binary search.
match c {
- '_' | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' => true,
+ '_' | '0' ... '9' | 'a' ... 'z' | 'A' ... 'Z' => true,
_ => PERLW.binary_search(|&(start, end)| {
if c >= start && c <= end {
Equal
'-' | ':' => result.push_char('.'),
// These are legal symbols
- 'a' .. 'z'
- | 'A' .. 'Z'
- | '0' .. '9'
+ 'a' ... 'z'
+ | 'A' ... 'Z'
+ | '0' ... '9'
| '_' | '.' | '$' => result.push_char(c),
_ => {
E0157,
E0158,
E0159,
- E0161
+ E0161,
+ E0162
)
"static_assert",
"thread_local",
"no_debug",
+ "unsafe_no_drop_flag",
// used in resolve
"prelude_import",
let (value, msg, struct_lit_needs_parens) = match e.node {
ast::ExprIf(ref cond, _, _) => (cond, "`if` condition", true),
ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true),
- ast::ExprMatch(ref head, _) => (head, "`match` head expression", true),
+ ast::ExprMatch(ref head, _, source) => match source {
+ ast::MatchNormal => (head, "`match` head expression", true),
+ ast::MatchIfLetDesugar => (head, "`if let` head expression", true)
+ },
ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
ast::ExprAssign(_, ref value) => (value, "assigned value", false),
ast::ExprAssignOp(_, _, ref value) => (value, "assigned value", false),
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
match e.node {
- ast::ExprMatch(_, ref arms) => {
+ ast::ExprMatch(_, ref arms, _) => {
for a in arms.iter() {
self.check_unused_mut_pat(cx, a.pats.as_slice())
}
pub static tag_items_data_item_stability: uint = 0x92;
+pub static tag_items_data_item_repr: uint = 0x93;
+
#[deriving(Clone, Show)]
pub struct LinkMeta {
pub crate_name: String,
decoder::get_stability(&*cdata, def.node)
}
+pub fn get_repr_attrs(cstore: &cstore::CStore, def: ast::DefId)
+ -> Vec<attr::ReprAttr> {
+ let cdata = cstore.get_crate_data(def.krate);
+ decoder::get_repr_attrs(&*cdata, def.node)
+}
+
pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
let cdata = cstore.get_crate_data(def.krate);
decoder::is_associated_type(&*cdata, def.node)
MutStatic, // b
Fn, // f
UnsafeFn, // u
+ CtorFn, // o
StaticMethod, // F
UnsafeStaticMethod, // U
Type, // y
'b' => MutStatic,
'f' => Fn,
'u' => UnsafeFn,
+ 'o' => CtorFn,
'F' => StaticMethod,
'U' => UnsafeStaticMethod,
'y' => Type,
ImmStatic => DlDef(def::DefStatic(did, false)),
MutStatic => DlDef(def::DefStatic(did, true)),
Struct => DlDef(def::DefStruct(did)),
- UnsafeFn => DlDef(def::DefFn(did, ast::UnsafeFn)),
- Fn => DlDef(def::DefFn(did, ast::NormalFn)),
+ UnsafeFn => DlDef(def::DefFn(did, ast::UnsafeFn, false)),
+ Fn => DlDef(def::DefFn(did, ast::NormalFn, false)),
+ CtorFn => DlDef(def::DefFn(did, ast::NormalFn, true)),
StaticMethod | UnsafeStaticMethod => {
let fn_style = if fam == UnsafeStaticMethod {
ast::UnsafeFn
})
}
+pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
+ let item = lookup_item(id, cdata.data());
+ match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
+ let mut decoder = reader::Decoder::new(doc);
+ Decodable::decode(&mut decoder).unwrap()
+ }) {
+ Some(attrs) => attrs,
+ None => Vec::new(),
+ }
+}
+
pub fn get_impl_trait(cdata: Cmd,
id: ast::NodeId,
tcx: &ty::ctxt) -> Option<Rc<ty::TraitRef>>
encode_parent_item(rbml_w, local_def(id));
encode_visibility(rbml_w, variant.node.vis);
encode_attributes(rbml_w, variant.node.attrs.as_slice());
+ encode_repr_attrs(rbml_w, ecx, variant.node.attrs.as_slice());
let stab = stability::lookup(ecx.tcx, ast_util::local_def(variant.node.id));
encode_stability(rbml_w, stab);
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, local_def(ctor_id));
- encode_family(rbml_w, 'f');
+ encode_family(rbml_w, 'o');
encode_bounds_and_type(rbml_w, ecx,
&lookup_item_type(ecx.tcx, local_def(ctor_id)));
encode_name(rbml_w, name.name);
rbml_w.end_tag();
}
+fn encode_repr_attrs(rbml_w: &mut Encoder,
+ ecx: &EncodeContext,
+ attrs: &[Attribute]) {
+ let mut repr_attrs = Vec::new();
+ for attr in attrs.iter() {
+ repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(),
+ attr).into_iter());
+ }
+ rbml_w.start_tag(tag_items_data_item_repr);
+ repr_attrs.encode(rbml_w);
+ rbml_w.end_tag();
+}
+
fn encode_inlined_item(ecx: &EncodeContext,
rbml_w: &mut Encoder,
ii: InlinedItemRef) {
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
encode_name(rbml_w, item.ident.name);
encode_attributes(rbml_w, item.attrs.as_slice());
+ encode_repr_attrs(rbml_w, ecx, item.attrs.as_slice());
for v in (*enum_definition).variants.iter() {
encode_variant_id(rbml_w, local_def(v.node.id));
}
encode_path(rbml_w, path.clone());
encode_stability(rbml_w, stab);
encode_visibility(rbml_w, vis);
+ encode_repr_attrs(rbml_w, ecx, item.attrs.as_slice());
/* Encode def_ids for each field and method
for methods, write all the stuff get_trait_method
impl tr for def::Def {
fn tr(&self, dcx: &DecodeContext) -> def::Def {
match *self {
- def::DefFn(did, p) => def::DefFn(did.tr(dcx), p),
+ def::DefFn(did, p, is_ctor) => def::DefFn(did.tr(dcx), p, is_ctor),
def::DefStaticMethod(did, wrapped_did2, p) => {
def::DefStaticMethod(did.tr(dcx),
match wrapped_did2 {
self.add_node(expr.id, [then_exit, else_exit]) // 4, 5
}
+ ast::ExprIfLet(..) => {
+ self.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
+
ast::ExprWhile(ref cond, ref body, _) => {
//
// [pred]
expr_exit
}
- ast::ExprMatch(ref discr, ref arms) => {
+ ast::ExprMatch(ref discr, ref arms, _) => {
//
// [pred]
// |
}
match v.tcx.def_map.borrow().find(&e.id) {
Some(&DefStatic(..)) |
- Some(&DefFn(_, _)) |
+ Some(&DefFn(..)) |
Some(&DefVariant(_, _, _)) |
Some(&DefStruct(_)) => { }
fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
visit::walk_expr(cx, ex);
match ex.node {
- ExprMatch(ref scrut, ref arms) => {
+ ExprMatch(ref scrut, ref arms, source) => {
// First, check legality of move bindings.
for arm in arms.iter() {
check_legality_of_move_bindings(cx,
}
// Fourth, check for unreachable arms.
- check_arms(cx, inlined_arms.as_slice());
+ check_arms(cx, inlined_arms.as_slice(), source);
// Finally, check if the whole match expression is exhaustive.
// Check for empty enum, because is_useful only works on inhabited types.
}
// Check for unreachable patterns
-fn check_arms(cx: &MatchCheckCtxt, arms: &[(Vec<P<Pat>>, Option<&Expr>)]) {
+fn check_arms(cx: &MatchCheckCtxt, arms: &[(Vec<P<Pat>>, Option<&Expr>)], source: MatchSource) {
let mut seen = Matrix(vec![]);
+ let mut printed_if_let_err = false;
for &(ref pats, guard) in arms.iter() {
for pat in pats.iter() {
let v = vec![&**pat];
+
match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
- NotUseful => span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"),
+ NotUseful => {
+ if source == MatchIfLetDesugar {
+ if printed_if_let_err {
+ // we already printed an irrefutable if-let pattern error.
+ // We don't want two, that's just confusing.
+ } else {
+ // find the first arm pattern so we can use its span
+ let &(ref first_arm_pats, _) = &arms[0];
+ let first_pat = first_arm_pats.get(0);
+ let span = first_pat.span;
+ span_err!(cx.tcx.sess, span, E0162, "irrefutable if-let pattern");
+ printed_if_let_err = true;
+ }
+ } else {
+ span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern");
+ }
+ }
Useful => (),
UsefulWithWitness(_) => unreachable!()
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Def {
- DefFn(ast::DefId, ast::FnStyle),
+ DefFn(ast::DefId, ast::FnStyle, bool /* is_ctor */),
DefStaticMethod(/* method */ ast::DefId, MethodProvenance, ast::FnStyle),
DefSelfTy(/* trait id */ ast::NodeId),
DefMod(ast::DefId),
impl Def {
pub fn def_id(&self) -> ast::DefId {
match *self {
- DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
+ DefFn(id, _, _) | DefStaticMethod(id, _, _) | DefMod(id) |
DefForeignMod(id) | DefStatic(id, _) |
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
}
}
- ast::ExprMatch(ref discr, ref arms) => {
+ ast::ExprIfLet(..) => {
+ self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
+
+ ast::ExprMatch(ref discr, ref arms, _) => {
let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
match expr.node {
ast::ExprPath(..) => {
match ty::resolve_expr(self.tcx, expr) {
- DefFn(did, _) if self.def_id_is_transmute(did) => {
+ DefFn(did, _, _) if self.def_id_is_transmute(did) => {
let typ = ty::node_id_to_type(self.tcx, expr.id);
match ty::get(typ).sty {
ty_bare_fn(ref bare_fn_ty)
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr);
}
+ ExprIfLet(..) => {
+ ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
ExprForLoop(ref pat, _, _, _) => {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
debug!("adding local variable {} from for loop with bm {:?}",
self.propagate_through_expr(&**cond, ln)
}
+ ExprIfLet(..) => {
+ self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
+
ExprWhile(ref cond, ref blk, _) => {
self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ)
}
self.propagate_through_loop(expr, LoopLoop, &**blk, succ)
}
- ExprMatch(ref e, ref arms) => {
+ ExprMatch(ref e, ref arms, _) => {
//
// (e)
// |
ExprPath(..) | ExprBox(..) => {
visit::walk_expr(this, expr);
}
+ ExprIfLet(..) => {
+ this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
}
}
Some(adjustment) => {
match *adjustment {
ty::AdjustAddEnv(..) => {
+ debug!("cat_expr(AdjustAddEnv): {}",
+ expr.repr(self.tcx()));
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
ty::AdjustDerefRef(
ty::AutoDerefRef {
autoref: Some(_), ..}) => {
+ debug!("cat_expr(AdjustDerefRef): {}",
+ expr.repr(self.tcx()));
// Equivalent to &*expr or something similar.
// Result is an rvalue.
let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
autoderefs: uint)
-> McResult<cmt> {
let mut cmt = if_ok!(self.cat_expr_unadjusted(expr));
+ debug!("cat_expr_autoderefd: autoderefs={}, cmt={}",
+ autoderefs,
+ cmt.repr(self.tcx()));
for deref in range(1u, autoderefs + 1) {
cmt = self.cat_deref(expr, cmt, deref, false);
}
ast::ExprField(ref base, f_name, _) => {
let base_cmt = if_ok!(self.cat_expr(&**base));
+ debug!("cat_expr(cat_field): id={} expr={} base={}",
+ expr.id,
+ expr.repr(self.tcx()),
+ base_cmt.repr(self.tcx()));
Ok(self.cat_field(expr, base_cmt, f_name.node, expr_ty))
}
ast::ExprForLoop(..) => {
Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
}
+
+ ast::ExprIfLet(..) => {
+ self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
}
}
}
// Tuple struct constructors across crates are identified as
// DefFn types, so we explicitly handle that case here.
- Some(&def::DefFn(did, _)) if !is_local(did) => {
+ Some(&def::DefFn(did, _, _)) if !is_local(did) => {
match csearch::get_tuple_struct_definition_if_ctor(
&self.tcx.sess.cstore, did) {
Some(did) => guard(did),
let name_bindings =
self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
- let def = DefFn(local_def(item.id), fn_style);
+ let def = DefFn(local_def(item.id), fn_style, false);
name_bindings.define_value(def, sp, is_public);
parent
}
match foreign_item.node {
ForeignItemFn(_, ref generics) => {
- let def = DefFn(local_def(foreign_item.id), UnsafeFn);
+ let def = DefFn(local_def(foreign_item.id), UnsafeFn, false);
name_bindings.define_value(def, foreign_item.span, is_public);
self.with_type_parameter_rib(
DUMMY_SP);
let def = DefFn(
static_method_info.def_id,
- static_method_info.fn_style);
+ static_method_info.fn_style,
+ false);
method_name_bindings.define_value(
def, DUMMY_SP,
match value_result {
BoundResult(ref target_module, ref name_bindings) => {
- debug!("(resolving single import) found value target");
+ debug!("(resolving single import) found value target: {:?}",
+ { name_bindings.value_def.borrow().clone().unwrap().def });
self.check_for_conflicting_import(
&import_resolution.value_target,
directive.span,
def::DefVariant(_, _, _) |
def::DefUpvar(..) => Some(recorder::VarRef),
- def::DefFn(_, _) => Some(recorder::FnRef),
+ def::DefFn(..) => Some(recorder::FnRef),
def::DefSelfTy(_) |
def::DefRegion(_) |
Some(declid),
self.cur_scope);
},
- def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
- sub_span,
- def_id,
- self.cur_scope),
+ def::DefFn(def_id, _, _) => self.fmt.fn_call_str(ex.span,
+ sub_span,
+ def_id,
+ self.cur_scope),
_ => self.sess.span_bug(ex.span,
format!("Unexpected def kind while looking up path in '{}'",
self.span.snippet(ex.span)).as_slice()),
def::DefLocal(_) |
def::DefStatic(_,_) |
def::DefStruct(_) |
- def::DefFn(_, _) => self.write_sub_paths_truncated(path),
+ def::DefFn(..) => self.write_sub_paths_truncated(path),
_ => {},
}
FieldSized,
}
+// An error has already been reported to the user, so no need to continue checking.
+#[deriving(Clone,Show)]
+pub struct ErrorReported;
+
pub type Obligations = subst::VecPerParamSpace<Obligation>;
pub type Selection = Vtable<Obligation>;
cause: ObligationCause,
source_ty: ty::t,
builtin_bound: ty::BuiltinBound)
- -> Obligation
+ -> Result<Obligation, ErrorReported>
{
util::obligation_for_builtin_bound(tcx, cause, builtin_bound, 0, source_ty)
}
bound,
previous_stack.obligation.recursion_depth + 1,
ty);
+ let obligation = match obligation {
+ Ok(ob) => ob,
+ _ => return EvaluatedToMatch
+ };
+
self.evaluate_obligation_recursively(previous_stack, &obligation)
}
use syntax::codemap::Span;
use util::ppaux::Repr;
-use super::{Obligation, ObligationCause, VtableImpl, VtableParam, VtableParamData, VtableImplData};
+use super::{ErrorReported, Obligation, ObligationCause, VtableImpl,
+ VtableParam, VtableParamData, VtableImplData};
///////////////////////////////////////////////////////////////////////////
// Supertrait iterator
let bound_trait_ref = trait_ref_for_builtin_bound(self.tcx,
builtin_bound,
trait_ref.self_ty());
- trait_bounds.push(bound_trait_ref);
+ bound_trait_ref.map(|trait_ref| trait_bounds.push(trait_ref));
}
// Only keep those bounds that we haven't already seen. This
let param_ty = *param_substs.types.get(space, index);
for builtin_bound in param_bounds.builtin_bounds.iter() {
- obligations.push(
- space,
- obligation_for_builtin_bound(tcx,
- cause,
- builtin_bound,
- recursion_depth,
- param_ty));
+ let obligation = obligation_for_builtin_bound(tcx,
+ cause,
+ builtin_bound,
+ recursion_depth,
+ param_ty);
+ match obligation {
+ Ok(ob) => obligations.push(space, ob),
+ _ => {}
+ }
}
for bound_trait_ref in param_bounds.trait_bounds.iter() {
tcx: &ty::ctxt,
builtin_bound: ty::BuiltinBound,
param_ty: ty::t)
- -> Rc<ty::TraitRef>
+ -> Option<Rc<ty::TraitRef>>
{
match tcx.lang_items.from_builtin_kind(builtin_bound) {
Ok(def_id) => {
- Rc::new(ty::TraitRef {
+ Some(Rc::new(ty::TraitRef {
def_id: def_id,
substs: Substs::empty().with_self_ty(param_ty)
- })
+ }))
}
Err(e) => {
- tcx.sess.bug(e.as_slice());
+ tcx.sess.err(e.as_slice());
+ None
}
}
}
builtin_bound: ty::BuiltinBound,
recursion_depth: uint,
param_ty: ty::t)
- -> Obligation
+ -> Result<Obligation, ErrorReported>
{
let trait_ref = trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty);
- Obligation {
- cause: cause,
- recursion_depth: recursion_depth,
- trait_ref: trait_ref
+ match trait_ref {
+ Some(trait_ref) => Ok(Obligation {
+ cause: cause,
+ recursion_depth: recursion_depth,
+ trait_ref: trait_ref
+ }),
+ None => Err(ErrorReported)
}
}
// Default per-arch clobbers
// Basically what clang does
-#[cfg(target_arch = "arm")]
-#[cfg(target_arch = "mips")]
-#[cfg(target_arch = "mipsel")]
+#[cfg(any(target_arch = "arm",
+ target_arch = "mips",
+ target_arch = "mipsel"))]
fn get_clobbers() -> String {
"".to_string()
}
-#[cfg(target_arch = "x86")]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn get_clobbers() -> String {
"~{dirflag},~{fpsr},~{flags}".to_string()
}
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
let expr_ty = node_id_type(bcx, ref_expr.id);
match def {
- def::DefFn(did, _) if {
+ def::DefFn(did, _, _) if {
let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
.find(def_id.node));
data: NamedTupleConstructor(substs, 0)
}
}
- def::DefFn(did, _) if match ty::get(expr_ty).sty {
+ def::DefFn(did, _, _) if match ty::get(expr_ty).sty {
ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
_ => false
} => {
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
}
- def::DefFn(did, _) |
+ def::DefFn(did, _, _) |
def::DefStaticMethod(did, def::FromImpl(_), _) => {
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
}
is_local: bool) -> ValueRef {
let def_id = match def {
- def::DefFn(did, _) | def::DefStaticMethod(did, _, _) |
+ def::DefFn(did, _, _) | def::DefStaticMethod(did, _, _) |
def::DefVariant(_, did, _) | def::DefStruct(did) => did,
_ => {
ccx.sess().bug(format!("get_wrapper_for_bare_fn: \
let opt_def = cx.tcx().def_map.borrow().find_copy(&e.id);
match opt_def {
- Some(def::DefFn(def_id, _fn_style)) => {
+ Some(def::DefFn(def_id, _fn_style, _)) => {
if !ast_util::is_local(def_id) {
let ty = csearch::get_type(cx.tcx(), def_id).ty;
(base::trans_external_path(cx, def_id, ty), true)
// but it could be enabled (with patched LLVM)
pub fn is_split_stack_supported(&self) -> bool {
let ref cfg = self.sess().targ_cfg;
- cfg.os != abi::OsiOS || cfg.arch != abi::Arm
+ (cfg.os != abi::OsiOS || cfg.arch != abi::Arm) && cfg.os != abi::OsWindows
}
}
}
+ ast::ExprIfLet(..) => {
+ cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
+ Found unexpanded if-let.");
+ }
+
ast::ExprWhile(ref cond_exp, ref loop_body, _) => {
walk_expr(cx, &**cond_exp, scope_stack, scope_map);
}
}
- ast::ExprMatch(ref discriminant_exp, ref arms) => {
+ ast::ExprMatch(ref discriminant_exp, ref arms, _) => {
walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
// For each arm we have to first walk the pattern as these might
ast::ExprIf(ref cond, ref thn, ref els) => {
controlflow::trans_if(bcx, expr.id, &**cond, &**thn, els.as_ref().map(|e| &**e), dest)
}
- ast::ExprMatch(ref discr, ref arms) => {
+ ast::ExprMatch(ref discr, ref arms, _) => {
_match::trans_match(bcx, expr, &**discr, arms.as_slice(), dest)
}
ast::ExprBlock(ref blk) => {
let _icx = push_ctxt("trans_def_datum_unadjusted");
let llfn = match def {
- def::DefFn(did, _) |
+ def::DefFn(did, _, _) |
def::DefStruct(did) | def::DefVariant(_, did, _) |
def::DefStaticMethod(did, def::FromImpl(_), _) => {
callee::trans_fn_ref(bcx, did, ExprId(ref_expr.id))
/// Caches the results of trait selection. This cache is used
/// for things that do not have to do with the parameters in scope.
pub selection_cache: traits::SelectionCache,
+
+ /// Caches the representation hints for struct definitions.
+ pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
}
pub enum tbox_flag {
associated_types: RefCell::new(DefIdMap::new()),
trait_associated_types: RefCell::new(DefIdMap::new()),
selection_cache: traits::SelectionCache::new(),
+ repr_hint_cache: RefCell::new(DefIdMap::new()),
}
}
}
}
+ // Special case: A unit like struct's constructor must be called without () at the
+ // end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
+ // of unit structs this is should not be interpretet as function pointer but as
+ // call to the constructor.
+ def::DefFn(_, _, true) => RvalueDpsExpr,
+
// Fn pointers are just scalar values.
def::DefFn(..) | def::DefStaticMethod(..) => RvalueDatumExpr,
RvalueDpsExpr
}
+ ast::ExprIfLet(..) => {
+ tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
+
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
RvalueDpsExpr
}
}
pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
- ty_dtor(cx, struct_id).is_present()
+ cx.destructor_for_type.borrow().contains_key(&struct_id)
}
pub fn with_path<T>(cx: &ctxt, id: ast::DefId, f: |ast_map::PathElems| -> T) -> T {
}
/// Obtain the representation annotation for a struct definition.
-pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Vec<attr::ReprAttr> {
- let mut acc = Vec::new();
+pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
+ match tcx.repr_hint_cache.borrow().find(&did) {
+ None => {}
+ Some(ref hints) => return (*hints).clone(),
+ }
- ty::each_attr(tcx, did, |meta| {
- acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter());
- true
- });
+ let acc = if did.krate == LOCAL_CRATE {
+ let mut acc = Vec::new();
+ ty::each_attr(tcx, did, |meta| {
+ acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(),
+ meta).into_iter());
+ true
+ });
+ acc
+ } else {
+ csearch::get_repr_attrs(&tcx.sess.cstore, did)
+ };
+ let acc = Rc::new(acc);
+ tcx.repr_hint_cache.borrow_mut().insert(did, acc.clone());
acc
}
use middle::ty::*;
use middle::ty;
use middle::typeck::astconv::AstConv;
-use middle::typeck::check::{FnCtxt, PreferMutLvalue, impl_self_ty};
+use middle::typeck::check::{FnCtxt, NoPreference, PreferMutLvalue};
+use middle::typeck::check::{impl_self_ty};
use middle::typeck::check;
use middle::typeck::infer;
-use middle::typeck::MethodCallee;
+use middle::typeck::{MethodCall, MethodCallee};
use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam};
use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
let (_, _, result) =
check::autoderef(
- self.fcx, span, self_ty, self_expr_id, PreferMutLvalue,
+ self.fcx, span, self_ty, self_expr_id, NoPreference,
|self_ty, autoderefs| self.search_step(self_ty, autoderefs));
match result {
- Some(Some(result)) => Some(result),
+ Some(Some(result)) => {
+ self.fixup_derefs_on_method_receiver_if_necessary(&result,
+ self_ty);
+ Some(result)
+ }
_ => None
}
}
*/
let span = self.self_expr.map_or(self.span, |e| e.span);
- check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
+ check::autoderef(self.fcx, span, self_ty, None, NoPreference, |self_ty, _| {
match get(self_ty).sty {
ty_trait(box TyTrait { def_id, ref substs, bounds, .. }) => {
self.push_inherent_candidates_from_object(
fn push_bound_candidates(&mut self, self_ty: ty::t, restrict_to: Option<DefId>) {
let span = self.self_expr.map_or(self.span, |e| e.span);
- check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
+ check::autoderef(self.fcx, span, self_ty, None, NoPreference, |self_ty, _| {
match get(self_ty).sty {
ty_param(p) => {
self.push_inherent_candidates_from_param(self_ty, restrict_to, p);
};
// This is hokey. We should have mutability inference as a
- // variable. But for now, try &const, then &, then &mut:
+ // variable. But for now, try &, then &mut:
let region =
self.infcx().next_region_var(infer::Autoref(self.span));
for mutbl in mutbls.iter() {
}
}
+ fn fixup_derefs_on_method_receiver_if_necessary(
+ &self,
+ method_callee: &MethodCallee,
+ self_ty: ty::t) {
+ let sig = match ty::get(method_callee.ty).sty {
+ ty::ty_bare_fn(ref f) => f.sig.clone(),
+ ty::ty_closure(ref f) => f.sig.clone(),
+ _ => return,
+ };
+
+ match ty::get(*sig.inputs.get(0)).sty {
+ ty::ty_rptr(_, ty::mt {
+ ty: _,
+ mutbl: ast::MutMutable,
+ }) => {}
+ _ => return,
+ }
+
+ // Fix up autoderefs and derefs.
+ let mut self_expr = match self.self_expr {
+ Some(expr) => expr,
+ None => return,
+ };
+ loop {
+ // Count autoderefs.
+ let autoderef_count = match self.fcx
+ .inh
+ .adjustments
+ .borrow()
+ .find(&self_expr.id) {
+ Some(&ty::AdjustDerefRef(ty::AutoDerefRef {
+ autoderefs: autoderef_count,
+ autoref: _
+ })) if autoderef_count > 0 => autoderef_count,
+ Some(_) | None => return,
+ };
+
+ check::autoderef(self.fcx,
+ self_expr.span,
+ self.fcx.expr_ty(self_expr),
+ Some(self_expr.id),
+ PreferMutLvalue,
+ |_, autoderefs| {
+ if autoderefs == autoderef_count + 1 {
+ Some(())
+ } else {
+ None
+ }
+ });
+
+ match self_expr.node {
+ ast::ExprParen(ref expr) |
+ ast::ExprIndex(ref expr, _) |
+ ast::ExprField(ref expr, _, _) |
+ ast::ExprTupField(ref expr, _, _) |
+ ast::ExprSlice(ref expr, _, _, _) => self_expr = &**expr,
+ ast::ExprUnary(ast::UnDeref, ref expr) => {
+ drop(check::try_overloaded_deref(
+ self.fcx,
+ self_expr.span,
+ Some(MethodCall::expr(self_expr.id)),
+ Some(self_expr),
+ self_ty,
+ PreferMutLvalue));
+ self_expr = &**expr
+ }
+ _ => break,
+ }
+ }
+ }
+
fn enforce_object_limitations(&self, candidate: &Candidate) {
/*!
* There are some limitations to calling functions through an
code: traits::ObligationCauseCode,
bound: ty::BuiltinBound)
{
- self.register_obligation(
- traits::obligation_for_builtin_bound(
- self.tcx(),
- traits::ObligationCause::new(span, code),
- ty,
- bound));
+ let obligation = traits::obligation_for_builtin_bound(
+ self.tcx(),
+ traits::ObligationCause::new(span, code),
+ ty,
+ bound);
+ match obligation {
+ Ok(ob) => self.register_obligation(ob),
+ _ => {}
+ }
}
pub fn require_type_is_sized(&self,
}
}
+#[deriving(Show)]
pub enum LvaluePreference {
PreferMutLvalue,
NoPreference
check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
id, expr.span, expected);
}
+ ast::ExprIfLet(..) => {
+ tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
+ }
ast::ExprWhile(ref cond, ref body, _) => {
check_expr_has_type(fcx, &**cond, ty::mk_bool());
check_block_no_value(fcx, &**body);
fcx.write_nil(id);
}
}
- ast::ExprMatch(ref discrim, ref arms) => {
+ ast::ExprMatch(ref discrim, ref arms, _) => {
_match::check_match(fcx, expr, &**discrim, arms.as_slice());
}
ast::ExprFnBlock(_, ref decl, ref body) => {
let typ = fcx.local_ty(sp, nid);
return no_params(typ);
}
- def::DefFn(id, _) | def::DefStaticMethod(id, _, _) |
+ def::DefFn(id, _, _) | def::DefStaticMethod(id, _, _) |
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
def::DefStruct(id) => {
return ty::lookup_item_type(fcx.ccx.tcx, id);
visit::walk_expr(rcx, expr);
}
- ast::ExprMatch(ref discr, ref arms) => {
+ ast::ExprMatch(ref discr, ref arms, _) => {
link_match(rcx, &**discr, arms.as_slice());
visit::walk_expr(rcx, expr);
let cause = traits::ObligationCause::new(freevar.span, code);
let obligation = traits::obligation_for_builtin_bound(rcx.tcx(), cause,
var_ty, builtin_bound);
- rcx.fcx.inh.fulfillment_cx.borrow_mut().register_obligation(rcx.tcx(), obligation);
+ match obligation {
+ Ok(obligation) => {
+ rcx.fcx.inh.fulfillment_cx.borrow_mut().register_obligation(rcx.tcx(),
+ obligation)
+ }
+ _ => {}
+ }
}
type_must_outlive(
rcx, infer::RelateProcBound(expr.span, var_node_id, var_ty),
// object type is Foo+Send, this would create an obligation
// for the Send check.)
for builtin_bound in object_trait.bounds.builtin_bounds.iter() {
- fcx.register_obligation(
- obligation_for_builtin_bound(
+ let obligation = obligation_for_builtin_bound(
fcx.tcx(),
ObligationCause::new(span,
traits::ObjectCastObligation(object_trait_ty)),
referent_ty,
- builtin_bound));
+ builtin_bound);
+ match obligation {
+ Ok(obligation) => fcx.register_obligation(obligation),
+ _ => {}
+ }
}
object_trait_ref
if variant.fields.len() > 0 {
for field in variant.fields.init().iter() {
let cause = traits::ObligationCause::new(field.span, traits::FieldSized);
- fcx.register_obligation(
- traits::obligation_for_builtin_bound(fcx.tcx(),
- cause,
- field.ty,
- ty::BoundSized));
+ let obligation = traits::obligation_for_builtin_bound(fcx.tcx(),
+ cause,
+ field.ty,
+ ty::BoundSized);
+ match obligation {
+ Ok(obligation) => fcx.register_obligation(obligation),
+ _ => {}
+ }
}
}
}
&trait_def.bounds,
trait_ref.self_ty());
for builtin_bound in trait_def.bounds.builtin_bounds.iter() {
- fcx.register_obligation(
- traits::obligation_for_builtin_bound(fcx.tcx(),
- cause,
- trait_ref.self_ty(),
- builtin_bound));
+ let obligation = traits::obligation_for_builtin_bound(fcx.tcx(),
+ cause,
+ trait_ref.self_ty(),
+ builtin_bound);
+ match obligation {
+ Ok (obligation) => fcx.register_obligation(obligation),
+ _ => {}
+ }
}
for trait_bound in trait_def.bounds.trait_bounds.iter() {
let trait_bound = trait_bound.subst(fcx.tcx(), &trait_ref.substs);
&& !struct_tpt.generics.has_region_params(subst::TypeSpace)
{
let cause = traits::ObligationCause::new(span, traits::DropTrait);
- fcx.register_obligation(
- traits::obligation_for_builtin_bound(
- fcx.tcx(),
- cause,
- self_ty,
- ty::BoundSend));
+ let obligation = traits::obligation_for_builtin_bound(fcx.tcx(),
+ cause,
+ self_ty,
+ ty::BoundSend);
+ match obligation {
+ Ok(obligation) => fcx.register_obligation(obligation),
+ _ => {}
+ }
} else {
span_err!(fcx.tcx().sess, span, E0141,
"cannot implement a destructor on a structure \
ast::ExprMethodCall(..) => {
explain_span(cx, "method call", expr.span)
},
+ ast::ExprMatch(_, _, ast::MatchIfLetDesugar) => explain_span(cx, "if let", expr.span),
ast::ExprMatch(..) => explain_span(cx, "match", expr.span),
_ => explain_span(cx, "expression", expr.span)
}
return Ok(result);
}
-#[cfg(not(windows), test)]
+#[cfg(all(not(windows), test))]
mod test {
use std::io;
use std::io::fs::{File, symlink, mkdir, mkdir_recursive};
minimized
}
-#[cfg(unix, test)]
+#[cfg(all(unix, test))]
mod test {
use super::{RPathConfig};
use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
fn hex(b: u64) -> char {
let b = (b & 0xf) as u8;
let b = match b {
- 0 .. 9 => '0' as u8 + b,
+ 0 ... 9 => '0' as u8 + b,
_ => 'a' as u8 + b - 10,
};
b as char
ExprForLoop(..) => SawExprForLoop,
// just syntactic artifacts, expanded away by time of SVH.
+ ExprIfLet(..) => unreachable!(),
ExprMac(..) => unreachable!(),
}
}
record_extern_fqn(cx, did, clean::TypeTrait);
clean::TraitItem(build_external_trait(cx, tcx, did))
}
- def::DefFn(did, style) => {
+ def::DefFn(did, style, false) => {
// If this function is a tuple struct constructor, we just skip it
- if csearch::get_tuple_struct_definition_if_ctor(&tcx.sess.cstore,
- did).is_some() {
- return None
- }
record_extern_fqn(cx, did, clean::TypeFunction);
clean::FunctionItem(build_external_function(cx, tcx, did, style))
}
fn register_def(cx: &DocContext, def: def::Def) -> ast::DefId {
let (did, kind) = match def {
- def::DefFn(i, _) => (i, TypeFunction),
+ def::DefFn(i, _, _) => (i, TypeFunction),
def::DefTy(i, false) => (i, TypeTypedef),
def::DefTy(i, true) => (i, TypeEnum),
def::DefTrait(i) => (i, TypeTrait),
pub static F_SETLKW: libc::c_int = 9;
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
mod os {
use libc;
type Output = (clean::Crate, Vec<plugins::PluginJson> );
pub fn main() {
- // Why run rustdoc in a separate task? That's a good question!
- //
- // We first begin our adventure at the ancient commit of e7c4fb69. In this
- // commit it was discovered that the stack limit frobbing on windows ended
- // up causing some syscalls to fail. This was worked around manually in the
- // relevant location.
- //
- // Our journey now continues with #13259 where it was discovered that this
- // stack limit frobbing has the ability to affect nearly any syscall. Note
- // that the key idea here is that there is currently no knowledge as to why
- // this is happening or how to preserve it, fun times!
- //
- // Now we continue along to #16275 where it was discovered that --test on
- // windows didn't work at all! Yet curiously rustdoc worked without --test.
- // The exact reason that #16275 cropped up is that during the expansion
- // phase the compiler attempted to open libstd to read out its macros. This
- // invoked the LLVMRustOpenArchive shim which in turned went to LLVM to go
- // open a file and read it. Lo and behold this function returned an error!
- // It was then discovered that when the same fix mentioned in #13259 was
- // applied, the error went away. The plot thickens!
- //
- // Remember that rustdoc works without --test, which raises the question of
- // how because the --test and non --test paths are almost identical. The
- // first thing both paths do is parse and expand a crate! It turns out that
- // the difference is that --test runs on the *main task* while the normal
- // path runs in subtask. It turns out that running --test in a sub task also
- // fixes the problem!
- //
- // So, in summary, it is unknown why this is necessary, what it is
- // preventing, or what the actual bug is. In the meantime, this allows
- // --test to work on windows, which seems good, right? Fun times.
- let (tx, rx) = channel();
- spawn(proc() {
- std::os::set_exit_status(main_args(std::os::args().as_slice()));
- tx.send(());
- });
-
- // If the task failed, set an error'd exit status
- if rx.recv_opt().is_err() {
- std::os::set_exit_status(std::rt::DEFAULT_ERROR_CODE);
- }
+ std::os::set_exit_status(main_args(std::os::args().as_slice()));
}
pub fn opts() -> Vec<getopts::OptGroup> {
n
}
-#[cfg(not(target_os="windows"), not(target_os="macos"))]
+#[cfg(all(not(target_os="windows"), not(target_os="macos")))]
fn libname(n: String) -> String {
let mut i = String::from_str("lib");
i.push_str(n.as_slice());
/// Make a clone of the global arguments.
pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
mod imp {
use core::prelude::*;
}
}
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "windows")]
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "windows"))]
mod imp {
use core::prelude::*;
use collections::vec::Vec;
pub mod shouldnt_be_public {
#[cfg(not(test))]
pub use super::local_ptr::native::maybe_tls_key;
- #[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
+ #[cfg(all(not(windows), not(target_os = "android"), not(target_os = "ios")))]
pub use super::local_ptr::compiled::RT_TLS_PTR;
}
use libc;
-#[cfg(not(target_arch = "arm"))]
-#[cfg(target_os = "ios")]
+#[cfg(any(not(target_arch = "arm"), target_os = "ios"))]
#[repr(C)]
pub enum _Unwind_Action {
_UA_SEARCH_PHASE = 1,
#[cfg(target_arch = "x86_64")]
pub static unwinder_private_data_size: uint = 6;
-#[cfg(target_arch = "arm", not(target_os = "ios"))]
+#[cfg(all(target_arch = "arm", not(target_os = "ios")))]
pub static unwinder_private_data_size: uint = 20;
-#[cfg(target_arch = "arm", target_os = "ios")]
+#[cfg(all(target_arch = "arm", target_os = "ios"))]
pub static unwinder_private_data_size: uint = 5;
-#[cfg(target_arch = "mips")]
-#[cfg(target_arch = "mipsel")]
+#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
pub static unwinder_private_data_size: uint = 2;
#[repr(C)]
extern "C" fn(unwind_code: _Unwind_Reason_Code,
exception: *mut _Unwind_Exception);
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "freebsd")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
#[link(name = "gcc_s")]
extern {}
extern "C" {
// iOS on armv7 uses SjLj exceptions and requires to link
// against corresponding routine (..._SjLj_...)
- #[cfg(not(target_os = "ios", target_arch = "arm"))]
+ #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
-> _Unwind_Reason_Code;
- #[cfg(target_os = "ios", target_arch = "arm")]
+ #[cfg(all(target_os = "ios", target_arch = "arm"))]
fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception)
-> _Unwind_Reason_Code;
// ... and now we just providing access to SjLj counterspart
// through a standard name to hide those details from others
// (see also comment above regarding _Unwind_RaiseException)
-#[cfg(target_os = "ios", target_arch = "arm")]
+#[cfg(all(target_os = "ios", target_arch = "arm"))]
#[inline(always)]
pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception)
-> _Unwind_Reason_Code {
use core::mem;
use alloc::boxed::Box;
-#[cfg(windows)] // mingw-w32 doesn't like thread_local things
-#[cfg(target_os = "android")] // see #10686
-#[cfg(target_os = "ios")]
+#[cfg(any(windows, // mingw-w32 doesn't like thread_local things
+ target_os = "android", // see #10686
+ target_os = "ios"))]
pub use self::native::{init, cleanup, put, take, try_take, unsafe_take, exists,
unsafe_borrow, try_unsafe_borrow};
-#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
+#[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
pub use self::compiled::{init, cleanup, put, take, try_take, unsafe_take, exists,
unsafe_borrow, try_unsafe_borrow};
/// implemented using LLVM's thread_local attribute which isn't necessarily
/// working on all platforms. This implementation is faster, however, so we use
/// it wherever possible.
-#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
+#[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
pub mod compiled {
use core::prelude::*;
type pthread_mutexattr_t = libc::c_void;
type pthread_condattr_t = libc::c_void;
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
mod os {
use libc;
0 as pthread_cond_t;
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
mod os {
use libc;
#[cfg(not(windows))] #[inline(always)]
unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
- #[cfg(windows, target_arch = "x86")] #[inline(always)]
+ #[cfg(all(windows, target_arch = "x86"))] #[inline(always)]
unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
// stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile");
asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile");
}
- #[cfg(windows, target_arch = "x86_64")] #[inline(always)]
+ #[cfg(all(windows, target_arch = "x86_64"))] #[inline(always)]
unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
// stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
return target_record_sp_limit(limit);
// x86-64
- #[cfg(target_arch = "x86_64", target_os = "macos")]
- #[cfg(target_arch = "x86_64", target_os = "ios")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64",
+ any(target_os = "macos", target_os = "ios")))]
+ #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
asm!("movq $$0x60+90*8, %rsi
movq $0, %gs:(%rsi)" :: "r"(limit) : "rsi" : "volatile")
}
- #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "linux"))] #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile")
}
- #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
- // store this inside of the "arbitrary data slot", but double the size
- // because this is 64 bit instead of 32 bit
- asm!("movq $0, %gs:0x28" :: "r"(limit) :: "volatile")
+ #[cfg(all(target_arch = "x86_64", target_os = "windows"))] #[inline(always)]
+ unsafe fn target_record_sp_limit(_: uint) {
}
- #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "freebsd"))] #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
asm!("movq $0, %fs:24" :: "r"(limit) :: "volatile")
}
- #[cfg(target_arch = "x86_64", target_os = "dragonfly")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "dragonfly"))] #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
asm!("movq $0, %fs:32" :: "r"(limit) :: "volatile")
}
// x86
- #[cfg(target_arch = "x86", target_os = "macos")]
- #[cfg(target_arch = "x86", target_os = "ios")] #[inline(always)]
+ #[cfg(all(target_arch = "x86",
+ any(target_os = "macos", target_os = "ios")))]
+ #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
asm!("movl $$0x48+90*4, %eax
movl $0, %gs:(%eax)" :: "r"(limit) : "eax" : "volatile")
}
- #[cfg(target_arch = "x86", target_os = "linux")]
- #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
+ #[cfg(all(target_arch = "x86",
+ any(target_os = "linux", target_os = "freebsd")))]
+ #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile")
}
- #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
- // store this inside of the "arbitrary data slot"
- asm!("movl $0, %fs:0x14" :: "r"(limit) :: "volatile")
+ #[cfg(all(target_arch = "x86", target_os = "windows"))] #[inline(always)]
+ unsafe fn target_record_sp_limit(_: uint) {
}
// mips, arm - Some brave soul can port these to inline asm, but it's over
// my head personally
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
- #[cfg(target_arch = "arm", not(target_os = "ios"))] #[inline(always)]
+ #[cfg(any(target_arch = "mips",
+ target_arch = "mipsel",
+ all(target_arch = "arm", not(target_os = "ios"))))]
+ #[inline(always)]
unsafe fn target_record_sp_limit(limit: uint) {
use libc::c_void;
return record_sp_limit(limit as *const c_void);
}
// iOS segmented stack is disabled for now, see related notes
- #[cfg(target_arch = "arm", target_os = "ios")] #[inline(always)]
+ #[cfg(all(target_arch = "arm", target_os = "ios"))] #[inline(always)]
unsafe fn target_record_sp_limit(_: uint) {
}
}
return target_get_sp_limit();
// x86-64
- #[cfg(target_arch = "x86_64", target_os = "macos")]
- #[cfg(target_arch = "x86_64", target_os = "ios")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64",
+ any(target_os = "macos", target_os = "ios")))]
+ #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
let limit;
asm!("movq $$0x60+90*8, %rsi
movq %gs:(%rsi), $0" : "=r"(limit) :: "rsi" : "volatile");
return limit;
}
- #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "linux"))] #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
let limit;
asm!("movq %fs:112, $0" : "=r"(limit) ::: "volatile");
return limit;
}
- #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "windows"))] #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile");
- return limit;
+ return 1024;
}
- #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "freebsd"))] #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
let limit;
asm!("movq %fs:24, $0" : "=r"(limit) ::: "volatile");
return limit;
}
- #[cfg(target_arch = "x86_64", target_os = "dragonfly")] #[inline(always)]
+ #[cfg(all(target_arch = "x86_64", target_os = "dragonfly"))] #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
let limit;
asm!("movq %fs:32, $0" : "=r"(limit) ::: "volatile");
// x86
- #[cfg(target_arch = "x86", target_os = "macos")]
- #[cfg(target_arch = "x86", target_os = "ios")] #[inline(always)]
+ #[cfg(all(target_arch = "x86",
+ any(target_os = "macos", target_os = "ios")))]
+ #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
let limit;
asm!("movl $$0x48+90*4, %eax
movl %gs:(%eax), $0" : "=r"(limit) :: "eax" : "volatile");
return limit;
}
- #[cfg(target_arch = "x86", target_os = "linux")]
- #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
+ #[cfg(all(target_arch = "x86",
+ any(target_os = "linux", target_os = "freebsd")))]
+ #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
let limit;
asm!("movl %gs:48, $0" : "=r"(limit) ::: "volatile");
return limit;
}
- #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)]
+ #[cfg(all(target_arch = "x86", target_os = "windows"))] #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile");
- return limit;
+ return 1024;
}
// mips, arm - Some brave soul can port these to inline asm, but it's over
// my head personally
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "mipsel")]
- #[cfg(target_arch = "arm", not(target_os = "ios"))] #[inline(always)]
+ #[cfg(any(target_arch = "mips",
+ target_arch = "mipsel",
+ all(target_arch = "arm", not(target_os = "ios"))))]
+ #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
use libc::c_void;
return get_sp_limit() as uint;
// iOS doesn't support segmented stacks yet. This function might
// be called by runtime though so it is unsafe to mark it as
// unreachable, let's return a fixed constant.
- #[cfg(target_arch = "arm", target_os = "ios")] #[inline(always)]
+ #[cfg(all(target_arch = "arm", target_os = "ios"))] #[inline(always)]
unsafe fn target_get_sp_limit() -> uint {
1024
}
#[allow(non_camel_case_types)] // foreign type
type pthread_key_t = ::libc::c_ulong;
-#[cfg(target_os="linux")]
-#[cfg(target_os="freebsd")]
-#[cfg(target_os="dragonfly")]
-#[cfg(target_os="android")]
-#[cfg(target_os = "ios")]
+#[cfg(any(target_os="linux",
+ target_os="freebsd",
+ target_os="dragonfly",
+ target_os="android",
+ target_os = "ios"))]
#[allow(non_camel_case_types)] // foreign type
type pthread_key_t = ::libc::c_uint;
//
// See also: rt/rust_try.ll
-#[cfg(not(target_arch = "arm"), not(windows, target_arch = "x86_64"), not(test))]
+#[cfg(all(not(target_arch = "arm"),
+ not(all(windows, target_arch = "x86_64")),
+ not(test)))]
#[doc(hidden)]
pub mod eabi {
use libunwind as uw;
// iOS on armv7 is using SjLj exceptions and therefore requires to use
// a specialized personality routine: __gcc_personality_sj0
-#[cfg(target_os = "ios", target_arch = "arm", not(test))]
+#[cfg(all(target_os = "ios", target_arch = "arm", not(test)))]
#[doc(hidden)]
pub mod eabi {
use libunwind as uw;
// ARM EHABI uses a slightly different personality routine signature,
// but otherwise works the same.
-#[cfg(target_arch = "arm", not(target_os = "ios"), not(test))]
+#[cfg(all(target_arch = "arm", not(target_os = "ios"), not(test)))]
#[doc(hidden)]
pub mod eabi {
use libunwind as uw;
// GCC reuses the same personality routine as for the other architectures by wrapping it
// with an "API translator" layer (_GCC_specific_handler).
-#[cfg(windows, target_arch = "x86_64", not(test))]
+#[cfg(all(windows, target_arch = "x86_64", not(test)))]
#[doc(hidden)]
#[allow(non_camel_case_types, non_snake_case)]
pub mod eabi {
// libuv doesn't use pthread on windows
// android libc (bionic) provides pthread, so no additional link is required
-#[cfg(not(windows), not(target_os = "android"))]
+#[cfg(not(any(windows, target_os = "android")))]
#[link(name = "pthread")]
extern {}
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "linux", target_os = "dragonfly"))]
#[link(name = "rt")]
extern {}
#[link(name = "iphlpapi")]
extern {}
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
#[link(name = "kvm")]
extern {}
let val = byte as u32;
match byte {
- b'A'..b'Z' => buf |= val - 0x41,
- b'a'..b'z' => buf |= val - 0x47,
- b'0'..b'9' => buf |= val + 0x04,
+ b'A'...b'Z' => buf |= val - 0x41,
+ b'a'...b'z' => buf |= val - 0x47,
+ b'0'...b'9' => buf |= val + 0x04,
b'+' | b'-' => buf |= 0x3E,
b'/' | b'_' => buf |= 0x3F,
b'\r' | b'\n' => continue,
buf <<= 4;
match byte {
- b'A'..b'F' => buf |= byte - b'A' + 10,
- b'a'..b'f' => buf |= byte - b'a' + 10,
- b'0'..b'9' => buf |= byte - b'0',
+ b'A'...b'F' => buf |= byte - b'A' + 10,
+ b'a'...b'f' => buf |= byte - b'a' + 10,
+ b'0'...b'9' => buf |= byte - b'0',
b' '|b'\r'|b'\n'|b'\t' => {
buf >>= 4;
continue
// A leading '0' must be the only digit before the decimal point.
match self.ch_or_null() {
- '0' .. '9' => return self.error(InvalidNumber),
+ '0' ... '9' => return self.error(InvalidNumber),
_ => ()
}
},
- '1' .. '9' => {
+ '1' ... '9' => {
while !self.eof() {
match self.ch_or_null() {
- c @ '0' .. '9' => {
+ c @ '0' ... '9' => {
accum *= 10;
accum += (c as u64) - ('0' as u64);
// Make sure a digit follows the decimal place.
match self.ch_or_null() {
- '0' .. '9' => (),
+ '0' ... '9' => (),
_ => return self.error(InvalidNumber)
}
let mut dec = 1.0;
while !self.eof() {
match self.ch_or_null() {
- c @ '0' .. '9' => {
+ c @ '0' ... '9' => {
dec /= 10.0;
res += (((c as int) - ('0' as int)) as f64) * dec;
self.bump();
// Make sure a digit follows the exponent place.
match self.ch_or_null() {
- '0' .. '9' => (),
+ '0' ... '9' => (),
_ => return self.error(InvalidNumber)
}
while !self.eof() {
match self.ch_or_null() {
- c @ '0' .. '9' => {
+ c @ '0' ... '9' => {
exp *= 10;
exp += (c as uint) - ('0' as uint);
while i < 4 && !self.eof() {
self.bump();
n = match self.ch_or_null() {
- c @ '0' .. '9' => n * 16 + ((c as u16) - ('0' as u16)),
+ c @ '0' ... '9' => n * 16 + ((c as u16) - ('0' as u16)),
'a' | 'A' => n * 16 + 10,
'b' | 'B' => n * 16 + 11,
'c' | 'C' => n * 16 + 12,
'r' => res.push('\r'),
't' => res.push('\t'),
'u' => match try!(self.decode_hex_escape()) {
- 0xDC00 .. 0xDFFF => return self.error(LoneLeadingSurrogateInHexEscape),
+ 0xDC00 ... 0xDFFF => {
+ return self.error(LoneLeadingSurrogateInHexEscape)
+ }
// Non-BMP characters are encoded as a sequence of
// two hex escapes, representing UTF-16 surrogates.
- n1 @ 0xD800 .. 0xDBFF => {
+ n1 @ 0xD800 ... 0xDBFF => {
match (self.next_char(), self.next_char()) {
(Some('\\'), Some('u')) => (),
_ => return self.error(UnexpectedEndOfHexEscape),
'n' => { self.parse_ident("ull", NullValue) }
't' => { self.parse_ident("rue", BooleanValue(true)) }
'f' => { self.parse_ident("alse", BooleanValue(false)) }
- '0' .. '9' | '-' => self.parse_number(),
+ '0' ... '9' | '-' => self.parse_number(),
'"' => match self.parse_str() {
Ok(s) => StringValue(s),
Err(e) => Error(e),
}
}
-#[cfg(test, not(target_os = "ios"))]
+#[cfg(all(test, not(target_os = "ios")))]
mod test {
use super::*;
use prelude::*;
}
#[test]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "linux",
+ target_os = "macos",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
fn test_errors_do_not_crash() {
// Open /dev/null as a library to get an error, and make sure
// that only causes an error, and not a crash.
}
}
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
pub mod dl {
use c_str::{CString, ToCStr};
// Ignored on android since we cannot give tcp/ip
// permission without help of apk
-#[cfg(test, not(target_os = "android"))]
+#[cfg(all(test, not(target_os = "android")))]
mod test {
iotest!(fn dns_smoke_test() {
let ipaddrs = get_host_addresses("localhost").unwrap();
drop(p.wait().clone());
})
- #[cfg(unix, not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
iotest!(fn signal_reported_right() {
let p = Command::new("/bin/sh").arg("-c").arg("kill -1 $$").spawn();
assert!(p.is_ok());
assert_eq!(run_output(cmd), "foobar\n".to_string());
})
- #[cfg(unix, not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
iotest!(fn set_cwd_works() {
let mut cmd = Command::new("/bin/sh");
cmd.arg("-c").arg("pwd")
assert_eq!(run_output(cmd), "/\n".to_string());
})
- #[cfg(unix, not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
iotest!(fn stdin_works() {
let mut p = Command::new("/bin/sh")
.arg("-c").arg("read line; echo $line")
assert!(Command::new("test").uid(10).spawn().is_err());
})
- #[cfg(unix, not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
iotest!(fn uid_works() {
use libc;
let mut p = Command::new("/bin/sh")
assert!(p.wait().unwrap().success());
})
- #[cfg(unix, not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
iotest!(fn uid_to_root_fails() {
use libc;
}
})
- #[cfg(unix,not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
pub fn pwd_cmd() -> Command {
Command::new("pwd")
}
assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
})
- #[cfg(unix,not(target_os="android"))]
+ #[cfg(all(unix, not(target_os="android")))]
pub fn env_cmd() -> Command {
Command::new("env")
}
}
}
-#[cfg(test, unix)]
+#[cfg(all(test, unix))]
mod test_unix {
use prelude::*;
use libc;
}
}
-#[cfg(test, windows)]
+#[cfg(all(test, windows))]
mod test_windows {
use super::{User1, Listener};
use result::{Ok, Err};
current_digit_signed
};
buf[cur] = match current_digit.to_u8().unwrap() {
- i @ 0..9 => b'0' + i,
- i => b'a' + (i - 10),
+ i @ 0...9 => b'0' + i,
+ i => b'a' + (i - 10),
};
cur += 1;
/// ```
pub fn self_exe_name() -> Option<Path> {
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
fn load_self() -> Option<Vec<u8>> {
unsafe {
use libc::funcs::bsd44::*;
}
}
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
fn load_self() -> Option<Vec<u8>> {
use std::io;
}
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
fn load_self() -> Option<Vec<u8>> {
unsafe {
use libc::funcs::extra::_NSGetExecutablePath;
#[cfg(unix)]
/// Returns the platform-specific value of errno
pub fn errno() -> int {
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "freebsd")]
+ #[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "freebsd"))]
fn errno_location() -> *const c_int {
extern {
fn __error() -> *const c_int;
}
}
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
fn errno_location() -> *const c_int {
extern {
fn __errno_location() -> *const c_int;
#[cfg(unix)]
fn strerror(errnum: uint) -> String {
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "dragonfly")]
+ #[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t)
-> c_int {
extern {
res
}
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "dragonfly")]
+#[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
fn real_args_as_bytes() -> Vec<Vec<u8>> {
use rt;
pub use self::imp::OsRng;
-#[cfg(unix, not(target_os = "ios"))]
+#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
use io::{IoResult, File};
use path::Path;
use os;
use rand::Rng;
use result::{Ok, Err};
- use rt::stack;
use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
use self::libc::types::os::arch::extra::{LONG_PTR};
use slice::MutableSlice;
static PROV_RSA_FULL: DWORD = 1;
static CRYPT_SILENT: DWORD = 64;
static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
- static NTE_BAD_SIGNATURE: DWORD = 0x80090006;
#[allow(non_snake_case)]
extern "system" {
/// Create a new `OsRng`.
pub fn new() -> IoResult<OsRng> {
let mut hcp = 0;
- let mut ret = unsafe {
+ let ret = unsafe {
CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
};
- // FIXME #13259:
- // It turns out that if we can't acquire a context with the
- // NTE_BAD_SIGNATURE error code, the documentation states:
- //
- // The provider DLL signature could not be verified. Either the
- // DLL or the digital signature has been tampered with.
- //
- // Sounds fishy, no? As it turns out, our signature can be bad
- // because our Thread Information Block (TIB) isn't exactly what it
- // expects. As to why, I have no idea. The only data we store in the
- // TIB is the stack limit for each thread, but apparently that's
- // enough to make the signature valid.
- //
- // Furthermore, this error only happens the *first* time we call
- // CryptAcquireContext, so we don't have to worry about future
- // calls.
- //
- // Anyway, the fix employed here is that if we see this error, we
- // pray that we're not close to the end of the stack, temporarily
- // set the stack limit to 0 (what the TIB originally was), acquire a
- // context, and then reset the stack limit.
- //
- // Again, I'm not sure why this is the fix, nor why we're getting
- // this error. All I can say is that this seems to allow libnative
- // to progress where it otherwise would be hindered. Who knew?
- if ret == 0 && os::errno() as DWORD == NTE_BAD_SIGNATURE {
- unsafe {
- let limit = stack::get_sp_limit();
- stack::record_sp_limit(0);
- ret = CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
- stack::record_sp_limit(limit);
- }
- }
-
if ret == 0 {
Err(IoError::last_error())
} else {
/// play well with green threads, so while it is extremely nice
/// and simple to use it should be used only on iOS devices as the
/// only viable option.
- #[cfg(target_os = "ios", target_arch = "arm")]
+ #[cfg(all(target_os = "ios", target_arch = "arm"))]
#[inline(never)]
pub fn write(w: &mut Writer) -> IoResult<()> {
use iter::{Iterator, range};
result::fold(iter, (), |_, _| ())
}
- #[cfg(not(target_os = "ios", target_arch = "arm"))]
+ #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
#[inline(never)] // if we know this is a function call, we can skip it when
// tracing
pub fn write(w: &mut Writer) -> IoResult<()> {
}
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
use intrinsics;
#[repr(C)]
}
}
- #[cfg(not(target_os = "macos"), not(target_os = "ios"))]
+ #[cfg(not(any(target_os = "macos", target_os = "ios")))]
fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
use collections::Collection;
use iter::Iterator;
extern {
// No native _Unwind_Backtrace on iOS
- #[cfg(not(target_os = "ios", target_arch = "arm"))]
+ #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
trace_argument: *mut libc::c_void)
-> _Unwind_Reason_Code;
- #[cfg(not(target_os = "android"),
- not(target_os = "linux", target_arch = "arm"))]
+ #[cfg(all(not(target_os = "android"),
+ not(all(target_os = "linux", target_arch = "arm"))))]
pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
- #[cfg(not(target_os = "android"),
- not(target_os = "linux", target_arch = "arm"))]
+
+ #[cfg(all(not(target_os = "android"),
+ not(all(target_os = "linux", target_arch = "arm"))))]
pub fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void)
-> *mut libc::c_void;
}
// On android, the function _Unwind_GetIP is a macro, and this is the
// expansion of the macro. This is all copy/pasted directly from the
// header file with the definition of _Unwind_GetIP.
- #[cfg(target_os = "android")]
- #[cfg(target_os = "linux", target_arch = "arm")]
+ #[cfg(any(target_os = "android",
+ all(target_os = "linux", target_arch = "arm")))]
pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
#[repr(C)]
enum _Unwind_VRS_Result {
// This function also doesn't exist on Android or ARM/Linux, so make it
// a no-op
- #[cfg(target_os = "android")]
- #[cfg(target_os = "linux", target_arch = "arm")]
+ #[cfg(any(target_os = "android",
+ all(target_os = "linux", target_arch = "arm")))]
pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void)
-> *mut libc::c_void
{
ExprLit(P<Lit>),
ExprCast(P<Expr>, P<Ty>),
ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
+ ExprIfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
ExprWhile(P<Expr>, P<Block>, Option<Ident>),
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
// Conditionless loop (can be exited with break, cont, or ret)
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
ExprLoop(P<Block>, Option<Ident>),
- ExprMatch(P<Expr>, Vec<Arm>),
+ ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
ExprFnBlock(CaptureClause, P<FnDecl>, P<Block>),
ExprProc(P<FnDecl>, P<Block>),
ExprUnboxedFn(CaptureClause, UnboxedClosureKind, P<FnDecl>, P<Block>),
pub item_name: Ident,
}
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum MatchSource {
+ MatchNormal,
+ MatchIfLetDesugar
+}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum CaptureClause {
CaptureByValue,
ast::MetaList(ref pred, ref mis) if pred.get() == "all" =>
mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
ast::MetaList(ref pred, ref mis) if pred.get() == "not" => {
- // NOTE: turn on after snapshot
- /*
if mis.len() != 1 {
diagnostic.span_warn(cfg.span, "the use of multiple cfgs in the same `not` \
statement is deprecated. Change `not(a, b)` to \
`not(all(a, b))`.");
}
- */
!mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi))
}
ast::MetaList(ref pred, _) => {
}
}
-#[deriving(PartialEq, Show)]
+#[deriving(PartialEq, Show, Encodable, Decodable)]
pub enum ReprAttr {
ReprAny,
ReprInt(Span, IntType),
}
}
-#[deriving(Eq, Hash, PartialEq, Show)]
+#[deriving(Eq, Hash, PartialEq, Show, Encodable, Decodable)]
pub enum IntType {
SignedInt(ast::IntTy),
UnsignedInt(ast::UintTy)
}
/// get a line from the list of pre-computed line-beginnings
+ ///
+ /// NOTE(stage0, pcwalton): Remove `#[allow(unused_mut)]` after snapshot.
+ #[allow(unused_mut)]
pub fn get_line(&self, line: int) -> String {
let mut lines = self.lines.borrow_mut();
let begin: BytePos = *lines.get(line as uint) - self.start_pos;
return a;
}
+ // NOTE(stage0, pcwalton): Remove `#[allow(unused_mut)]` after snapshot.
+ #[allow(unused_mut)]
fn lookup_line(&self, pos: BytePos) -> FileMapAndLine {
let idx = self.lookup_filemap_idx(pos);
fold::noop_fold_expr(ast::Expr {
id: id,
node: match node {
- ast::ExprMatch(m, arms) => {
+ ast::ExprMatch(m, arms, source) => {
ast::ExprMatch(m, arms.into_iter()
.filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
- .collect())
+ .collect(), source)
}
_ => node
},
_ => continue
};
- // NOTE: turn on after snapshot
- /*
if mis.len() != 1 {
diagnostic.span_warn(attr.span, "The use of multiple cfgs in the top level of \
`#[cfg(..)]` is deprecated. Change `#[cfg(a, b)]` to \
the intersection of the cfgs. Change `#[cfg(a)] \
#[cfg(b)]` to `#[cfg(any(a, b))]`.");
}
- */
seen_cfg = true;
in_cfg |= mis.iter().all(|mi| attr::cfg_matches(diagnostic, cfg, &**mi));
}
fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> {
- self.expr(span, ast::ExprMatch(arg, arms))
+ self.expr(span, ast::ExprMatch(arg, arms, ast::MatchNormal))
}
fn expr_if(&self, span: Span, cond: P<ast::Expr>,
p.expect(&token::COMMA);
}
- // NOTE: turn on after snapshot
- /*
if cfgs.len() != 1 {
cx.span_warn(sp, "The use of multiple cfgs at the top level of `cfg!` \
is deprecated. Change `cfg!(a, b)` to \
`cfg!(all(a, b))`.");
}
- */
let matches_cfg = cfgs.iter().all(|cfg| attr::cfg_matches(&cx.parse_sess.span_diagnostic,
cx.cfg.as_slice(), &**cfg));
e.and_then(|ast::Expr {id, node, span}| match node {
// expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions.
- ExprMac(mac) => {
+ ast::ExprMac(mac) => {
let expanded_expr = match expand_mac_invoc(mac, span,
|r| r.make_expr(),
mark_expr, fld) {
fld.cx.expr(span, ast::ExprWhile(cond, body, opt_ident))
}
+ // Desugar ExprIfLet
+ // From: `if let <pat> = <expr> <body> [<elseopt>]`
+ ast::ExprIfLet(pat, expr, body, mut elseopt) => {
+ // to:
+ //
+ // match <expr> {
+ // <pat> => <body>,
+ // [_ if <elseopt_if_cond> => <elseopt_if_body>,]
+ // _ => [<elseopt> | ()]
+ // }
+
+ // `<pat> => <body>`
+ let pat_arm = {
+ let body_expr = fld.cx.expr_block(body);
+ fld.cx.arm(pat.span, vec![pat], body_expr)
+ };
+
+ // `[_ if <elseopt_if_cond> => <elseopt_if_body>,]`
+ let else_if_arms = {
+ let mut arms = vec![];
+ loop {
+ let elseopt_continue = elseopt
+ .and_then(|els| els.and_then(|els| match els.node {
+ // else if
+ ast::ExprIf(cond, then, elseopt) => {
+ let pat_under = fld.cx.pat_wild(span);
+ arms.push(ast::Arm {
+ attrs: vec![],
+ pats: vec![pat_under],
+ guard: Some(cond),
+ body: fld.cx.expr_block(then)
+ });
+ elseopt.map(|elseopt| (elseopt, true))
+ }
+ _ => Some((P(els), false))
+ }));
+ match elseopt_continue {
+ Some((e, true)) => {
+ elseopt = Some(e);
+ }
+ Some((e, false)) => {
+ elseopt = Some(e);
+ break;
+ }
+ None => {
+ elseopt = None;
+ break;
+ }
+ }
+ }
+ arms
+ };
+
+ // `_ => [<elseopt> | ()]`
+ let else_arm = {
+ let pat_under = fld.cx.pat_wild(span);
+ let else_expr = elseopt.unwrap_or_else(|| fld.cx.expr_lit(span, ast::LitNil));
+ fld.cx.arm(span, vec![pat_under], else_expr)
+ };
+
+ let mut arms = Vec::with_capacity(else_if_arms.len() + 2);
+ arms.push(pat_arm);
+ arms.push_all_move(else_if_arms);
+ arms.push(else_arm);
+
+ let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, arms, ast::MatchIfLetDesugar));
+ fld.fold_expr(match_expr)
+ }
+
+ // Desugar support for ExprIfLet in the ExprIf else position
+ ast::ExprIf(cond, blk, elseopt) => {
+ let elseopt = elseopt.map(|els| els.and_then(|els| match els.node {
+ ast::ExprIfLet(..) => {
+ // wrap the if-let expr in a block
+ let span = els.span;
+ let blk = P(ast::Block {
+ view_items: vec![],
+ stmts: vec![],
+ expr: Some(P(els)),
+ id: ast::DUMMY_NODE_ID,
+ rules: ast::DefaultBlock,
+ span: span
+ });
+ fld.cx.expr_block(blk)
+ }
+ _ => P(els)
+ }));
+ let if_expr = fld.cx.expr(span, ast::ExprIf(cond, blk, elseopt));
+ if_expr.map(|e| noop_fold_expr(e, fld))
+ }
+
ast::ExprLoop(loop_block, opt_ident) => {
let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld);
fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident))
("associated_types", Active),
("visible_private_types", Active),
+ ("if_let", Active),
+
// if you change this list without updating src/doc/rust.md, cmr will be sad
// A temporary feature gate used to enable parser extensions needed
e.span,
"tuple indexing is experimental");
}
+ ast::ExprIfLet(..) => {
+ self.gate_feature("if_let", e.span,
+ "`if let` syntax is experimental");
+ }
_ => {}
}
visit::walk_expr(self, e);
folder.fold_block(tr),
fl.map(|x| folder.fold_expr(x)))
}
+ ExprIfLet(pat, expr, tr, fl) => {
+ ExprIfLet(folder.fold_pat(pat),
+ folder.fold_expr(expr),
+ folder.fold_block(tr),
+ fl.map(|x| folder.fold_expr(x)))
+ }
ExprWhile(cond, body, opt_ident) => {
ExprWhile(folder.fold_expr(cond),
folder.fold_block(body),
ExprLoop(folder.fold_block(body),
opt_ident.map(|i| folder.fold_ident(i)))
}
- ExprMatch(expr, arms) => {
+ ExprMatch(expr, arms, source) => {
ExprMatch(folder.fold_expr(expr),
- arms.move_map(|x| folder.fold_arm(x)))
+ arms.move_map(|x| folder.fold_arm(x)),
+ source)
}
ExprFnBlock(capture_clause, decl, body) => {
ExprFnBlock(capture_clause,
pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
match e.node {
ast::ExprIf(..)
+ | ast::ExprIfLet(..)
| ast::ExprMatch(..)
| ast::ExprBlock(_)
| ast::ExprWhile(..)
'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2); }
'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8); }
'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16); }
- '0'..'9' | '_' | '.' => {
+ '0'...'9' | '_' | '.' => {
num_digits = self.scan_digits(10) + 1;
}
'u' | 'i' => {
use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
use ast::{ExprBreak, ExprCall, ExprCast};
-use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex, ExprSlice};
+use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
use ast::{ExprLit, ExprLoop, ExprMac};
use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
use ast::{LifetimeDef, Lit, Lit_};
use ast::{LitBool, LitChar, LitByte, LitBinary};
use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
-use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
+use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal, MatchNormal};
use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
/// If the next token is the given keyword, eat it and return
/// true. Otherwise, return false.
pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
- match self.token {
- token::IDENT(sid, false) if kw.to_name() == sid.name => {
- self.bump();
- true
- }
- _ => false
+ if self.is_keyword(kw) {
+ self.bump();
+ true
+ } else {
+ false
}
}
}
}
- /// Parse an 'if' expression ('if' token already eaten)
+ /// Parse an 'if' or 'if let' expression ('if' token already eaten)
pub fn parse_if_expr(&mut self) -> P<Expr> {
+ if self.is_keyword(keywords::Let) {
+ return self.parse_if_let_expr();
+ }
let lo = self.last_span.lo;
let cond = self.parse_expr_res(RestrictionNoStructLiteral);
let thn = self.parse_block();
self.mk_expr(lo, hi, ExprIf(cond, thn, els))
}
+ /// Parse an 'if let' expression ('if' token already eaten)
+ pub fn parse_if_let_expr(&mut self) -> P<Expr> {
+ let lo = self.last_span.lo;
+ self.expect_keyword(keywords::Let);
+ let pat = self.parse_pat();
+ self.expect(&token::EQ);
+ let expr = self.parse_expr_res(RestrictionNoStructLiteral);
+ let thn = self.parse_block();
+ let (hi, els) = if self.eat_keyword(keywords::Else) {
+ let expr = self.parse_else_expr();
+ (expr.span.hi, Some(expr))
+ } else {
+ (thn.span.hi, None)
+ };
+ self.mk_expr(lo, hi, ExprIfLet(pat, expr, thn, els))
+ }
+
// `|args| expr`
pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
-> P<Expr> {
}
let hi = self.span.hi;
self.bump();
- return self.mk_expr(lo, hi, ExprMatch(discriminant, arms));
+ return self.mk_expr(lo, hi, ExprMatch(discriminant, arms, MatchNormal));
}
pub fn parse_arm(&mut self) -> Arm {
// These expressions are limited to literals (possibly
// preceded by unary-minus) or identifiers.
let val = self.parse_literal_maybe_minus();
- // FIXME(#17295) remove the DOTDOT option.
- if (self.token == token::DOTDOTDOT || self.token == token::DOTDOT) &&
+ if (self.token == token::DOTDOTDOT) &&
self.look_ahead(1, |t| {
*t != token::COMMA && *t != token::RBRACKET
}) {
}
});
- // FIXME(#17295) remove the DOTDOT option.
- if self.look_ahead(1, |t| *t == token::DOTDOTDOT || *t == token::DOTDOT) &&
+ if self.look_ahead(1, |t| *t == token::DOTDOTDOT) &&
self.look_ahead(2, |t| {
*t != token::COMMA && *t != token::RBRACKET
}) {
let start = self.parse_expr_res(RestrictionNoBarOp);
- // FIXME(#17295) remove the DOTDOT option (self.eat(&token::DOTDOTDOT)).
- if self.token == token::DOTDOTDOT || self.token == token::DOTDOT {
- self.bump();
- }
+ self.eat(&token::DOTDOTDOT);
let end = self.parse_expr_res(RestrictionNoBarOp);
pat = PatRange(start, end);
} else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
try!(self.print_block(&**then));
self.print_else(e.as_ref().map(|e| &**e))
}
+ // "another else-if-let"
+ ast::ExprIfLet(ref pat, ref expr, ref then, ref e) => {
+ try!(self.cbox(indent_unit - 1u));
+ try!(self.ibox(0u));
+ try!(word(&mut self.s, " else if let "));
+ try!(self.print_pat(&**pat));
+ try!(space(&mut self.s));
+ try!(self.word_space("="));
+ try!(self.print_expr(&**expr));
+ try!(space(&mut self.s));
+ try!(self.print_block(&**then));
+ self.print_else(e.as_ref().map(|e| &**e))
+ }
// "final else"
ast::ExprBlock(ref b) => {
try!(self.cbox(indent_unit - 1u));
}
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
- elseopt: Option<&ast::Expr>, chk: bool) -> IoResult<()> {
+ elseopt: Option<&ast::Expr>) -> IoResult<()> {
try!(self.head("if"));
- if chk { try!(self.word_nbsp("check")); }
try!(self.print_expr(test));
try!(space(&mut self.s));
try!(self.print_block(blk));
self.print_else(elseopt)
}
+ pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
+ elseopt: Option<&ast::Expr>) -> IoResult<()> {
+ try!(self.head("if let"));
+ try!(self.print_pat(pat));
+ try!(space(&mut self.s));
+ try!(self.word_space("="));
+ try!(self.print_expr(expr));
+ try!(space(&mut self.s));
+ try!(self.print_block(blk));
+ self.print_else(elseopt)
+ }
+
pub fn print_mac(&mut self, m: &ast::Mac) -> IoResult<()> {
match m.node {
// I think it's reasonable to hide the ctxt here:
try!(self.print_type(&**ty));
}
ast::ExprIf(ref test, ref blk, ref elseopt) => {
- try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e), false));
+ try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e)));
+ }
+ ast::ExprIfLet(ref pat, ref expr, ref blk, ref elseopt) => {
+ try!(self.print_if_let(&**pat, &**expr, &** blk, elseopt.as_ref().map(|e| &**e)));
}
ast::ExprWhile(ref test, ref blk, opt_ident) => {
for ident in opt_ident.iter() {
try!(space(&mut self.s));
try!(self.print_block(&**blk));
}
- ast::ExprMatch(ref expr, ref arms) => {
+ ast::ExprMatch(ref expr, ref arms, _) => {
try!(self.cbox(indent_unit));
try!(self.ibox(4));
try!(self.word_nbsp("match"));
visitor.visit_expr(&**subexpression);
visitor.visit_block(&**block)
}
+ ExprIfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => {
+ visitor.visit_pat(&**pattern);
+ visitor.visit_expr(&**subexpression);
+ visitor.visit_block(&**if_block);
+ walk_expr_opt(visitor, optional_else);
+ }
ExprForLoop(ref pattern, ref subexpression, ref block, _) => {
visitor.visit_pat(&**pattern);
visitor.visit_expr(&**subexpression);
visitor.visit_block(&**block)
}
ExprLoop(ref block, _) => visitor.visit_block(&**block),
- ExprMatch(ref subexpression, ref arms) => {
+ ExprMatch(ref subexpression, ref arms, _) => {
visitor.visit_expr(&**subexpression);
for arm in arms.iter() {
visitor.visit_arm(arm)
if res.is_err() { return res }
output.push_all(res.unwrap().as_slice())
} else { return Err("stack is empty".to_string()) },
- ':'|'#'|' '|'.'|'0'..'9' => {
+ ':'|'#'|' '|'.'|'0'...'9' => {
let mut flags = Flags::new();
let mut fstate = FormatStateFlags;
match cur {
'#' => flags.alternate = true,
' ' => flags.space = true,
'.' => fstate = FormatStatePrecision,
- '0'..'9' => {
+ '0'...'9' => {
flags.width = cur as uint - '0' as uint;
fstate = FormatStateWidth;
}
stack.push(Number(i));
state = Nothing;
}
- '0'..'9' => {
+ '0'...'9' => {
state = IntConstant(i*10 + (cur as int - '0' as int));
old_state = Nothing;
}
(FormatStateFlags,' ') => {
flags.space = true;
}
- (FormatStateFlags,'0'..'9') => {
+ (FormatStateFlags,'0'...'9') => {
flags.width = cur as uint - '0' as uint;
*fstate = FormatStateWidth;
}
(FormatStateFlags,'.') => {
*fstate = FormatStatePrecision;
}
- (FormatStateWidth,'0'..'9') => {
+ (FormatStateWidth,'0'...'9') => {
let old = flags.width;
flags.width = flags.width * 10 + (cur as uint - '0' as uint);
if flags.width < old { return Err("format width overflow".to_string()) }
(FormatStateWidth,'.') => {
*fstate = FormatStatePrecision;
}
- (FormatStatePrecision,'0'..'9') => {
+ (FormatStatePrecision,'0'...'9') => {
let old = flags.precision;
flags.precision = flags.precision * 10 + (cur as uint - '0' as uint);
if flags.precision < old {
}
}
-#[cfg(unix, not(target_os = "macos"), not(target_os = "ios"))]
+#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios")))]
mod imp {
use libc::{c_int, timespec};
}
}
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "ios")]
+#[cfg(any(target_os = "macos", target_os = "ios"))]
mod imp {
use libc::{timeval, timezone, c_int, mach_timebase_info};
((ns_since_1970 % 1000000) * 1000) as i32)
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
unsafe fn os_get_time() -> (i64, i32) {
use std::ptr;
let mut tv = libc::timeval { tv_sec: 0, tv_usec: 0 };
(tv.tv_sec as i64, tv.tv_usec * 1000)
}
- #[cfg(not(target_os = "macos"), not(target_os = "ios"), not(windows))]
+ #[cfg(not(any(target_os = "macos", target_os = "ios", windows)))]
unsafe fn os_get_time() -> (i64, i32) {
let mut tv = libc::timespec { tv_sec: 0, tv_nsec: 0 };
imp::clock_gettime(libc::CLOCK_REALTIME, &mut tv);
return (ticks as u64 * 1000000000) / (ticks_per_s as u64);
}
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "ios")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
fn os_precise_time_ns() -> u64 {
static mut TIMEBASE: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0,
denom: 0 };
}
}
- #[cfg(not(windows), not(target_os = "macos"), not(target_os = "ios"))]
+ #[cfg(not(any(windows, target_os = "macos", target_os = "ios")))]
fn os_precise_time_ns() -> u64 {
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
unsafe {
pos = range.next;
match range.ch {
- '0' .. '9' => {
+ '0' ... '9' => {
value = value * 10_i32 + (range.ch as i32 - '0' as i32);
}
' ' if ws => (),
let range = ss.char_range_at(pos);
match range.ch {
- '0' .. '9' => {
+ '0' ... '9' => {
pos = range.next;
// This will drop digits after the nanoseconds place
let digit = range.ch as i32 - '0' as i32;
/// code point
pub fn is_alphabetic(c: char) -> bool {
match c {
- 'a' .. 'z' | 'A' .. 'Z' => true,
+ 'a' ... 'z' | 'A' ... 'Z' => true,
c if c > '\x7f' => derived_property::Alphabetic(c),
_ => false
}
#[inline]
pub fn is_lowercase(c: char) -> bool {
match c {
- 'a' .. 'z' => true,
+ 'a' ... 'z' => true,
c if c > '\x7f' => derived_property::Lowercase(c),
_ => false
}
#[inline]
pub fn is_uppercase(c: char) -> bool {
match c {
- 'A' .. 'Z' => true,
+ 'A' ... 'Z' => true,
c if c > '\x7f' => derived_property::Uppercase(c),
_ => false
}
#[inline]
pub fn is_whitespace(c: char) -> bool {
match c {
- ' ' | '\x09' .. '\x0d' => true,
+ ' ' | '\x09' ... '\x0d' => true,
c if c > '\x7f' => property::White_Space(c),
_ => false
}
#[inline]
pub fn is_digit(c: char) -> bool {
match c {
- '0' .. '9' => true,
+ '0' ... '9' => true,
c if c > '\x7f' => general_category::N(c),
_ => false
}
c.container_as_bytes().iter().fold(String::new(), |mut out, &b| {
match b as char {
// unreserved:
- 'A' .. 'Z'
- | 'a' .. 'z'
- | '0' .. '9'
+ 'A' ... 'Z'
+ | 'a' ... 'z'
+ | '0' ... '9'
| '-' | '.' | '_' | '~' => out.push_char(b as char),
// gen-delims:
fn encode_plus<T: Str>(s: &T) -> String {
s.as_slice().bytes().fold(String::new(), |mut out, b| {
match b as char {
- 'A' .. 'Z'
- | 'a' .. 'z'
- | '0' .. '9'
+ 'A' ... 'Z'
+ | 'a' ... 'z'
+ | '0' ... '9'
| '_' | '.' | '-' => out.push_char(b as char),
' ' => out.push_char('+'),
ch => out.push_str(format!("%{:X}", ch as uint).as_slice())
pub fn get_scheme(rawurl: &str) -> DecodeResult<(&str, &str)> {
for (i,c) in rawurl.chars().enumerate() {
let result = match c {
- 'A' .. 'Z'
- | 'a' .. 'z' => continue,
- '0' .. '9' | '+' | '-' | '.' => {
+ 'A' ... 'Z'
+ | 'a' ... 'z' => continue,
+ '0' ... '9' | '+' | '-' | '.' => {
if i != 0 { continue }
Err("url: Scheme must begin with a letter.".to_string())
.skip(2) {
// deal with input class first
match c {
- '0' .. '9' => (),
- 'A' .. 'F'
- | 'a' .. 'f' => {
+ '0' ... '9' => (),
+ 'A' ... 'F'
+ | 'a' ... 'f' => {
if input == Digit {
input = Hex;
}
}
- 'G' .. 'Z'
- | 'g' .. 'z'
+ 'G' ... 'Z'
+ | 'g' ... 'z'
| '-' | '.' | '_' | '~' | '%'
| '&' |'\'' | '(' | ')' | '+'
| '!' | '*' | ',' | ';' | '=' => input = Unreserved,
let mut end = len;
for (i,c) in rawurl.chars().enumerate() {
match c {
- 'A' .. 'Z'
- | 'a' .. 'z'
- | '0' .. '9'
+ 'A' ... 'Z'
+ | 'a' ... 'z'
+ | '0' ... '9'
| '&' |'\'' | '(' | ')' | '.'
| '@' | ':' | '%' | '/' | '+'
| '!' | '*' | ',' | ';' | '='
// Make sure all chars are either hex digits or hyphen
for (i, c) in us.chars().enumerate() {
match c {
- '0'..'9' | 'A'..'F' | 'a'..'f' | '-' => {},
+ '0'...'9' | 'A'...'F' | 'a'...'f' | '-' => {},
_ => return Err(ErrorInvalidCharacter(c, i)),
}
}
--- /dev/null
+// 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.
+
+#![crate_type="lib"]
+#![crate_name="issue12660aux"]
+
+pub use my_mod::{MyStruct, my_fn};
+
+mod my_mod {
+ pub struct MyStruct;
+
+ pub fn my_fn(my_struct: MyStruct) {
+ }
+}
--- /dev/null
+// 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.
+
+#![feature(macro_rules,if_let)]
+
+fn macros() {
+ macro_rules! foo{
+ ($p:pat, $e:expr, $b:block) => {{
+ if let $p = $e $b
+ }}
+ }
+ macro_rules! bar{
+ ($p:pat, $e:expr, $b:block) => {{
+ foo!($p, $e, $b)
+ }}
+ }
+
+ foo!(a, 1i, { //~ ERROR irrefutable if-let
+ println!("irrefutable pattern");
+ });
+ bar!(a, 1i, { //~ ERROR irrefutable if-let
+ println!("irrefutable pattern");
+ });
+}
+
+pub fn main() {
+ if let a = 1i { //~ ERROR irrefutable if-let
+ println!("irrefutable pattern");
+ }
+
+ if let a = 1i { //~ ERROR irrefutable if-let
+ println!("irrefutable pattern");
+ } else if true {
+ println!("else-if in irrefutable if-let");
+ } else {
+ println!("else in irrefutable if-let");
+ }
+
+ if let 1i = 2i {
+ println!("refutable pattern");
+ } else if let a = 1i { //~ ERROR irrefutable if-let
+ println!("irrefutable pattern");
+ }
+
+ if true {
+ println!("if");
+ } else if let a = 1i { //~ ERROR irrefutable if-let
+ println!("irrefutable pattern");
+ }
+}
--- /dev/null
+// 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.
+
+// Test that a missing lang item (in this case `sized`) does not cause an ICE,
+// see #17392.
+
+// error-pattern: requires `sized` lang_item
+
+#![no_std]
+
+#[start]
+fn start(argc: int, argv: *const *const u8) -> int {
+ 0
+}
// except according to those terms.
#![deny(unnecessary_parens)]
+#![feature(if_let)]
#[deriving(Eq, PartialEq)]
struct X { y: bool }
match (true) { //~ ERROR unnecessary parentheses around `match` head expression
_ => {}
}
+ if let 1i = (1i) {} //~ ERROR unnecessary parentheses around `if let` head expression
let v = X { y: false };
// struct lits needs parens, so these shouldn't warn.
if (v == X { y: true }) {}
fn main() {
match 1 {
- 1..2u => 1, //~ ERROR mismatched types in range
+ 1...2u => 1, //~ ERROR mismatched types in range
_ => 2,
};
}
fn main() {
match 5u {
- 1u .. 10u => { }
- 5u .. 6u => { }
+ 1u ... 10u => { }
+ 5u ... 6u => { }
_ => {}
};
match 5u {
- 3u .. 6u => { }
- 4u .. 6u => { }
+ 3u ... 6u => { }
+ 4u ... 6u => { }
_ => {}
};
match 5u {
- 4u .. 6u => { }
- 4u .. 6u => { }
+ 4u ... 6u => { }
+ 4u ... 6u => { }
_ => {}
};
match 'c' {
- 'A' .. 'z' => {}
- 'a' .. 'z' => {}
+ 'A' ... 'z' => {}
+ 'a' ... 'z' => {}
_ => {}
};
match 1.0f64 {
- 0.01f64 .. 6.5f64 => {}
+ 0.01f64 ... 6.5f64 => {}
0.02f64 => {}
_ => {}
};
fn main() {
match 5u {
- 6u .. 1u => { }
+ 6u ... 1u => { }
_ => { }
};
match "wow" {
- "bar" .. "foo" => { }
+ "bar" ... "foo" => { }
};
match 5u {
- 'c' .. 100u => { }
+ 'c' ... 100u => { }
_ => { }
};
}
// except according to those terms.
-fn func((1, (Some(1), 2..3)): (int, (Option<int>, int))) { }
+fn func((1, (Some(1), 2...3)): (int, (Option<int>, int))) { }
//~^ ERROR refutable pattern in function argument: `(_, _)` not covered
fn main() {
- let (1i, (Some(1i), 2i..3i)) = (1i, (None, 2i));
+ let (1i, (Some(1i), 2i...3i)) = (1i, (None, 2i));
//~^ ERROR refutable pattern in local binding: `(_, _)` not covered
}
// except according to those terms.
// ignore-android: FIXME(#10381)
+// ignore-windows failing on 64-bit bots FIXME #17638
// compile-flags:-g
-// gdb-command:break issue12886.rs:29
+// gdb-command:break issue12886.rs:30
// gdb-command:run
// gdb-command:next
-// gdb-check:[...]30[...]s
+// gdb-check:[...]31[...]s
// gdb-command:continue
// IF YOU MODIFY THIS FILE, BE CAREFUL TO ADAPT THE LINE NUMBERS IN THE DEBUGGER COMMANDS
}
match 100 {
- b'a' .. b'z' => {},
+ b'a' ... b'z' => {},
_ => fail!()
}
}
pub fn foo(arr: &mut Arr) {
- assert!(arr.len() == 3);
let x: &mut [uint] = &mut **arr;
assert!(x[0] == 1);
assert!(x[1] == 2);
--- /dev/null
+// 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.
+
+// Generic unique/owned smaht pointer.
+struct Own<T> {
+ value: *mut T
+}
+
+impl<T> Deref<T> for Own<T> {
+ fn deref<'a>(&'a self) -> &'a T {
+ unsafe { &*self.value }
+ }
+}
+
+impl<T> DerefMut<T> for Own<T> {
+ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
+ unsafe { &mut *self.value }
+ }
+}
+
+struct Point {
+ x: int,
+ y: int
+}
+
+impl Point {
+ fn get(&mut self) -> (int, int) {
+ (self.x, self.y)
+ }
+}
+
+fn test0(mut x: Own<Point>) {
+ let _ = x.get();
+}
+
+fn test1(mut x: Own<Own<Own<Point>>>) {
+ let _ = x.get();
+}
+
+fn test2(mut x: Own<Own<Own<Point>>>) {
+ let _ = (**x).get();
+}
+
+fn main() {}
+
--- /dev/null
+// 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.
+
+#![feature(if_let)]
+
+pub fn main() {
+ let x = Some(3i);
+ if let Some(y) = x {
+ assert_eq!(y, 3i);
+ } else {
+ fail!("if-let failed");
+ }
+ let mut worked = false;
+ if let Some(_) = x {
+ worked = true;
+ }
+ assert!(worked);
+ let clause: uint;
+ if let None = Some("test") {
+ clause = 1;
+ } else if 4u > 5 {
+ clause = 2;
+ } else if let Ok(()) = Err::<(),&'static str>("test") {
+ clause = 3;
+ } else {
+ clause = 4;
+ }
+ assert_eq!(clause, 4u);
+
+ if 3i > 4 {
+ fail!("bad math");
+ } else if let 1 = 2i {
+ fail!("bad pattern match");
+ }
+
+ enum Foo {
+ One,
+ Two(uint),
+ Three(String, int)
+ }
+
+ let foo = Three("three".to_string(), 42i);
+ if let One = foo {
+ fail!("bad pattern match");
+ } else if let Two(_x) = foo {
+ fail!("bad pattern match");
+ } else if let Three(s, _) = foo {
+ assert_eq!(s.as_slice(), "three");
+ } else {
+ fail!("bad else");
+ }
+
+ if false {
+ fail!("wat");
+ } else if let a@Two(_) = Two(42u) {
+ if let Two(b) = a {
+ assert_eq!(b, 42u);
+ } else {
+ fail!("fail in nested if-let");
+ }
+ }
+}
pub fn main() {
let x = 2i;
let x_message = match x {
- 0 .. 1 => { "not many".to_string() }
+ 0 ... 1 => { "not many".to_string() }
_ => { "lots".to_string() }
};
assert_eq!(x_message, "lots".to_string());
let y = 2i;
let y_message = match y {
- 0 .. 1 => { "not many".to_string() }
+ 0 ... 1 => { "not many".to_string() }
_ => { "lots".to_string() }
};
assert_eq!(y_message, "lots".to_string());
let z = 1u64;
let z_message = match z {
- 0 .. 1 => { "not many".to_string() }
+ 0 ... 1 => { "not many".to_string() }
_ => { "lots".to_string() }
};
assert_eq!(z_message, "not many".to_string());
assert_eq!(3i, match (x, y) {
(1, 1) => 1,
(2, 2) => 2,
- (1..2, 2) => 3,
+ (1...2, 2) => 3,
_ => 4,
});
assert_eq!(3i, match ((x, y),) {
((1, 1),) => 1,
((2, 2),) => 2,
- ((1..2, 2),) => 3,
+ ((1...2, 2),) => 3,
_ => 4,
});
}
--- /dev/null
+// 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.
+
+// aux-build:issue-12660-aux.rs
+
+extern crate issue12660aux;
+
+use issue12660aux::{my_fn, MyStruct};
+
+#[allow(path_statement)]
+fn main() {
+ my_fn(MyStruct);
+ MyStruct;
+}
fn lit_shadow_range() {
assert_eq!(2i, match 1i {
1 if false => 1i,
- 1..2 => 2,
+ 1...2 => 2,
_ => 3
});
assert_eq!(2i, match x+1 {
0 => 0i,
1 if false => 1,
- 1..2 => 2,
+ 1...2 => 2,
_ => 3
});
assert_eq!(2i, match val() {
1 if false => 1i,
- 1..2 => 2,
+ 1...2 => 2,
_ => 3
});
assert_eq!(2i, match CONST {
0 => 0i,
1 if false => 1,
- 1..2 => 2,
+ 1...2 => 2,
_ => 3
});
// value is out of the range of second arm, should match wildcard pattern
assert_eq!(3i, match 3i {
1 if false => 1i,
- 1..2 => 2,
+ 1...2 => 2,
_ => 3
});
}
fn range_shadow_lit() {
assert_eq!(2i, match 1i {
- 1..2 if false => 1i,
+ 1...2 if false => 1i,
1 => 2,
_ => 3
});
let x = 0i;
assert_eq!(2i, match x+1 {
0 => 0i,
- 1..2 if false => 1,
+ 1...2 if false => 1,
1 => 2,
_ => 3
});
assert_eq!(2i, match val() {
- 1..2 if false => 1i,
+ 1...2 if false => 1i,
1 => 2,
_ => 3
});
assert_eq!(2i, match CONST {
0 => 0i,
- 1..2 if false => 1,
+ 1...2 if false => 1,
1 => 2,
_ => 3
});
// ditto
assert_eq!(3i, match 3i {
- 1..2 if false => 1i,
+ 1...2 if false => 1i,
1 => 2,
_ => 3
});
fn range_shadow_range() {
assert_eq!(2i, match 1i {
- 0..2 if false => 1i,
- 1..3 => 2,
+ 0...2 if false => 1i,
+ 1...3 => 2,
_ => 3,
});
let x = 0i;
assert_eq!(2i, match x+1 {
100 => 0,
- 0..2 if false => 1,
- 1..3 => 2,
+ 0...2 if false => 1,
+ 1...3 => 2,
_ => 3,
});
assert_eq!(2i, match val() {
- 0..2 if false => 1,
- 1..3 => 2,
+ 0...2 if false => 1,
+ 1...3 => 2,
_ => 3,
});
assert_eq!(2i, match CONST {
100 => 0,
- 0..2 if false => 1,
- 1..3 => 2,
+ 0...2 if false => 1,
+ 1...3 => 2,
_ => 3,
});
// ditto
assert_eq!(3i, match 5i {
- 0..2 if false => 1i,
- 1..3 => 2,
+ 0...2 if false => 1i,
+ 1...3 => 2,
_ => 3,
});
}
fn multi_pats_shadow_lit() {
assert_eq!(2i, match 1i {
100 => 0i,
- 0 | 1..10 if false => 1,
+ 0 | 1...10 if false => 1,
1 => 2,
_ => 3,
});
fn multi_pats_shadow_range() {
assert_eq!(2i, match 1i {
100 => 0i,
- 0 | 1..10 if false => 1,
- 1..3 => 2,
+ 0 | 1...10 if false => 1,
+ 1...3 => 2,
_ => 3,
});
}
assert_eq!(2i, match 1i {
100 => 0i,
1 if false => 1,
- 0 | 1..10 => 2,
+ 0 | 1...10 => 2,
_ => 3,
});
}
fn range_shadow_multi_pats() {
assert_eq!(2i, match 1i {
100 => 0i,
- 1..3 if false => 1,
- 0 | 1..10 => 2,
+ 1...3 if false => 1,
+ 0 | 1...10 => 2,
_ => 3,
});
}
--- /dev/null
+// 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.
+
+extern crate libc;
+
+#[cfg(windows)]
+mod imp {
+ use libc::{c_void, LPVOID, DWORD};
+ use libc::types::os::arch::extra::LPWSTR;
+
+ extern "system" {
+ fn FormatMessageW(flags: DWORD,
+ lpSrc: LPVOID,
+ msgId: DWORD,
+ langId: DWORD,
+ buf: LPWSTR,
+ nsize: DWORD,
+ args: *const c_void)
+ -> DWORD;
+ }
+
+ pub fn test() {
+ let mut buf: [u16, ..50] = [0, ..50];
+ let ret = unsafe {
+ FormatMessageW(0x1000, 0 as *mut c_void, 1, 0x400,
+ buf.as_mut_ptr(), buf.len() as u32, 0 as *const c_void)
+ };
+ // On some 32-bit Windowses (Win7-8 at least) this will fail with segmented
+ // stacks taking control of pvArbitrary
+ assert!(ret != 0);
+ }
+}
+
+#[cfg(not(windows))]
+mod imp {
+ pub fn test() { }
+}
+
+fn main() {
+ imp::test()
+}
fn main() {
let r = match (FooNullary, 'a') {
- (FooUint(..), 'a'..'z') => 1i,
+ (FooUint(..), 'a'...'z') => 1i,
(FooNullary, 'x') => 2i,
_ => 0
};
assert_eq!(r, 0);
let r = match (FooUint(0), 'a') {
- (FooUint(1), 'a'..'z') => 1i,
+ (FooUint(1), 'a'...'z') => 1i,
(FooUint(..), 'x') => 2i,
(FooNullary, 'a') => 3i,
_ => 0
assert_eq!(r, 0);
let r = match ('a', FooUint(0)) {
- ('a'..'z', FooUint(1)) => 1i,
+ ('a'...'z', FooUint(1)) => 1i,
('x', FooUint(..)) => 2i,
('a', FooNullary) => 3i,
_ => 0
assert_eq!(r, 0);
let r = match ('a', 'a') {
- ('a'..'z', 'b') => 1i,
- ('x', 'a'..'z') => 2i,
+ ('a'...'z', 'b') => 1i,
+ ('x', 'a'...'z') => 2i,
_ => 0
};
assert_eq!(r, 0);
let r = match ('a', 'a') {
- ('a'..'z', 'b') => 1i,
- ('x', 'a'..'z') => 2i,
+ ('a'...'z', 'b') => 1i,
+ ('x', 'a'...'z') => 2i,
('a', 'a') => 3i,
_ => 0
};
static FOO: f64 = 10.0;
match 0.0 {
- 0.0 .. FOO => (),
+ 0.0 ... FOO => (),
_ => ()
}
}
pub fn main() {
match 5u {
- 1u..5u => {}
+ 1u...5u => {}
_ => fail!("should match range"),
}
match 5u {
- 6u..7u => fail!("shouldn't match range"),
+ 6u...7u => fail!("shouldn't match range"),
_ => {}
}
match 5u {
1u => fail!("should match non-first range"),
- 2u..6u => {}
+ 2u...6u => {}
_ => fail!("math is broken")
}
match 'c' {
- 'a'..'z' => {}
+ 'a'...'z' => {}
_ => fail!("should suppport char ranges")
}
match -3i {
- -7..5 => {}
+ -7...5 => {}
_ => fail!("should match signed range")
}
match 3.0f64 {
- 1.0..5.0 => {}
+ 1.0...5.0 => {}
_ => fail!("should match float range")
}
match -1.5f64 {
- -3.6..3.6 => {}
+ -3.6...3.6 => {}
_ => fail!("should match negative float range")
}
}
let silent = Command::new(args[0].as_slice()).arg("silent").output().unwrap();
assert!(!silent.status.success());
let error = String::from_utf8_lossy(silent.error.as_slice());
- assert!(error.as_slice().contains("has overflowed its stack"));
+ // FIXME #17562: Windows is using stack probes and isn't wired up to print an error
+ if !cfg!(windows) {
+ assert!(error.as_slice().contains("has overflowed its stack"));
+ }
let loud = Command::new(args[0].as_slice()).arg("loud").output().unwrap();
assert!(!loud.status.success());
let error = String::from_utf8_lossy(silent.error.as_slice());
- assert!(error.as_slice().contains("has overflowed its stack"));
+ // FIXME #17562: Windows is using stack probes and isn't wired up to print an error
+ if !cfg!(windows) {
+ assert!(error.as_slice().contains("has overflowed its stack"));
+ }
}
}
assert_eq!(p.counts(), (2, 2));
p.get();
- assert_eq!(p.counts(), (2, 3));
+ assert_eq!(p.counts(), (3, 2));
// Check the final state.
assert_eq!(*p, Point {x: 3, y: 0});
ret
}
+ unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
+ if PRINT { println!("deallocate(ptr=0x{:010x} size={:u} align={:u})",
+ ptr as uint, size, align);
+ }
+
+ heap::deallocate(ptr, size, align);
+ }
unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
old_size: uint) -> *mut u8 {
if PRINT {
}
sanity_check(ascend.as_slice());
- test_1(ascend);
- test_2(ascend);
- test_3(ascend);
- test_4(ascend);
+ test_1(ascend); // triangle -> square
+ test_2(ascend); // square -> triangle
+ test_3(ascend); // triangle -> square
+ test_4(ascend); // square -> triangle
+
+ for i in range(0u, COUNT / 2) {
+ let size = idx_to_size(i);
+ deallocate(ascend[2*i], size, ALIGN);
+ deallocate(ascend[2*i+1], size, ALIGN);
+ }
return true;