auto merge of #17629 : alexcrichton/rust/rollup, r=alexcrichton
This commit is contained in:
commit
1f3cda8bd8
8
configure
vendored
8
configure
vendored
@ -453,12 +453,12 @@ valopt datadir "${CFG_PREFIX}/share" "install data"
|
||||
valopt infodir "${CFG_PREFIX}/share/info" "install additional info"
|
||||
valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
|
||||
|
||||
valopt release-channel "source" "the name of the release channel to build"
|
||||
valopt release-channel "dev" "the name of the release channel to build"
|
||||
|
||||
# On windows we just store the libraries in the bin directory because
|
||||
# there's no rpath. This is where the build system itself puts libraries;
|
||||
# --libdir is used to configure the installation directory.
|
||||
# FIXME: Thise needs to parameterized over target triples. Do it in platform.mk
|
||||
# FIXME: This needs to parameterized over target triples. Do it in platform.mk
|
||||
CFG_LIBDIR_RELATIVE=lib
|
||||
if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
|
||||
then
|
||||
@ -479,10 +479,10 @@ validate_opt
|
||||
|
||||
# Validate the release channel
|
||||
case "$CFG_RELEASE_CHANNEL" in
|
||||
(source | nightly | beta | stable)
|
||||
(dev | nightly | beta | stable)
|
||||
;;
|
||||
(*)
|
||||
err "release channel must be 'source', 'nightly', 'beta' or 'stable'"
|
||||
err "release channel must be 'dev', 'nightly', 'beta' or 'stable'"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -71,7 +71,7 @@ DEPS_graphviz := std
|
||||
DEPS_green := std native:context_switch
|
||||
DEPS_rustuv := std native:uv native:uv_support
|
||||
DEPS_native := std
|
||||
DEPS_syntax := std term serialize log fmt_macros debug arena
|
||||
DEPS_syntax := std term serialize log fmt_macros debug arena libc
|
||||
DEPS_rustc := syntax flate arena serialize getopts rbml \
|
||||
time log graphviz debug rustc_llvm rustc_back
|
||||
DEPS_rustc_llvm := native:rustllvm libc std
|
||||
|
@ -35,9 +35,9 @@ ifeq ($(CFG_RELEASE_CHANNEL),nightly)
|
||||
CFG_RELEASE=$(CFG_RELEASE_NUM)-nightly
|
||||
CFG_PACKAGE_VERS=nightly
|
||||
endif
|
||||
ifeq ($(CFG_RELEASE_CHANNEL),source)
|
||||
CFG_RELEASE=$(CFG_RELEASE_NUM)-pre
|
||||
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-pre
|
||||
ifeq ($(CFG_RELEASE_CHANNEL),dev)
|
||||
CFG_RELEASE=$(CFG_RELEASE_NUM)-dev
|
||||
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-dev
|
||||
endif
|
||||
|
||||
# The name of the package to use for creating tarballs, installers etc.
|
||||
|
@ -4325,8 +4325,6 @@ and so we tell it that we want a vector of integers.
|
||||
is one:
|
||||
|
||||
```{rust}
|
||||
let one_to_one_hundred = range(0i, 100i);
|
||||
|
||||
let greater_than_forty_two = range(0i, 100i)
|
||||
.find(|x| *x >= 42);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
SetupIconFile=rust-logo.ico
|
||||
AppName=Rust
|
||||
AppVersion={#CFG_RELEASE}
|
||||
AppCopyright=Copyright (C) 2006-2013 Mozilla Foundation, MIT license
|
||||
AppCopyright=Copyright (C) 2006-2014 Mozilla Foundation, MIT license
|
||||
AppPublisher=Mozilla Foundation
|
||||
AppPublisherURL=http://www.rust-lang.org
|
||||
VersionInfoVersion={#CFG_VERSION_WIN}
|
||||
@ -43,7 +43,7 @@ Source: "tmp/dist/win/*.*" ; DestDir: "{app}"; Flags: ignoreversion recursesubdi
|
||||
[Code]
|
||||
const
|
||||
ModPathName = 'modifypath';
|
||||
ModPathType = 'user';
|
||||
ModPathType = 'system';
|
||||
|
||||
function ModPathDir(): TArrayOfString;
|
||||
begin
|
||||
|
@ -120,10 +120,9 @@ LIT_INTEGER
|
||||
| '0x' [0-9a-fA-F][0-9a-fA-F_]* INT_SUFFIX?
|
||||
;
|
||||
|
||||
FLOAT_SUFFIX
|
||||
fragment FLOAT_SUFFIX
|
||||
: 'f32'
|
||||
| 'f64'
|
||||
| 'f128'
|
||||
;
|
||||
|
||||
LIT_FLOAT
|
||||
|
@ -96,12 +96,6 @@ pub trait BoxAny {
|
||||
/// `Err(Self)` if it isn't.
|
||||
#[unstable = "naming conventions around accessing innards may change"]
|
||||
fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
|
||||
|
||||
/// Deprecated; this method has been renamed to `downcast`.
|
||||
#[deprecated = "use downcast instead"]
|
||||
fn move<T: 'static>(self) -> Result<Box<T>, Self> {
|
||||
self.downcast::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable]
|
||||
|
@ -16,7 +16,7 @@ use core::raw;
|
||||
#[inline]
|
||||
#[deprecated]
|
||||
pub fn get_box_size(body_size: uint, body_align: uint) -> uint {
|
||||
let header_size = mem::size_of::<raw::Box<()>>();
|
||||
let header_size = mem::size_of::<raw::GcBox<()>>();
|
||||
let total_size = align_to(header_size, body_align) + body_size;
|
||||
total_size
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
use core::prelude::*;
|
||||
use core::fmt;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Hash)]
|
||||
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
/// A specialized `Set` implementation to use enum types.
|
||||
pub struct EnumSet<E> {
|
||||
// We must maintain the invariant that no bits are set
|
||||
|
@ -18,6 +18,7 @@ use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
use core::ops;
|
||||
// FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait
|
||||
use core::raw::Slice as RawSlice;
|
||||
|
||||
@ -530,7 +531,7 @@ impl String {
|
||||
/// assert_eq!(s.as_slice(), "abc123");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable = "function just renamed from push"]
|
||||
#[stable = "function just renamed from push_char"]
|
||||
pub fn push(&mut self, ch: char) {
|
||||
let cur_len = self.len();
|
||||
// This may use up to 4 bytes.
|
||||
@ -926,6 +927,28 @@ impl<S: Str> Add<S, String> for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Slice<uint, str> for String {
|
||||
#[inline]
|
||||
fn as_slice_<'a>(&'a self) -> &'a str {
|
||||
self.as_slice()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_from_<'a>(&'a self, from: &uint) -> &'a str {
|
||||
self[][*from..]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_to_<'a>(&'a self, to: &uint) -> &'a str {
|
||||
self[][..*to]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
|
||||
self[][*from..*to]
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafe operations
|
||||
#[unstable = "waiting on raw module conventions"]
|
||||
pub mod raw {
|
||||
@ -1290,6 +1313,15 @@ mod tests {
|
||||
#[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
|
||||
#[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
|
||||
|
||||
#[test]
|
||||
fn test_slicing() {
|
||||
let s = "foobar".to_string();
|
||||
assert_eq!("foobar", s[]);
|
||||
assert_eq!("foo", s[..3]);
|
||||
assert_eq!("bar", s[3..]);
|
||||
assert_eq!("oob", s[1..4]);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_with_capacity(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
@ -2393,8 +2393,6 @@ mod tests {
|
||||
let _ = vec[3];
|
||||
}
|
||||
|
||||
// NOTE uncomment after snapshot
|
||||
/*
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_slice_out_of_bounds_1() {
|
||||
@ -2429,7 +2427,6 @@ mod tests {
|
||||
let x: Vec<int> = vec![1, 2, 3, 4, 5];
|
||||
x[3..2];
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_swap_remove_empty() {
|
||||
|
@ -33,24 +33,9 @@
|
||||
use fmt;
|
||||
use intrinsics;
|
||||
|
||||
// NOTE: remove after next snapshot
|
||||
#[cfg(stage0)]
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail_"]
|
||||
fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
||||
let (expr, file, line) = *expr_file_line;
|
||||
let ref file_line = (file, line);
|
||||
format_args!(|args| -> () {
|
||||
fail_fmt(args, file_line);
|
||||
}, "{}", expr);
|
||||
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail"]
|
||||
fn fail(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
||||
pub fn fail(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
||||
let (expr, file, line) = *expr_file_line;
|
||||
let ref file_line = (file, line);
|
||||
format_args!(|args| -> () {
|
||||
@ -70,23 +55,10 @@ fn fail_bounds_check(file_line: &(&'static str, uint),
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cold] #[inline(never)]
|
||||
pub fn fail_str(msg: &str, file: &(&'static str, uint)) -> ! {
|
||||
format_args!(|fmt| fail_fmt(fmt, file), "{}", msg)
|
||||
}
|
||||
|
||||
#[cold] #[inline(never)]
|
||||
pub fn fail_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
|
||||
#[allow(ctypes)]
|
||||
extern {
|
||||
|
||||
// NOTE: remove after next snapshot
|
||||
#[cfg(stage0)]
|
||||
#[lang = "begin_unwind"]
|
||||
fn fail_impl(fmt: &fmt::Arguments, file: &'static str,
|
||||
line: uint) -> !;
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[lang = "fail_fmt"]
|
||||
fn fail_impl(fmt: &fmt::Arguments, file: &'static str,
|
||||
line: uint) -> !;
|
||||
|
@ -366,7 +366,7 @@ pub trait Iterator<A> {
|
||||
/// let mut sum = 0;
|
||||
/// for x in it {
|
||||
/// if x > 5 {
|
||||
/// continue;
|
||||
/// break;
|
||||
/// }
|
||||
/// sum += x;
|
||||
/// }
|
||||
@ -377,6 +377,8 @@ pub trait Iterator<A> {
|
||||
/// sum
|
||||
/// }
|
||||
/// let x = vec![1i,2,3,7,8,9];
|
||||
/// assert_eq!(process(x.into_iter()), 6);
|
||||
/// let x = vec![1i,2,3];
|
||||
/// assert_eq!(process(x.into_iter()), 1006);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -17,8 +17,8 @@ macro_rules! fail(
|
||||
fail!("{}", "explicit failure")
|
||||
);
|
||||
($msg:expr) => ({
|
||||
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
|
||||
::core::failure::fail_str($msg, &_FILE_LINE)
|
||||
static _MSG_FILE_LINE: (&'static str, &'static str, uint) = ($msg, file!(), line!());
|
||||
::core::failure::fail(&_MSG_FILE_LINE)
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => ({
|
||||
// a closure can't have return type !, so we need a full
|
||||
|
@ -764,13 +764,13 @@ pub trait Slice<Idx, Sized? Result> for Sized? {
|
||||
// FIXME(#17273) remove the postscript _s
|
||||
#[lang="slice_mut"]
|
||||
pub trait SliceMut<Idx, Sized? Result> for Sized? {
|
||||
/// The method for the slicing operation foo[]
|
||||
/// The method for the slicing operation foo[mut]
|
||||
fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result;
|
||||
/// The method for the slicing operation foo[from..]
|
||||
/// The method for the slicing operation foo[mut from..]
|
||||
fn slice_from_mut_<'a>(&'a mut self, from: &Idx) -> &'a mut Result;
|
||||
/// The method for the slicing operation foo[..to]
|
||||
/// The method for the slicing operation foo[mut ..to]
|
||||
fn slice_to_mut_<'a>(&'a mut self, to: &Idx) -> &'a mut Result;
|
||||
/// The method for the slicing operation foo[from..to]
|
||||
/// The method for the slicing operation foo[mut from..to]
|
||||
fn slice_mut_<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result;
|
||||
}
|
||||
/**
|
||||
|
@ -312,7 +312,7 @@ impl<T> Option<T> {
|
||||
pub fn expect(self, msg: &str) -> T {
|
||||
match self {
|
||||
Some(val) => val,
|
||||
None => fail!(msg),
|
||||
None => fail!("{}", msg),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,12 @@
|
||||
|
||||
use mem;
|
||||
|
||||
/// The representation of a Rust managed box
|
||||
pub struct Box<T> {
|
||||
/// The representation of `std::gc::Gc`.
|
||||
pub struct GcBox<T> {
|
||||
pub ref_count: uint,
|
||||
pub drop_glue: fn(ptr: *mut u8),
|
||||
pub prev: *mut Box<T>,
|
||||
pub next: *mut Box<T>,
|
||||
pub prev: *mut GcBox<T>,
|
||||
pub next: *mut GcBox<T>,
|
||||
pub data: T,
|
||||
}
|
||||
|
||||
|
@ -1123,6 +1123,7 @@ pub mod traits {
|
||||
use collections::Collection;
|
||||
use iter::Iterator;
|
||||
use option::{Option, Some};
|
||||
use ops;
|
||||
use str::{Str, StrSlice, eq_slice};
|
||||
|
||||
impl<'a> Ord for &'a str {
|
||||
@ -1162,6 +1163,28 @@ pub mod traits {
|
||||
#[inline]
|
||||
fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
|
||||
}
|
||||
|
||||
impl ops::Slice<uint, str> for str {
|
||||
#[inline]
|
||||
fn as_slice_<'a>(&'a self) -> &'a str {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_from_<'a>(&'a self, from: &uint) -> &'a str {
|
||||
self.slice_from(*from)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_to_<'a>(&'a self, to: &uint) -> &'a str {
|
||||
self.slice_to(*to)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
|
||||
self.slice(*from, *to)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Any string that can be represented as a slice
|
||||
|
@ -277,7 +277,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
try!(self, self.writer.write("box(GC) ".as_bytes()));
|
||||
self.write_mut_qualifier(mtbl);
|
||||
self.get::<&raw::Box<()>>(|this, b| {
|
||||
self.get::<&raw::GcBox<()>>(|this, b| {
|
||||
let p = &b.data as *const () as *const u8;
|
||||
this.visit_ptr_inner(p, inner)
|
||||
})
|
||||
|
@ -1319,6 +1319,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
// Fix up permissions of the copy, as fs::copy() preserves
|
||||
// permissions, but the original file may have been installed
|
||||
// by a package manager and may be read-only.
|
||||
match fs::chmod(&dst, io::UserRead | io::UserWrite) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to chmod {} when preparing \
|
||||
for LTO: {}", dst.display(),
|
||||
e).as_slice());
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
let handler = &sess.diagnostic().handler;
|
||||
let config = ArchiveConfig {
|
||||
handler: handler,
|
||||
|
@ -16,6 +16,7 @@ use driver::session::Session;
|
||||
use driver::config;
|
||||
use llvm;
|
||||
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
|
||||
use llvm::SMDiagnosticRef;
|
||||
use util::common::time;
|
||||
use syntax::abi;
|
||||
use syntax::codemap;
|
||||
@ -326,14 +327,40 @@ impl<'a> CodegenContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
struct DiagHandlerFreeVars<'a> {
|
||||
struct HandlerFreeVars<'a> {
|
||||
llcx: ContextRef,
|
||||
cgcx: &'a CodegenContext<'a>,
|
||||
}
|
||||
|
||||
unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
|
||||
user: *const c_void,
|
||||
cookie: c_uint) {
|
||||
use syntax::codemap::ExpnId;
|
||||
|
||||
let HandlerFreeVars { cgcx, .. }
|
||||
= *mem::transmute::<_, *const HandlerFreeVars>(user);
|
||||
|
||||
let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
|
||||
.expect("non-UTF8 SMDiagnostic");
|
||||
|
||||
match cgcx.lto_ctxt {
|
||||
Some((sess, _)) => {
|
||||
sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info {
|
||||
Some(ei) => sess.span_err(ei.call_site, msg.as_slice()),
|
||||
None => sess.err(msg.as_slice()),
|
||||
});
|
||||
}
|
||||
|
||||
None => {
|
||||
cgcx.handler.err(msg.as_slice());
|
||||
cgcx.handler.note("build without -C codegen-units for more exact errors");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
|
||||
let DiagHandlerFreeVars { llcx, cgcx }
|
||||
= *mem::transmute::<_, *const DiagHandlerFreeVars>(user);
|
||||
let HandlerFreeVars { llcx, cgcx }
|
||||
= *mem::transmute::<_, *const HandlerFreeVars>(user);
|
||||
|
||||
match llvm::diagnostic::Diagnostic::unpack(info) {
|
||||
llvm::diagnostic::Optimization(opt) => {
|
||||
@ -368,14 +395,16 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
||||
let tm = config.tm;
|
||||
|
||||
// llcx doesn't outlive this function, so we can put this on the stack.
|
||||
let fv = DiagHandlerFreeVars {
|
||||
let fv = HandlerFreeVars {
|
||||
llcx: llcx,
|
||||
cgcx: cgcx,
|
||||
};
|
||||
let fv = &fv as *const HandlerFreeVars as *mut c_void;
|
||||
|
||||
llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
|
||||
|
||||
if !cgcx.remark.is_empty() {
|
||||
llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler,
|
||||
&fv as *const DiagHandlerFreeVars
|
||||
as *mut c_void);
|
||||
llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
|
||||
}
|
||||
|
||||
if config.emit_no_opt_bc {
|
||||
|
@ -288,8 +288,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap());
|
||||
}
|
||||
let cfg = syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: sess.features.borrow().default_type_params,
|
||||
crate_name: crate_name.to_string(),
|
||||
deriving_hash_type_parameter: sess.features.borrow().default_type_params,
|
||||
enable_quotes: sess.features.borrow().quote,
|
||||
};
|
||||
let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
|
||||
cfg,
|
||||
@ -556,6 +557,8 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
|
||||
sess.opts.output_types.as_slice(),
|
||||
outputs));
|
||||
}
|
||||
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
|
||||
/// Run the linker on any artifacts that resulted from the LLVM run.
|
||||
|
@ -32,7 +32,6 @@ This API is completely unstable and subject to change.
|
||||
#![feature(macro_rules, globs, struct_variant, quote)]
|
||||
#![feature(default_type_params, phase, unsafe_destructor)]
|
||||
|
||||
#![allow(unknown_features)] // NOTE: Remove after next snapshot
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(import_shadowing)]
|
||||
|
||||
|
@ -652,12 +652,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})",
|
||||
id, use_kind, lp.repr(self.bccx.tcx));
|
||||
let base_lp = owned_ptr_base_path_rc(lp);
|
||||
self.move_data.each_move_of(id, &base_lp, |move, moved_lp| {
|
||||
self.move_data.each_move_of(id, &base_lp, |the_move, moved_lp| {
|
||||
self.bccx.report_use_of_moved_value(
|
||||
span,
|
||||
use_kind,
|
||||
&**lp,
|
||||
move,
|
||||
the_move,
|
||||
moved_lp);
|
||||
false
|
||||
});
|
||||
|
@ -108,8 +108,8 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
let move_index_to_path = |move_index| {
|
||||
let move_data = &self.analysis_data.move_data.move_data;
|
||||
let moves = move_data.moves.borrow();
|
||||
let move = moves.get(move_index);
|
||||
move_data.path_loan_path(move.path)
|
||||
let the_move = moves.get(move_index);
|
||||
move_data.path_loan_path(the_move.path)
|
||||
};
|
||||
self.build_set(e, cfgidx, dfcx, move_index_to_path)
|
||||
}
|
||||
|
@ -409,14 +409,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
use_span: Span,
|
||||
use_kind: MovedValueUseKind,
|
||||
lp: &LoanPath,
|
||||
move: &move_data::Move,
|
||||
the_move: &move_data::Move,
|
||||
moved_lp: &LoanPath) {
|
||||
let verb = match use_kind {
|
||||
MovedInUse => "use",
|
||||
MovedInCapture => "capture",
|
||||
};
|
||||
|
||||
match move.kind {
|
||||
match the_move.kind {
|
||||
move_data::Declared => {
|
||||
self.tcx.sess.span_err(
|
||||
use_span,
|
||||
@ -435,18 +435,20 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
match move.kind {
|
||||
match the_move.kind {
|
||||
move_data::Declared => {}
|
||||
|
||||
move_data::MoveExpr => {
|
||||
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
|
||||
let (expr_ty, expr_span) = match self.tcx
|
||||
.map
|
||||
.find(the_move.id) {
|
||||
Some(ast_map::NodeExpr(expr)) => {
|
||||
(ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
|
||||
}
|
||||
r => {
|
||||
self.tcx.sess.bug(format!("MoveExpr({:?}) maps to \
|
||||
{:?}, not Expr",
|
||||
move.id,
|
||||
the_move.id,
|
||||
r).as_slice())
|
||||
}
|
||||
};
|
||||
@ -461,8 +463,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
move_data::MovePat => {
|
||||
let pat_ty = ty::node_id_to_type(self.tcx, move.id);
|
||||
self.tcx.sess.span_note(self.tcx.map.span(move.id),
|
||||
let pat_ty = ty::node_id_to_type(self.tcx, the_move.id);
|
||||
self.tcx.sess.span_note(self.tcx.map.span(the_move.id),
|
||||
format!("`{}` moved here because it has type `{}`, \
|
||||
which is moved by default (use `ref` to \
|
||||
override)",
|
||||
@ -471,14 +473,16 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
move_data::Captured => {
|
||||
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
|
||||
let (expr_ty, expr_span) = match self.tcx
|
||||
.map
|
||||
.find(the_move.id) {
|
||||
Some(ast_map::NodeExpr(expr)) => {
|
||||
(ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
|
||||
}
|
||||
r => {
|
||||
self.tcx.sess.bug(format!("Captured({:?}) maps to \
|
||||
{:?}, not Expr",
|
||||
move.id,
|
||||
the_move.id,
|
||||
r).as_slice())
|
||||
}
|
||||
};
|
||||
|
@ -413,8 +413,8 @@ impl MoveData {
|
||||
* killed by scoping. See `doc.rs` for more details.
|
||||
*/
|
||||
|
||||
for (i, move) in self.moves.borrow().iter().enumerate() {
|
||||
dfcx_moves.add_gen(move.id, i);
|
||||
for (i, the_move) in self.moves.borrow().iter().enumerate() {
|
||||
dfcx_moves.add_gen(the_move.id, i);
|
||||
}
|
||||
|
||||
for (i, assignment) in self.var_assignments.borrow().iter().enumerate() {
|
||||
@ -577,10 +577,10 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
let mut ret = None;
|
||||
for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() {
|
||||
self.dfcx_moves.each_gen_bit(id, |move_index| {
|
||||
let move = self.move_data.moves.borrow();
|
||||
let move = move.get(move_index);
|
||||
if move.path == **loan_path_index {
|
||||
ret = Some(move.kind);
|
||||
let the_move = self.move_data.moves.borrow();
|
||||
let the_move = the_move.get(move_index);
|
||||
if the_move.path == **loan_path_index {
|
||||
ret = Some(the_move.kind);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -622,13 +622,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
let mut ret = true;
|
||||
|
||||
self.dfcx_moves.each_bit_on_entry(id, |index| {
|
||||
let move = self.move_data.moves.borrow();
|
||||
let move = move.get(index);
|
||||
let moved_path = move.path;
|
||||
let the_move = self.move_data.moves.borrow();
|
||||
let the_move = the_move.get(index);
|
||||
let moved_path = the_move.path;
|
||||
if base_indices.iter().any(|x| x == &moved_path) {
|
||||
// Scenario 1 or 2: `loan_path` or some base path of
|
||||
// `loan_path` was moved.
|
||||
if !f(move, &*self.move_data.path_loan_path(moved_path)) {
|
||||
if !f(the_move, &*self.move_data.path_loan_path(moved_path)) {
|
||||
ret = false;
|
||||
}
|
||||
} else {
|
||||
@ -637,7 +637,8 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
if p == loan_path_index {
|
||||
// Scenario 3: some extension of `loan_path`
|
||||
// was moved
|
||||
f(move, &*self.move_data.path_loan_path(moved_path))
|
||||
f(the_move,
|
||||
&*self.move_data.path_loan_path(moved_path))
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use middle::trans::type_::Type;
|
||||
use std::c_str::ToCStr;
|
||||
use std::string::String;
|
||||
use syntax::ast;
|
||||
use libc::{c_uint, c_char};
|
||||
|
||||
// Take an inline assembly expression and splat it out via LLVM
|
||||
pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
||||
@ -141,6 +142,19 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
||||
}
|
||||
}
|
||||
|
||||
// Store expn_id in a metadata node so we can map LLVM errors
|
||||
// back to source locations. See #17552.
|
||||
unsafe {
|
||||
let key = "srcloc";
|
||||
let kind = llvm::LLVMGetMDKindIDInContext(bcx.ccx().llcx(),
|
||||
key.as_ptr() as *const c_char, key.len() as c_uint);
|
||||
|
||||
let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id.to_llvm_cookie());
|
||||
|
||||
llvm::LLVMSetMetadata(r, kind,
|
||||
llvm::LLVMMDNodeInContext(bcx.ccx().llcx(), &val, 1));
|
||||
}
|
||||
|
||||
return bcx;
|
||||
|
||||
}
|
||||
|
@ -1405,6 +1405,37 @@ fn check_cast(fcx: &FnCtxt,
|
||||
return
|
||||
}
|
||||
|
||||
if !ty::type_is_sized(fcx.tcx(), t_1) {
|
||||
let tstr = fcx.infcx().ty_to_string(t_1);
|
||||
fcx.type_error_message(span, |actual| {
|
||||
format!("cast to unsized type: `{}` as `{}`", actual, tstr)
|
||||
}, t_e, None);
|
||||
match ty::get(t_e).sty {
|
||||
ty::ty_rptr(_, ty::mt { mutbl: mt, .. }) => {
|
||||
let mtstr = match mt {
|
||||
ast::MutMutable => "mut ",
|
||||
ast::MutImmutable => ""
|
||||
};
|
||||
if ty::type_is_trait(t_1) {
|
||||
span_note!(fcx.tcx().sess, t.span, "did you mean `&{}{}`?", mtstr, tstr);
|
||||
} else {
|
||||
span_note!(fcx.tcx().sess, span,
|
||||
"consider using an implicit coercion to `&{}{}` instead",
|
||||
mtstr, tstr);
|
||||
}
|
||||
}
|
||||
ty::ty_uniq(..) => {
|
||||
span_note!(fcx.tcx().sess, t.span, "did you mean `Box<{}>`?", tstr);
|
||||
}
|
||||
_ => {
|
||||
span_note!(fcx.tcx().sess, e.span,
|
||||
"consider using a box or reference as appropriate");
|
||||
}
|
||||
}
|
||||
fcx.write_error(id);
|
||||
return
|
||||
}
|
||||
|
||||
if ty::type_is_trait(t_1) {
|
||||
// This will be looked up later on.
|
||||
vtable2::check_object_cast(fcx, cast_expr, e, t_1);
|
||||
|
@ -49,8 +49,8 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
|
||||
|
||||
// FIXME -- it seems like this method actually pushes
|
||||
// duplicate impls onto the list
|
||||
ty::populate_implementations_for_type_if_necessary(self.tcx,
|
||||
trait_def_id);
|
||||
ty::populate_implementations_for_trait_if_necessary(self.tcx,
|
||||
trait_def_id);
|
||||
|
||||
let mut impls = Vec::new();
|
||||
self.push_impls_of_trait(trait_def_id, &mut impls);
|
||||
|
@ -424,8 +424,11 @@ pub enum DiagnosticInfo_opaque {}
|
||||
pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
|
||||
pub enum DebugLoc_opaque {}
|
||||
pub type DebugLocRef = *mut DebugLoc_opaque;
|
||||
pub enum SMDiagnostic_opaque {}
|
||||
pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
|
||||
|
||||
pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
|
||||
pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
|
||||
|
||||
pub mod debuginfo {
|
||||
use super::{ValueRef};
|
||||
@ -1967,6 +1970,12 @@ extern {
|
||||
pub fn LLVMGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind;
|
||||
|
||||
pub fn LLVMWriteDebugLocToString(C: ContextRef, DL: DebugLocRef, s: RustStringRef);
|
||||
|
||||
pub fn LLVMSetInlineAsmDiagnosticHandler(C: ContextRef,
|
||||
H: InlineAsmDiagHandler,
|
||||
CX: *mut c_void);
|
||||
|
||||
pub fn LLVMWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef);
|
||||
}
|
||||
|
||||
pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
|
||||
|
@ -641,11 +641,27 @@ impl Clean<Option<Lifetime>> for ty::Region {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable, PartialEq)]
|
||||
pub struct WherePredicate {
|
||||
pub name: String,
|
||||
pub bounds: Vec<TyParamBound>
|
||||
}
|
||||
|
||||
impl Clean<WherePredicate> for ast::WherePredicate {
|
||||
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
||||
WherePredicate {
|
||||
name: self.ident.clean(cx),
|
||||
bounds: self.bounds.clean(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe use a Generic enum and use ~[Generic]?
|
||||
#[deriving(Clone, Encodable, Decodable, PartialEq)]
|
||||
pub struct Generics {
|
||||
pub lifetimes: Vec<Lifetime>,
|
||||
pub type_params: Vec<TyParam>,
|
||||
pub where_predicates: Vec<WherePredicate>
|
||||
}
|
||||
|
||||
impl Clean<Generics> for ast::Generics {
|
||||
@ -653,6 +669,7 @@ impl Clean<Generics> for ast::Generics {
|
||||
Generics {
|
||||
lifetimes: self.lifetimes.clean(cx),
|
||||
type_params: self.ty_params.clean(cx),
|
||||
where_predicates: self.where_clause.predicates.clean(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -663,6 +680,7 @@ impl<'a> Clean<Generics> for (&'a ty::Generics, subst::ParamSpace) {
|
||||
Generics {
|
||||
type_params: me.types.get_slice(space).to_vec().clean(cx),
|
||||
lifetimes: me.regions.get_slice(space).to_vec().clean(cx),
|
||||
where_predicates: vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1260,7 +1278,9 @@ impl Clean<Type> for ty::t {
|
||||
ty::ty_bare_fn(ref fty) => BareFunction(box BareFunctionDecl {
|
||||
fn_style: fty.fn_style,
|
||||
generics: Generics {
|
||||
lifetimes: Vec::new(), type_params: Vec::new()
|
||||
lifetimes: Vec::new(),
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
decl: (ast_util::local_def(0), &fty.sig).clean(cx),
|
||||
abi: fty.abi.to_string(),
|
||||
@ -1670,6 +1690,7 @@ impl Clean<BareFunctionDecl> for ast::BareFnTy {
|
||||
generics: Generics {
|
||||
lifetimes: self.lifetimes.clean(cx),
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
decl: self.decl.clean(cx),
|
||||
abi: self.abi.to_string(),
|
||||
@ -2172,6 +2193,7 @@ impl Clean<Item> for ast::Typedef {
|
||||
generics: Generics {
|
||||
lifetimes: Vec::new(),
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
}),
|
||||
visibility: None,
|
||||
|
@ -44,6 +44,11 @@ pub struct RawMutableSpace(pub clean::Mutability);
|
||||
pub struct Stability<'a>(pub &'a Option<clean::Stability>);
|
||||
/// Wrapper struct for emitting the stability level concisely.
|
||||
pub struct ConciseStability<'a>(pub &'a Option<clean::Stability>);
|
||||
/// Wrapper struct for emitting a where clause from Generics.
|
||||
pub struct WhereClause<'a>(pub &'a clean::Generics);
|
||||
|
||||
/// Wrapper struct for emitting type parameter bounds.
|
||||
struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
|
||||
|
||||
impl VisSpace {
|
||||
pub fn get(&self) -> Option<ast::Visibility> {
|
||||
@ -57,6 +62,19 @@ impl FnStyleSpace {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for TyParamBounds<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let &TyParamBounds(bounds) = self;
|
||||
for (i, bound) in bounds.iter().enumerate() {
|
||||
if i > 0 {
|
||||
try!(f.write(" + ".as_bytes()));
|
||||
}
|
||||
try!(write!(f, "{}", *bound));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Generics {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
||||
@ -73,7 +91,6 @@ impl fmt::Show for clean::Generics {
|
||||
if self.lifetimes.len() > 0 {
|
||||
try!(f.write(", ".as_bytes()));
|
||||
}
|
||||
|
||||
for (i, tp) in self.type_params.iter().enumerate() {
|
||||
if i > 0 {
|
||||
try!(f.write(", ".as_bytes()))
|
||||
@ -81,13 +98,7 @@ impl fmt::Show for clean::Generics {
|
||||
try!(f.write(tp.name.as_bytes()));
|
||||
|
||||
if tp.bounds.len() > 0 {
|
||||
try!(f.write(": ".as_bytes()));
|
||||
for (i, bound) in tp.bounds.iter().enumerate() {
|
||||
if i > 0 {
|
||||
try!(f.write(" + ".as_bytes()));
|
||||
}
|
||||
try!(write!(f, "{}", *bound));
|
||||
}
|
||||
try!(write!(f, ": {}", TyParamBounds(tp.bounds.as_slice())));
|
||||
}
|
||||
|
||||
match tp.default {
|
||||
@ -101,6 +112,24 @@ impl fmt::Show for clean::Generics {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for WhereClause<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let &WhereClause(gens) = self;
|
||||
if gens.where_predicates.len() == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
try!(f.write(" where ".as_bytes()));
|
||||
for (i, pred) in gens.where_predicates.iter().enumerate() {
|
||||
if i > 0 {
|
||||
try!(f.write(", ".as_bytes()));
|
||||
}
|
||||
let bounds = pred.bounds.as_slice();
|
||||
try!(write!(f, "{}: {}", pred.name, TyParamBounds(bounds)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Lifetime {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(f.write(self.get_ref().as_bytes()));
|
||||
|
@ -56,7 +56,7 @@ use clean;
|
||||
use doctree;
|
||||
use fold::DocFolder;
|
||||
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability};
|
||||
use html::format::{ConciseStability};
|
||||
use html::format::{ConciseStability, WhereClause};
|
||||
use html::highlight;
|
||||
use html::item_type::{ItemType, shortty};
|
||||
use html::item_type;
|
||||
@ -1610,11 +1610,12 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||
fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
|
||||
f: &clean::Function) -> fmt::Result {
|
||||
try!(write!(w, "<pre class='rust fn'>{vis}{fn_style}fn \
|
||||
{name}{generics}{decl}</pre>",
|
||||
{name}{generics}{decl}{where_clause}</pre>",
|
||||
vis = VisSpace(it.visibility),
|
||||
fn_style = FnStyleSpace(f.fn_style),
|
||||
name = it.name.get_ref().as_slice(),
|
||||
generics = f.generics,
|
||||
where_clause = WhereClause(&f.generics),
|
||||
decl = f.decl));
|
||||
document(w, it)
|
||||
}
|
||||
@ -1631,11 +1632,12 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
}
|
||||
|
||||
// Output the trait definition
|
||||
try!(write!(w, "<pre class='rust trait'>{}trait {}{}{} ",
|
||||
try!(write!(w, "<pre class='rust trait'>{}trait {}{}{}{} ",
|
||||
VisSpace(it.visibility),
|
||||
it.name.get_ref().as_slice(),
|
||||
t.generics,
|
||||
bounds));
|
||||
bounds,
|
||||
WhereClause(&t.generics)));
|
||||
let required = t.items.iter()
|
||||
.filter(|m| {
|
||||
match **m {
|
||||
@ -1719,9 +1721,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
match cache.implementors.find(&it.def_id) {
|
||||
Some(implementors) => {
|
||||
for i in implementors.iter() {
|
||||
try!(writeln!(w, "<li>{}<code>impl{} {} for {}</code></li>",
|
||||
try!(writeln!(w, "<li>{}<code>impl{} {} for {}{}</code></li>",
|
||||
ConciseStability(&i.stability),
|
||||
i.generics, i.trait_, i.for_));
|
||||
i.generics, i.trait_, i.for_, WhereClause(&i.generics)));
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
@ -1747,7 +1749,7 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
|
||||
g: &clean::Generics, selfty: &clean::SelfTy,
|
||||
d: &clean::FnDecl) -> fmt::Result {
|
||||
write!(w, "{}fn <a href='#{ty}.{name}' class='fnname'>{name}</a>\
|
||||
{generics}{decl}",
|
||||
{generics}{decl}{where_clause}",
|
||||
match fn_style {
|
||||
ast::UnsafeFn => "unsafe ",
|
||||
_ => "",
|
||||
@ -1755,7 +1757,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
|
||||
ty = shortty(it),
|
||||
name = it.name.get_ref().as_slice(),
|
||||
generics = *g,
|
||||
decl = Method(selfty, d))
|
||||
decl = Method(selfty, d),
|
||||
where_clause = WhereClause(g))
|
||||
}
|
||||
match meth.inner {
|
||||
clean::TyMethodItem(ref m) => {
|
||||
@ -1810,10 +1813,11 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
||||
|
||||
fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
|
||||
e: &clean::Enum) -> fmt::Result {
|
||||
try!(write!(w, "<pre class='rust enum'>{}enum {}{}",
|
||||
try!(write!(w, "<pre class='rust enum'>{}enum {}{}{}",
|
||||
VisSpace(it.visibility),
|
||||
it.name.get_ref().as_slice(),
|
||||
e.generics));
|
||||
e.generics,
|
||||
WhereClause(&e.generics)));
|
||||
if e.variants.len() == 0 && !e.variants_stripped {
|
||||
try!(write!(w, " {{}}"));
|
||||
} else {
|
||||
@ -1917,7 +1921,7 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
||||
if structhead {"struct "} else {""},
|
||||
it.name.get_ref().as_slice()));
|
||||
match g {
|
||||
Some(g) => try!(write!(w, "{}", *g)),
|
||||
Some(g) => try!(write!(w, "{}{}", *g, WhereClause(g))),
|
||||
None => {}
|
||||
}
|
||||
match ty {
|
||||
@ -2009,7 +2013,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
|
||||
Some(ref ty) => try!(write!(w, "{} for ", *ty)),
|
||||
None => {}
|
||||
}
|
||||
try!(write!(w, "{}</code></h3>", i.impl_.for_));
|
||||
try!(write!(w, "{}{}</code></h3>", i.impl_.for_, WhereClause(&i.impl_.generics)));
|
||||
match i.dox {
|
||||
Some(ref dox) => {
|
||||
try!(write!(w, "<div class='docblock'>{}</div>",
|
||||
|
@ -24,7 +24,7 @@ use task::Task;
|
||||
|
||||
static RC_IMMORTAL : uint = 0x77777777;
|
||||
|
||||
pub type Box = raw::Box<()>;
|
||||
pub type Box = raw::GcBox<()>;
|
||||
|
||||
pub struct MemoryRegion {
|
||||
live_allocations: uint,
|
||||
@ -32,7 +32,7 @@ pub struct MemoryRegion {
|
||||
|
||||
pub struct LocalHeap {
|
||||
memory_region: MemoryRegion,
|
||||
live_allocs: *mut raw::Box<()>,
|
||||
live_allocs: *mut raw::GcBox<()>,
|
||||
}
|
||||
|
||||
impl LocalHeap {
|
||||
@ -161,7 +161,7 @@ impl LocalHeap {
|
||||
}
|
||||
|
||||
unsafe fn each_live_alloc(&mut self, read_next_before: bool,
|
||||
f: |&mut LocalHeap, alloc: *mut raw::Box<()>|) {
|
||||
f: |&mut LocalHeap, alloc: *mut raw::GcBox<()>|) {
|
||||
//! Walks the internal list of allocations
|
||||
|
||||
let mut alloc = self.live_allocs;
|
||||
|
@ -37,11 +37,11 @@
|
||||
//! In the cleanup phase, personality routines invoke cleanup code associated
|
||||
//! with their stack frames (i.e. destructors). Once stack has been unwound down
|
||||
//! to the handler frame level, unwinding stops and the last personality routine
|
||||
//! transfers control to its' catch block.
|
||||
//! transfers control to its catch block.
|
||||
//!
|
||||
//! ## Frame unwind info registration
|
||||
//!
|
||||
//! Each module has its' own frame unwind info section (usually ".eh_frame"), and
|
||||
//! Each module has its own frame unwind info section (usually ".eh_frame"), and
|
||||
//! unwinder needs to know about all of them in order for unwinding to be able to
|
||||
//! cross module boundaries.
|
||||
//!
|
||||
@ -488,22 +488,13 @@ pub mod eabi {
|
||||
}
|
||||
|
||||
// Entry point of failure from the libcore crate
|
||||
#[cfg(not(test), not(stage0))]
|
||||
#[cfg(not(test))]
|
||||
#[lang = "fail_fmt"]
|
||||
pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
|
||||
file: &'static str, line: uint) -> ! {
|
||||
begin_unwind_fmt(msg, &(file, line))
|
||||
}
|
||||
|
||||
//
|
||||
// Entry point of failure from the libcore crate
|
||||
#[cfg(stage0, not(test))]
|
||||
#[lang = "begin_unwind"]
|
||||
pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
|
||||
file: &'static str, line: uint) -> ! {
|
||||
begin_unwind_fmt(msg, &(file, line))
|
||||
}
|
||||
|
||||
/// The entry point for unwinding with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
|
@ -668,16 +668,23 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
|
||||
if cnt == 0 {
|
||||
escape_str(self.writer, name)
|
||||
} else {
|
||||
try!(write!(self.writer, "{{\n"));
|
||||
self.curr_indent += self.indent;
|
||||
try!(write!(self.writer, "[\n"));
|
||||
try!(spaces(self.writer, self.curr_indent));
|
||||
try!(write!(self.writer, "\"variant\": "));
|
||||
try!(escape_str(self.writer, name));
|
||||
try!(write!(self.writer, ",\n"));
|
||||
try!(spaces(self.writer, self.curr_indent));
|
||||
try!(write!(self.writer, "\"fields\": [\n"));
|
||||
self.curr_indent += self.indent;
|
||||
try!(f(self));
|
||||
self.curr_indent -= self.indent;
|
||||
try!(write!(self.writer, "\n"));
|
||||
try!(spaces(self.writer, self.curr_indent));
|
||||
write!(self.writer, "]")
|
||||
self.curr_indent -= self.indent;
|
||||
try!(write!(self.writer, "]\n"));
|
||||
try!(spaces(self.writer, self.curr_indent));
|
||||
write!(self.writer, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -2651,12 +2658,13 @@ mod tests {
|
||||
let mut encoder = PrettyEncoder::new(writer);
|
||||
animal.encode(&mut encoder).unwrap();
|
||||
}),
|
||||
"\
|
||||
[\n \
|
||||
\"Frog\",\n \
|
||||
\"Henry\",\n \
|
||||
349\n\
|
||||
]".to_string()
|
||||
"{\n \
|
||||
\"variant\": \"Frog\",\n \
|
||||
\"fields\": [\n \
|
||||
\"Henry\",\n \
|
||||
349\n \
|
||||
]\n\
|
||||
}".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@
|
||||
///
|
||||
/// - `BitOr`: union
|
||||
/// - `BitAnd`: intersection
|
||||
/// - `BitXor`: toggle
|
||||
/// - `Sub`: set difference
|
||||
/// - `Not`: set complement
|
||||
///
|
||||
@ -109,6 +110,8 @@
|
||||
/// - `contains`: `true` all of the flags in `other` are contained within `self`
|
||||
/// - `insert`: inserts the specified flags in-place
|
||||
/// - `remove`: removes the specified flags in-place
|
||||
/// - `toggle`: the specified flags will be inserted if not present, and removed
|
||||
/// if they are.
|
||||
#[macro_export]
|
||||
macro_rules! bitflags {
|
||||
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
|
||||
@ -184,6 +187,11 @@ macro_rules! bitflags {
|
||||
pub fn remove(&mut self, other: $BitFlags) {
|
||||
self.bits &= !other.bits;
|
||||
}
|
||||
|
||||
/// Toggles the specified flags in-place.
|
||||
pub fn toggle(&mut self, other: $BitFlags) {
|
||||
self.bits ^= other.bits;
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
|
||||
@ -194,6 +202,14 @@ macro_rules! bitflags {
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXor<$BitFlags, $BitFlags> for $BitFlags {
|
||||
/// Returns the left flags, but with all the right flags toggled.
|
||||
#[inline]
|
||||
fn bitxor(&self, other: &$BitFlags) -> $BitFlags {
|
||||
$BitFlags { bits: self.bits ^ other.bits }
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
|
||||
/// Returns the intersection between the two sets of flags.
|
||||
#[inline]
|
||||
@ -234,7 +250,7 @@ macro_rules! bitflags {
|
||||
mod tests {
|
||||
use hash;
|
||||
use option::{Some, None};
|
||||
use ops::{BitOr, BitAnd, Sub, Not};
|
||||
use ops::{BitOr, BitAnd, BitXor, Sub, Not};
|
||||
|
||||
bitflags! {
|
||||
#[doc = "> The first principle is that you must not fool yourself — and"]
|
||||
@ -358,10 +374,14 @@ mod tests {
|
||||
fn test_operators() {
|
||||
let e1 = FlagA | FlagC;
|
||||
let e2 = FlagB | FlagC;
|
||||
assert!((e1 | e2) == FlagABC); // union
|
||||
assert!((e1 & e2) == FlagC); // intersection
|
||||
assert!((e1 - e2) == FlagA); // set difference
|
||||
assert!(!e2 == FlagA); // set complement
|
||||
assert!((e1 | e2) == FlagABC); // union
|
||||
assert!((e1 & e2) == FlagC); // intersection
|
||||
assert!((e1 - e2) == FlagA); // set difference
|
||||
assert!(!e2 == FlagA); // set complement
|
||||
assert!(e1 ^ e2 == FlagA | FlagB); // toggle
|
||||
let mut e3 = e1;
|
||||
e3.toggle(e2);
|
||||
assert!(e3 == FlagA | FlagB);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -89,7 +89,7 @@ impl<T: Default + 'static> Default for Gc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> raw::Repr<*const raw::Box<T>> for Gc<T> {}
|
||||
impl<T: 'static> raw::Repr<*const raw::GcBox<T>> for Gc<T> {}
|
||||
|
||||
impl<S: hash::Writer, T: hash::Hash<S> + 'static> hash::Hash<S> for Gc<T> {
|
||||
fn hash(&self, s: &mut S) {
|
||||
|
@ -229,7 +229,7 @@ use int;
|
||||
use iter::Iterator;
|
||||
use libc;
|
||||
use mem::transmute;
|
||||
use ops::{BitOr, BitAnd, Sub, Not};
|
||||
use ops::{BitOr, BitXor, BitAnd, Sub, Not};
|
||||
use option::{Option, Some, None};
|
||||
use os;
|
||||
use boxed::Box;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// The Rust abstract syntax tree.
|
||||
|
||||
use codemap::{Span, Spanned, DUMMY_SP};
|
||||
use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
|
||||
use abi::Abi;
|
||||
use ast_util;
|
||||
use owned_slice::OwnedSlice;
|
||||
@ -983,7 +983,8 @@ pub struct InlineAsm {
|
||||
pub clobbers: InternedString,
|
||||
pub volatile: bool,
|
||||
pub alignstack: bool,
|
||||
pub dialect: AsmDialect
|
||||
pub dialect: AsmDialect,
|
||||
pub expn_id: ExpnId,
|
||||
}
|
||||
|
||||
/// represents an argument in a function header
|
||||
|
@ -26,6 +26,7 @@ source code snippets, etc.
|
||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use libc::c_uint;
|
||||
|
||||
pub trait Pos {
|
||||
fn from_uint(n: uint) -> Self;
|
||||
@ -223,11 +224,22 @@ pub struct ExpnInfo {
|
||||
pub callee: NameAndSpan
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Clone, Show, Hash)]
|
||||
#[deriving(PartialEq, Eq, Clone, Show, Hash, Encodable, Decodable)]
|
||||
pub struct ExpnId(u32);
|
||||
|
||||
pub static NO_EXPANSION: ExpnId = ExpnId(-1);
|
||||
|
||||
impl ExpnId {
|
||||
pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId {
|
||||
ExpnId(cookie as u32)
|
||||
}
|
||||
|
||||
pub fn to_llvm_cookie(self) -> i32 {
|
||||
let ExpnId(cookie) = self;
|
||||
cookie as i32
|
||||
}
|
||||
}
|
||||
|
||||
pub type FileName = String;
|
||||
|
||||
pub struct FileLines {
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
use ast;
|
||||
use codemap;
|
||||
use codemap::Span;
|
||||
use ext::base;
|
||||
use ext::base::*;
|
||||
@ -198,6 +199,15 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
}
|
||||
}
|
||||
|
||||
let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
|
||||
call_site: sp,
|
||||
callee: codemap::NameAndSpan {
|
||||
name: "asm".to_string(),
|
||||
format: codemap::MacroBang,
|
||||
span: None,
|
||||
},
|
||||
});
|
||||
|
||||
MacExpr::new(P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprInlineAsm(ast::InlineAsm {
|
||||
@ -208,7 +218,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
clobbers: token::intern_and_get_ident(cons.as_slice()),
|
||||
volatile: volatile,
|
||||
alignstack: alignstack,
|
||||
dialect: dialect
|
||||
dialect: dialect,
|
||||
expn_id: expn_id,
|
||||
}),
|
||||
span: sp
|
||||
}))
|
||||
|
@ -344,7 +344,7 @@ impl BlockInfo {
|
||||
|
||||
/// The base map of methods for expanding syntax extension
|
||||
/// AST nodes into full ASTs
|
||||
fn initial_syntax_expander_table() -> SyntaxEnv {
|
||||
fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
|
||||
// utility function to simplify creating NormalTT syntax extensions
|
||||
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
|
||||
NormalTT(box f, None)
|
||||
@ -383,31 +383,33 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
|
||||
syntax_expanders.insert(intern("deriving"),
|
||||
Decorator(box ext::deriving::expand_meta_deriving));
|
||||
|
||||
// Quasi-quoting expanders
|
||||
syntax_expanders.insert(intern("quote_tokens"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_tokens));
|
||||
syntax_expanders.insert(intern("quote_expr"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_expr));
|
||||
syntax_expanders.insert(intern("quote_ty"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_ty));
|
||||
syntax_expanders.insert(intern("quote_method"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_method));
|
||||
syntax_expanders.insert(intern("quote_item"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_item));
|
||||
syntax_expanders.insert(intern("quote_pat"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_pat));
|
||||
syntax_expanders.insert(intern("quote_arm"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_arm));
|
||||
syntax_expanders.insert(intern("quote_stmt"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_stmt));
|
||||
if ecfg.enable_quotes {
|
||||
// Quasi-quoting expanders
|
||||
syntax_expanders.insert(intern("quote_tokens"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_tokens));
|
||||
syntax_expanders.insert(intern("quote_expr"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_expr));
|
||||
syntax_expanders.insert(intern("quote_ty"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_ty));
|
||||
syntax_expanders.insert(intern("quote_method"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_method));
|
||||
syntax_expanders.insert(intern("quote_item"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_item));
|
||||
syntax_expanders.insert(intern("quote_pat"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_pat));
|
||||
syntax_expanders.insert(intern("quote_arm"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_arm));
|
||||
syntax_expanders.insert(intern("quote_stmt"),
|
||||
builtin_normal_expander(
|
||||
ext::quote::expand_quote_stmt));
|
||||
}
|
||||
|
||||
syntax_expanders.insert(intern("line"),
|
||||
builtin_normal_expander(
|
||||
@ -466,6 +468,7 @@ pub struct ExtCtxt<'a> {
|
||||
impl<'a> ExtCtxt<'a> {
|
||||
pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
|
||||
ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
|
||||
let env = initial_syntax_expander_table(&ecfg);
|
||||
ExtCtxt {
|
||||
parse_sess: parse_sess,
|
||||
cfg: cfg,
|
||||
@ -474,7 +477,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
ecfg: ecfg,
|
||||
trace_mac: false,
|
||||
exported_macros: Vec::new(),
|
||||
syntax_env: initial_syntax_expander_table(),
|
||||
syntax_env: env,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -975,8 +975,19 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
|
||||
}
|
||||
|
||||
pub struct ExpansionConfig {
|
||||
pub deriving_hash_type_parameter: bool,
|
||||
pub crate_name: String,
|
||||
pub deriving_hash_type_parameter: bool,
|
||||
pub enable_quotes: bool,
|
||||
}
|
||||
|
||||
impl ExpansionConfig {
|
||||
pub fn default(crate_name: String) -> ExpansionConfig {
|
||||
ExpansionConfig {
|
||||
crate_name: crate_name,
|
||||
deriving_hash_type_parameter: false,
|
||||
enable_quotes: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExportedMacros {
|
||||
@ -1106,7 +1117,7 @@ impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{pattern_bindings, expand_crate, contains_macro_escape};
|
||||
use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
|
||||
use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
|
||||
use ast;
|
||||
use ast::{Attribute_, AttrOuter, MetaWord, Name};
|
||||
use attr;
|
||||
@ -1171,6 +1182,10 @@ mod test {
|
||||
// these following tests are quite fragile, in that they don't test what
|
||||
// *kind* of failure occurs.
|
||||
|
||||
fn test_ecfg() -> ExpansionConfig {
|
||||
ExpansionConfig::default("test".to_string())
|
||||
}
|
||||
|
||||
// make sure that macros can't escape fns
|
||||
#[should_fail]
|
||||
#[test] fn macros_cant_escape_fns_test () {
|
||||
@ -1182,11 +1197,7 @@ mod test {
|
||||
src,
|
||||
Vec::new(), &sess);
|
||||
// should fail:
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_name: "test".to_string(),
|
||||
};
|
||||
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||
expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
|
||||
}
|
||||
|
||||
// make sure that macros can't escape modules
|
||||
@ -1199,11 +1210,7 @@ mod test {
|
||||
"<test>".to_string(),
|
||||
src,
|
||||
Vec::new(), &sess);
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_name: "test".to_string(),
|
||||
};
|
||||
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||
expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
|
||||
}
|
||||
|
||||
// macro_escape modules should allow macros to escape
|
||||
@ -1215,11 +1222,7 @@ mod test {
|
||||
"<test>".to_string(),
|
||||
src,
|
||||
Vec::new(), &sess);
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_name: "test".to_string(),
|
||||
};
|
||||
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
|
||||
expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast);
|
||||
}
|
||||
|
||||
#[test] fn test_contains_flatten (){
|
||||
@ -1252,11 +1255,7 @@ mod test {
|
||||
let ps = parse::new_parse_sess();
|
||||
let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
|
||||
// the cfg argument actually does matter, here...
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_name: "test".to_string(),
|
||||
};
|
||||
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
|
||||
expand_crate(&ps,test_ecfg(),vec!(),vec!(),crate_ast)
|
||||
}
|
||||
|
||||
// find the pat_ident paths in a crate
|
||||
|
@ -102,6 +102,7 @@ pub struct Features {
|
||||
pub rustc_diagnostic_macros: bool,
|
||||
pub import_shadowing: bool,
|
||||
pub visible_private_types: bool,
|
||||
pub quote: bool,
|
||||
}
|
||||
|
||||
impl Features {
|
||||
@ -112,6 +113,7 @@ impl Features {
|
||||
rustc_diagnostic_macros: false,
|
||||
import_shadowing: false,
|
||||
visible_private_types: false,
|
||||
quote: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,10 +284,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
||||
fn visit_mac(&mut self, macro: &ast::Mac) {
|
||||
let ast::MacInvocTT(ref path, _, _) = macro.node;
|
||||
let id = path.segments.last().unwrap().identifier;
|
||||
let quotes = ["quote_tokens", "quote_expr", "quote_ty",
|
||||
"quote_item", "quote_pat", "quote_stmt"];
|
||||
let msg = " is not stable enough for use and are subject to change";
|
||||
|
||||
|
||||
if id == token::str_to_ident("macro_rules") {
|
||||
self.gate_feature("macro_rules", path.span, "macro definitions are \
|
||||
@ -311,16 +309,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
||||
self.gate_feature("concat_idents", path.span, "`concat_idents` is not \
|
||||
stable enough for use and is subject to change");
|
||||
}
|
||||
|
||||
else {
|
||||
for "e in quotes.iter() {
|
||||
if id == token::str_to_ident(quote) {
|
||||
self.gate_feature("quote",
|
||||
path.span,
|
||||
format!("{}{}", quote, msg).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
|
||||
@ -483,6 +471,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features,
|
||||
rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
|
||||
import_shadowing: cx.has_feature("import_shadowing"),
|
||||
visible_private_types: cx.has_feature("visible_private_types"),
|
||||
quote: cx.has_feature("quote"),
|
||||
},
|
||||
unknown_features)
|
||||
}
|
||||
|
@ -1279,7 +1279,8 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
|
||||
clobbers,
|
||||
volatile,
|
||||
alignstack,
|
||||
dialect
|
||||
dialect,
|
||||
expn_id,
|
||||
}) => ExprInlineAsm(InlineAsm {
|
||||
inputs: inputs.move_map(|(c, input)| {
|
||||
(c, folder.fold_expr(input))
|
||||
@ -1292,7 +1293,8 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
|
||||
clobbers: clobbers,
|
||||
volatile: volatile,
|
||||
alignstack: alignstack,
|
||||
dialect: dialect
|
||||
dialect: dialect,
|
||||
expn_id: expn_id,
|
||||
}),
|
||||
ExprMac(mac) => ExprMac(folder.fold_mac(mac)),
|
||||
ExprStruct(path, fields, maybe_expr) => {
|
||||
|
@ -33,6 +33,7 @@ extern crate debug;
|
||||
#[phase(plugin, link)] extern crate log;
|
||||
extern crate serialize;
|
||||
extern crate term;
|
||||
extern crate libc;
|
||||
|
||||
pub mod util {
|
||||
pub mod interner;
|
||||
|
@ -2084,7 +2084,7 @@ impl<'a> Parser<'a> {
|
||||
ExprBlock(blk));
|
||||
},
|
||||
token::BINOP(token::OR) | token::OROR => {
|
||||
return self.parse_lambda_expr(CaptureByValue);
|
||||
return self.parse_lambda_expr(CaptureByRef);
|
||||
},
|
||||
// FIXME #13626: Should be able to stick in
|
||||
// token::SELF_KEYWORD_NAME
|
||||
@ -2135,8 +2135,8 @@ impl<'a> Parser<'a> {
|
||||
hi = self.last_span.hi;
|
||||
}
|
||||
_ => {
|
||||
if self.eat_keyword(keywords::Ref) {
|
||||
return self.parse_lambda_expr(CaptureByRef);
|
||||
if self.eat_keyword(keywords::Move) {
|
||||
return self.parse_lambda_expr(CaptureByValue);
|
||||
}
|
||||
if self.eat_keyword(keywords::Proc) {
|
||||
let decl = self.parse_proc_decl();
|
||||
|
@ -482,40 +482,41 @@ declare_special_idents_and_keywords! {
|
||||
(25, Loop, "loop");
|
||||
(26, Match, "match");
|
||||
(27, Mod, "mod");
|
||||
(28, Mut, "mut");
|
||||
(29, Once, "once");
|
||||
(30, Pub, "pub");
|
||||
(31, Ref, "ref");
|
||||
(32, Return, "return");
|
||||
(28, Move, "move");
|
||||
(29, Mut, "mut");
|
||||
(30, Once, "once");
|
||||
(31, Pub, "pub");
|
||||
(32, Ref, "ref");
|
||||
(33, Return, "return");
|
||||
// Static and Self are also special idents (prefill de-dupes)
|
||||
(super::STATIC_KEYWORD_NAME_NUM, Static, "static");
|
||||
(super::SELF_KEYWORD_NAME_NUM, Self, "self");
|
||||
(33, Struct, "struct");
|
||||
(34, Struct, "struct");
|
||||
(super::SUPER_KEYWORD_NAME_NUM, Super, "super");
|
||||
(34, True, "true");
|
||||
(35, Trait, "trait");
|
||||
(36, Type, "type");
|
||||
(37, Unsafe, "unsafe");
|
||||
(38, Use, "use");
|
||||
(39, Virtual, "virtual");
|
||||
(40, While, "while");
|
||||
(41, Continue, "continue");
|
||||
(42, Proc, "proc");
|
||||
(43, Box, "box");
|
||||
(44, Const, "const");
|
||||
(45, Where, "where");
|
||||
(35, True, "true");
|
||||
(36, Trait, "trait");
|
||||
(37, Type, "type");
|
||||
(38, Unsafe, "unsafe");
|
||||
(39, Use, "use");
|
||||
(40, Virtual, "virtual");
|
||||
(41, While, "while");
|
||||
(42, Continue, "continue");
|
||||
(43, Proc, "proc");
|
||||
(44, Box, "box");
|
||||
(45, Const, "const");
|
||||
(46, Where, "where");
|
||||
|
||||
'reserved:
|
||||
(46, Alignof, "alignof");
|
||||
(47, Be, "be");
|
||||
(48, Offsetof, "offsetof");
|
||||
(49, Priv, "priv");
|
||||
(50, Pure, "pure");
|
||||
(51, Sizeof, "sizeof");
|
||||
(52, Typeof, "typeof");
|
||||
(53, Unsized, "unsized");
|
||||
(54, Yield, "yield");
|
||||
(55, Do, "do");
|
||||
(47, Alignof, "alignof");
|
||||
(48, Be, "be");
|
||||
(49, Offsetof, "offsetof");
|
||||
(50, Priv, "priv");
|
||||
(51, Pure, "pure");
|
||||
(52, Sizeof, "sizeof");
|
||||
(53, Typeof, "typeof");
|
||||
(54, Unsized, "unsized");
|
||||
(55, Yield, "yield");
|
||||
(56, Do, "do");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2176,8 +2176,8 @@ impl<'a> State<'a> {
|
||||
pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
|
||||
-> IoResult<()> {
|
||||
match capture_clause {
|
||||
ast::CaptureByValue => Ok(()),
|
||||
ast::CaptureByRef => self.word_space("ref"),
|
||||
ast::CaptureByValue => self.word_space("move"),
|
||||
ast::CaptureByRef => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,10 +235,7 @@ fn generate_test_harness(sess: &ParseSess,
|
||||
sess: sess,
|
||||
span_diagnostic: sd,
|
||||
ext_cx: ExtCtxt::new(sess, cfg.clone(),
|
||||
ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_name: "test".to_string(),
|
||||
}),
|
||||
ExpansionConfig::default("test".to_string())),
|
||||
path: Vec::new(),
|
||||
testfns: Vec::new(),
|
||||
reexport_test_harness_main: reexport_test_harness_main,
|
||||
|
@ -871,3 +871,18 @@ extern "C" void LLVMWriteDebugLocToString(
|
||||
raw_rust_string_ostream os(str);
|
||||
unwrap(dl)->print(*unwrap(C), os);
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
|
||||
|
||||
extern "C" void LLVMSetInlineAsmDiagnosticHandler(
|
||||
LLVMContextRef C,
|
||||
LLVMContext::InlineAsmDiagHandlerTy H,
|
||||
void *CX)
|
||||
{
|
||||
unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
|
||||
}
|
||||
|
||||
extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
|
||||
raw_rust_string_ostream os(str);
|
||||
unwrap(d)->print("", os);
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ void LLVMRustSetLastError(const char*);
|
||||
typedef struct OpaqueRustString *RustStringRef;
|
||||
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
|
||||
typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
|
||||
typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
|
||||
|
||||
extern "C" void
|
||||
rust_llvm_string_write_impl(RustStringRef str, const char *ptr, size_t size);
|
||||
|
@ -1,3 +1,12 @@
|
||||
S 2014-09-28 7eb9337
|
||||
freebsd-x86_64 d45e0edd44f40a976ea0affaadd98732684cfca0
|
||||
linux-i386 3acb35755aa62b7ff78f76007d9a70696fce7aa7
|
||||
linux-x86_64 2615b67b700ae8f7d8d87c043207a1a6e2339389
|
||||
macos-i386 5eb4552dc66a14e1eff6e806a8ba27f4a73bb02a
|
||||
macos-x86_64 c6052632443f638f5024ae38f33ae2c80d8b18bd
|
||||
winnt-i386 269f46347b5766bff6f888c4307d50c475d3fe0f
|
||||
winnt-x86_64 06f89825cecda7f2e36a4660ffe6d2d4a0430ab4
|
||||
|
||||
S 2014-09-22 437179e
|
||||
freebsd-x86_64 f693c0441de3dbb2d471dde5a5045ac8a48807d8
|
||||
linux-i386 5c2132b65f45c21b43d28de6a9460978b1a7b08a
|
||||
|
20
src/test/compile-fail/asm-src-loc-codegen-units.rs
Normal file
20
src/test/compile-fail/asm-src-loc-codegen-units.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
//
|
||||
// compile-flags: -C codegen-units=2
|
||||
// error-pattern: build without -C codegen-units for more exact errors
|
||||
|
||||
#![feature(asm)]
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
asm!("nowayisthisavalidinstruction");
|
||||
}
|
||||
}
|
17
src/test/compile-fail/asm-src-loc.rs
Normal file
17
src/test/compile-fail/asm-src-loc.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// 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(asm)]
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
asm!("nowayisthisavalidinstruction"); //~ ERROR invalid instruction
|
||||
}
|
||||
}
|
@ -15,7 +15,9 @@
|
||||
extern crate trait_impl_conflict;
|
||||
use trait_impl_conflict::Foo;
|
||||
|
||||
impl<A> Foo for A { //~ ERROR E0117
|
||||
impl<A> Foo for A {
|
||||
//~^ ERROR E0117
|
||||
//~^^ ERROR E0119
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
24
src/test/compile-fail/issue-16465.rs
Normal file
24
src/test/compile-fail/issue-16465.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
// Used to cause an ICE
|
||||
|
||||
struct Foo<T>{
|
||||
x : T
|
||||
}
|
||||
|
||||
type FooInt = Foo<int>;
|
||||
|
||||
impl Drop for FooInt {
|
||||
//~^ ERROR cannot implement a destructor on a structure with type parameters
|
||||
fn drop(&mut self){}
|
||||
}
|
||||
|
||||
fn main() {}
|
24
src/test/compile-fail/issue-17441.rs
Normal file
24
src/test/compile-fail/issue-17441.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
fn main() {
|
||||
let _foo = &[1u, 2] as [uint];
|
||||
//~^ ERROR cast to unsized type: `&[uint, .. 2]` as `[uint]`
|
||||
//~^^ NOTE consider using an implicit coercion to `&[uint]` instead
|
||||
let _bar = box 1u as std::fmt::Show;
|
||||
//~^ ERROR cast to unsized type: `Box<uint>` as `core::fmt::Show`
|
||||
//~^^ NOTE did you mean `Box<core::fmt::Show>`?
|
||||
let _baz = 1u as std::fmt::Show;
|
||||
//~^ ERROR cast to unsized type: `uint` as `core::fmt::Show`
|
||||
//~^^ NOTE consider using a box or reference as appropriate
|
||||
let _quux = [1u, 2] as [uint];
|
||||
//~^ ERROR cast to unsized type: `[uint, .. 2]` as `[uint]`
|
||||
//~^^ NOTE consider using a box or reference as appropriate
|
||||
}
|
18
src/test/compile-fail/pat-range-bad-dots.rs
Normal file
18
src/test/compile-fail/pat-range-bad-dots.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// 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.
|
||||
|
||||
// ignore-test
|
||||
|
||||
pub fn main() {
|
||||
match 22i {
|
||||
0 .. 3 => {} //~ ERROR expected `=>`, found `..`
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ fn main() {
|
||||
{
|
||||
let c = 1;
|
||||
let c_ref = &c; //~ ERROR `c` does not live long enough
|
||||
f = |&mut: a: int, b: int| { a + b + *c_ref };
|
||||
f = move |&mut: a: int, b: int| { a + b + *c_ref };
|
||||
}
|
||||
}
|
||||
|
||||
|
12
src/test/run-make/lto-readonly-lib/Makefile
Normal file
12
src/test/run-make/lto-readonly-lib/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs
|
||||
|
||||
# the compiler needs to copy and modify the rlib file when performing
|
||||
# LTO, so we should ensure that it can cope with the original rlib
|
||||
# being read-only.
|
||||
chmod 444 $(TMPDIR)/*.rlib
|
||||
|
||||
$(RUSTC) main.rs -C lto
|
||||
$(call RUN,main)
|
11
src/test/run-make/lto-readonly-lib/lib.rs
Normal file
11
src/test/run-make/lto-readonly-lib/lib.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// 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 = "rlib"]
|
13
src/test/run-make/lto-readonly-lib/main.rs
Normal file
13
src/test/run-make/lto-readonly-lib/main.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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 lib;
|
||||
|
||||
fn main() {}
|
6
src/test/run-make/rustdoc-where/Makefile
Normal file
6
src/test/run-make/rustdoc-where/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all: verify.sh foo.rs
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||
cp verify.sh $(TMPDIR)
|
||||
$(call RUN,verify.sh) $(TMPDIR)
|
26
src/test/run-make/rustdoc-where/foo.rs
Normal file
26
src/test/run-make/rustdoc-where/foo.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// 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.
|
||||
|
||||
pub trait MyTrait {}
|
||||
|
||||
pub struct Alpha<A> where A: MyTrait;
|
||||
pub trait Bravo<B> where B: MyTrait {}
|
||||
pub fn charlie<C>() where C: MyTrait {}
|
||||
|
||||
pub struct Delta<D>;
|
||||
impl<D> Delta<D> where D: MyTrait {
|
||||
pub fn delta() {}
|
||||
}
|
||||
|
||||
pub struct Echo<E>;
|
||||
impl<E> MyTrait for Echo<E> where E: MyTrait {}
|
||||
|
||||
pub enum Foxtrot<F> {}
|
||||
impl<F> MyTrait for Foxtrot<F> where F: MyTrait {}
|
23
src/test/run-make/rustdoc-where/verify.sh
Executable file
23
src/test/run-make/rustdoc-where/verify.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# $1 is the TMPDIR
|
||||
DOC=$1/doc/foo
|
||||
|
||||
grep "Alpha.*where.*A:.*MyTrait" $DOC/struct.Alpha.html > /dev/null
|
||||
echo "Alpha"
|
||||
grep "Bravo.*where.*B:.*MyTrait" $DOC/trait.Bravo.html > /dev/null
|
||||
echo "Bravo"
|
||||
grep "charlie.*where.*C:.*MyTrait" $DOC/fn.charlie.html > /dev/null
|
||||
echo "Charlie"
|
||||
grep "impl.*Delta.*where.*D:.*MyTrait" $DOC/struct.Delta.html > /dev/null
|
||||
echo "Delta"
|
||||
grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/struct.Echo.html > /dev/null
|
||||
echo "Echo"
|
||||
grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/enum.Foxtrot.html > /dev/null
|
||||
echo "Foxtrot"
|
||||
|
||||
# check "Implementors" section of MyTrait
|
||||
grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null
|
||||
grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null
|
||||
echo "Implementors OK"
|
@ -17,7 +17,7 @@ fn each<T>(x: &[T], f: |&T|) {
|
||||
fn main() {
|
||||
let mut sum = 0u;
|
||||
let elems = [ 1u, 2, 3, 4, 5 ];
|
||||
each(elems, ref |val| sum += *val);
|
||||
each(elems, |val| sum += *val);
|
||||
assert_eq!(sum, 15);
|
||||
}
|
||||
|
||||
|
17
src/test/run-pass/non-built-in-quote.rs
Normal file
17
src/test/run-pass/non-built-in-quote.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// 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)]
|
||||
|
||||
macro_rules! quote_tokens ( () => (()) )
|
||||
|
||||
pub fn main() {
|
||||
quote_tokens!();
|
||||
}
|
@ -24,8 +24,8 @@ fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
|
||||
|
||||
fn main() {
|
||||
let z: int = 7;
|
||||
assert_eq!(a(|&: x: int, y| x + y + z), 10);
|
||||
assert_eq!(b(|&mut: x: int, y| x + y + z), 14);
|
||||
assert_eq!(c(|: x: int, y| x + y + z), 18);
|
||||
assert_eq!(a(move |&: x: int, y| x + y + z), 10);
|
||||
assert_eq!(b(move |&mut: x: int, y| x + y + z), 14);
|
||||
assert_eq!(c(move |: x: int, y| x + y + z), 18);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,8 @@
|
||||
use std::ops::FnMut;
|
||||
|
||||
fn make_adder(x: int) -> Box<FnMut<(int,),int>+'static> {
|
||||
(box |&mut: y: int| -> int { x + y }) as Box<FnMut<(int,),int>+'static>
|
||||
(box move |&mut: y: int| -> int { x + y }) as
|
||||
Box<FnMut<(int,),int>+'static>
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
@ -55,13 +55,13 @@ fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
|
||||
|
||||
fn test_fn() {
|
||||
{
|
||||
a(|&: a: int, b| { a + b });
|
||||
a(move |&: a: int, b| { a + b });
|
||||
}
|
||||
assert_eq!(drop_count(), 0);
|
||||
|
||||
{
|
||||
let z = &Droppable::new();
|
||||
a(|&: a: int, b| { z; a + b });
|
||||
a(move |&: a: int, b| { z; a + b });
|
||||
assert_eq!(drop_count(), 0);
|
||||
}
|
||||
assert_eq!(drop_count(), 1);
|
||||
@ -69,7 +69,7 @@ fn test_fn() {
|
||||
{
|
||||
let z = &Droppable::new();
|
||||
let zz = &Droppable::new();
|
||||
a(|&: a: int, b| { z; zz; a + b });
|
||||
a(move |&: a: int, b| { z; zz; a + b });
|
||||
assert_eq!(drop_count(), 1);
|
||||
}
|
||||
assert_eq!(drop_count(), 3);
|
||||
@ -77,13 +77,13 @@ fn test_fn() {
|
||||
|
||||
fn test_fn_mut() {
|
||||
{
|
||||
b(|&mut: a: int, b| { a + b });
|
||||
b(move |&mut: a: int, b| { a + b });
|
||||
}
|
||||
assert_eq!(drop_count(), 3);
|
||||
|
||||
{
|
||||
let z = &Droppable::new();
|
||||
b(|&mut: a: int, b| { z; a + b });
|
||||
b(move |&mut: a: int, b| { z; a + b });
|
||||
assert_eq!(drop_count(), 3);
|
||||
}
|
||||
assert_eq!(drop_count(), 4);
|
||||
@ -91,7 +91,7 @@ fn test_fn_mut() {
|
||||
{
|
||||
let z = &Droppable::new();
|
||||
let zz = &Droppable::new();
|
||||
b(|&mut: a: int, b| { z; zz; a + b });
|
||||
b(move |&mut: a: int, b| { z; zz; a + b });
|
||||
assert_eq!(drop_count(), 4);
|
||||
}
|
||||
assert_eq!(drop_count(), 6);
|
||||
@ -99,13 +99,13 @@ fn test_fn_mut() {
|
||||
|
||||
fn test_fn_once() {
|
||||
{
|
||||
c(|: a: int, b| { a + b });
|
||||
c(move |: a: int, b| { a + b });
|
||||
}
|
||||
assert_eq!(drop_count(), 6);
|
||||
|
||||
{
|
||||
let z = Droppable::new();
|
||||
c(|: a: int, b| { z; a + b });
|
||||
c(move |: a: int, b| { z; a + b });
|
||||
assert_eq!(drop_count(), 7);
|
||||
}
|
||||
assert_eq!(drop_count(), 7);
|
||||
@ -113,7 +113,7 @@ fn test_fn_once() {
|
||||
{
|
||||
let z = Droppable::new();
|
||||
let zz = Droppable::new();
|
||||
c(|: a: int, b| { z; zz; a + b });
|
||||
c(move |: a: int, b| { z; zz; a + b });
|
||||
assert_eq!(drop_count(), 9);
|
||||
}
|
||||
assert_eq!(drop_count(), 9);
|
||||
|
@ -27,8 +27,8 @@ fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
|
||||
|
||||
fn main() {
|
||||
let z = 10;
|
||||
assert_eq!(a(|&: x: int, y| x + y + z), 13);
|
||||
assert_eq!(b(|&mut: x: int, y| x + y + z), 17);
|
||||
assert_eq!(c(|: x: int, y| x + y + z), 21);
|
||||
assert_eq!(a(move |&: x: int, y| x + y + z), 13);
|
||||
assert_eq!(b(move |&mut: x: int, y| x + y + z), 17);
|
||||
assert_eq!(c(move |: x: int, y| x + y + z), 21);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user