Merge branch 'incoming' into newsnap
This commit is contained in:
commit
52c38ba886
@ -55,6 +55,10 @@ rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) \
|
||||
|
||||
include config.mk
|
||||
|
||||
# We track all of the object files we might build so that we can find
|
||||
# and include all of the .d files in one fell swoop.
|
||||
ALL_OBJ_FILES :=
|
||||
|
||||
MKFILE_DEPS := config.stamp $(call rwildcard,$(CFG_SRC_DIR)mk/,*)
|
||||
NON_HOST_TRIPLES = $(filter-out $(CFG_HOST_TRIPLE),$(CFG_TARGET_TRIPLES))
|
||||
|
||||
@ -527,3 +531,8 @@ ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \
|
||||
CFG_INFO := $(info cfg: including ctags rules)
|
||||
include $(CFG_SRC_DIR)mk/ctags.mk
|
||||
endif
|
||||
|
||||
# Find all of the .d files and include them to add information about
|
||||
# header file dependencies.
|
||||
ALL_DEP_FILES := $(ALL_OBJ_FILES:%.o=%.d)
|
||||
-include $(ALL_DEP_FILES)
|
||||
|
@ -210,18 +210,20 @@ ifeq ($(CFG_C_COMPILER),clang)
|
||||
CXX=clang++
|
||||
endif
|
||||
ifeq ($(origin CPP),default)
|
||||
CPP=cpp
|
||||
CPP=clang -E
|
||||
endif
|
||||
CFG_GCCISH_CFLAGS += -Wall -Werror -fno-rtti -g
|
||||
CFG_GCCISH_LINK_FLAGS += -g
|
||||
CFG_DEPEND_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_CFLAGS) -MT "$(1)" \
|
||||
-MM $(2)
|
||||
# These flags will cause the compiler to produce a .d file
|
||||
# next to the .o file that lists header deps.
|
||||
CFG_DEPEND_FLAGS = -MMD -MP -MT $(1) -MF $(1:%.o=%.d)
|
||||
|
||||
define CFG_MAKE_CC
|
||||
CFG_COMPILE_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
|
||||
$$(CFG_GCCISH_CFLAGS) $$(CFG_CLANG_CFLAGS) \
|
||||
$$(CFG_GCCISH_CFLAGS_$$(HOST_$(1))) \
|
||||
$$(CFG_CLANG_CFLAGS_$$(HOST_$(1))) \
|
||||
$$(CFG_DEPEND_FLAGS) \
|
||||
-c -o $$(1) $$(2)
|
||||
CFG_LINK_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
|
||||
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
|
||||
@ -241,12 +243,13 @@ ifeq ($(CFG_C_COMPILER),gcc)
|
||||
CXX=g++
|
||||
endif
|
||||
ifeq ($(origin CPP),default)
|
||||
CPP=cpp
|
||||
CPP=gcc -E
|
||||
endif
|
||||
CFG_GCCISH_CFLAGS += -Wall -Werror -fno-rtti -g
|
||||
CFG_GCCISH_LINK_FLAGS += -g
|
||||
CFG_DEPEND_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_CFLAGS) -MT "$(1)" \
|
||||
-MM $(2)
|
||||
# These flags will cause the compiler to produce a .d file
|
||||
# next to the .o file that lists header deps.
|
||||
CFG_DEPEND_FLAGS = -MMD -MP -MT $(1) -MF $(1:%.o=%.d)
|
||||
|
||||
define CFG_MAKE_CC
|
||||
CFG_COMPILE_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
|
||||
@ -254,6 +257,7 @@ ifeq ($(CFG_C_COMPILER),gcc)
|
||||
$$(CFG_GCCISH_CFLAGS_$$(HOST_$(1))) \
|
||||
$$(CFG_GCC_CFLAGS) \
|
||||
$$(CFG_GCC_CFLAGS_$$(HOST_$(1))) \
|
||||
$$(CFG_DEPEND_FLAGS) \
|
||||
-c -o $$(1) $$(2)
|
||||
CFG_LINK_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
|
||||
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
|
||||
@ -272,7 +276,7 @@ endif
|
||||
# We're using llvm-mc as our assembler because it supports
|
||||
# .cfi pseudo-ops on mac
|
||||
define CFG_MAKE_ASSEMBLER
|
||||
CFG_ASSEMBLE_$(1)=$$(CPP) $$(2) | \
|
||||
CFG_ASSEMBLE_$(1)=$$(CPP) $$(CFG_DEPEND_FLAGS) $$(2) | \
|
||||
$$(LLVM_MC_$$(CFG_HOST_TRIPLE)) \
|
||||
-assemble \
|
||||
-filetype=obj \
|
||||
|
24
mk/rt.mk
24
mk/rt.mk
@ -79,17 +79,6 @@ RUNTIME_S_$(1) := rt/arch/$$(HOST_$(1))/_context.S \
|
||||
rt/arch/$$(HOST_$(1))/ccall.S \
|
||||
rt/arch/$$(HOST_$(1))/record_sp.S
|
||||
|
||||
RUNTIME_HDR_$(1) := $$(wildcard \
|
||||
rt/*.h \
|
||||
rt/bigint/*.h \
|
||||
rt/isaac/*.h \
|
||||
rt/msvc/*.h \
|
||||
rt/sync/*.h \
|
||||
rt/uthash/*.h \
|
||||
rt/util/*.h \
|
||||
rt/vg/*.h \
|
||||
rt/arch/$$(HOST_$(1))/*.h)
|
||||
|
||||
ifeq ($$(HOST_$(1)), i386)
|
||||
LIBUV_ARCH_$(1) := ia32
|
||||
else
|
||||
@ -116,25 +105,28 @@ RUNTIME_INCS_$(1) := -I $$(S)src/rt -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
|
||||
-I $$(S)src/libuv/include
|
||||
RUNTIME_OBJS_$(1) := $$(RUNTIME_CS_$(1):rt/%.cpp=rt/$(1)/%.o) \
|
||||
$$(RUNTIME_S_$(1):rt/%.S=rt/$(1)/%.o)
|
||||
ALL_OBJ_FILES += $$(RUNTIME_OBJS_$(1))
|
||||
|
||||
MORESTACK_OBJ_$(1) := rt/$(1)/arch/$$(HOST_$(1))/morestack.o
|
||||
ALL_OBJ_FILES += $$(MORESTACK_OBJS_$(1))
|
||||
|
||||
RUNTIME_LIBS_$(1) := $$(LIBUV_LIB_$(1))
|
||||
|
||||
rt/$(1)/%.o: rt/%.cpp $$(RUNTIME_HDR_$(1)) $$(MKFILE_DEPS)
|
||||
rt/$(1)/%.o: rt/%.cpp $$(MKFILE_DEPS)
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$$(call CFG_COMPILE_C_$(1), $$@, $$(RUNTIME_INCS_$(1)) \
|
||||
$$(SNAP_DEFINES)) $$<
|
||||
|
||||
rt/$(1)/%.o: rt/%.S $$(RUNTIME_HDR_$(1)) $$(MKFILE_DEPS) \
|
||||
rt/$(1)/%.o: rt/%.S $$(MKFILE_DEPS) \
|
||||
$$(LLVM_CONFIG_$$(CFG_HOST_TRIPLE))
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
|
||||
|
||||
rt/$(1)/arch/$$(HOST_$(1))/libmorestack.a: \
|
||||
rt/$(1)/arch/$$(HOST_$(1))/morestack.o
|
||||
rt/$(1)/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJ_$(1))
|
||||
@$$(call E, link: $$@)
|
||||
$$(Q)ar rcs $$@ $$<
|
||||
|
||||
rt/$(1)/$(CFG_RUNTIME): $$(RUNTIME_OBJS_$(1)) $$(MKFILE_DEPS) \
|
||||
$$(RUNTIME_HDR_$(1)) \
|
||||
$$(RUNTIME_DEF_$(1)) \
|
||||
$$(RUNTIME_LIBS_$(1))
|
||||
@$$(call E, link: $$@)
|
||||
|
@ -20,6 +20,7 @@ RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
|
||||
-iquote $$(LLVM_INCDIR_$(1)) \
|
||||
-iquote $$(S)src/rustllvm/include
|
||||
RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=rustllvm/$(1)/%.o)
|
||||
ALL_OBJ_FILES += $$(RUSTLLVM_OBJS_OBJS_$(1))
|
||||
|
||||
rustllvm/$(1)/$(CFG_RUSTLLVM): $$(RUSTLLVM_OBJS_OBJS_$(1)) \
|
||||
$$(MKFILE_DEPS) $$(RUSTLLVM_DEF_$(1))
|
||||
|
@ -129,7 +129,7 @@ impl extensions<A> for dvec<A> {
|
||||
#[doc = "Overwrite the current contents"]
|
||||
fn set(+w: [mut A]) {
|
||||
self.check_not_borrowed();
|
||||
self.data <- w; //FIXME check for recursive use
|
||||
self.data <- w; //FIXME check for recursive use (#2607)
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,25 +177,28 @@ impl extensions<A:copy> for dvec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME--
|
||||
//#[doc = "
|
||||
// Append all elements of an iterable.
|
||||
//
|
||||
// Failure will occur if the iterable's `each()` method
|
||||
// attempts to access this vector.
|
||||
//"]
|
||||
//fn append_iter<I:iter::base<A>>(ts: I) {
|
||||
// self.data.swap { |v|
|
||||
// alt ts.size_hint() {
|
||||
// none {}
|
||||
// some(h) { vec::reserve(v, len(v) + h) }
|
||||
// }
|
||||
//
|
||||
// for ts.each { |t| v = v + [t] };
|
||||
//
|
||||
// v
|
||||
// }
|
||||
//}
|
||||
#[doc = "
|
||||
Append all elements of an iterable.
|
||||
|
||||
Failure will occur if the iterable's `each()` method
|
||||
attempts to access this vector.
|
||||
"]
|
||||
fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
|
||||
self.swap { |v|
|
||||
let mut v = alt ts.size_hint() {
|
||||
none { v }
|
||||
some(h) {
|
||||
let len = v.len() + h;
|
||||
let mut v <- v;
|
||||
vec::reserve(v, len);
|
||||
v
|
||||
}
|
||||
};
|
||||
|
||||
for ts.each { |t| v += [t] };
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Gets a copy of the current contents.
|
||||
|
@ -109,7 +109,7 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> str {
|
||||
// stack of digits
|
||||
let mut fractionalParts = [];
|
||||
|
||||
// FIXME:
|
||||
// FIXME: (#2608)
|
||||
// This used to return right away without rounding, as "[-]num",
|
||||
// but given epsilon like in f64.rs, I don't see how the comparison
|
||||
// to epsilon did much when only used there.
|
||||
|
@ -137,7 +137,7 @@ impl num of num::num for T {
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Has alignment issues on windows and 32-bit linux
|
||||
// FIXME: Has alignment issues on windows and 32-bit linux (#2609)
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_from_str() {
|
||||
@ -157,7 +157,7 @@ fn test_from_str() {
|
||||
assert from_str("x") == none;
|
||||
}
|
||||
|
||||
// FIXME: Has alignment issues on windows and 32-bit linux
|
||||
// FIXME: Has alignment issues on windows and 32-bit linux (#2609)
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_parse_buf() {
|
||||
|
@ -25,7 +25,7 @@ impl extensions<A:copy> for IMPL_T<A> {
|
||||
fn map_to_vec<B>(op: fn(A) -> B) -> [B] { iter::map_to_vec(self, op) }
|
||||
fn to_vec() -> [A] { iter::to_vec(self) }
|
||||
|
||||
// FIXME--bug in resolve prevents this from working
|
||||
// FIXME--bug in resolve prevents this from working (#2611)
|
||||
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> [B] {
|
||||
// iter::flat_map_to_vec(self, op)
|
||||
// }
|
||||
|
@ -1,8 +1,8 @@
|
||||
#[doc="An interface for numbers."]
|
||||
|
||||
iface num {
|
||||
// FIXME: Cross-crate overloading doesn't work yet.
|
||||
// FIXME: Interface inheritance.
|
||||
// FIXME: Cross-crate overloading doesn't work yet. (#2615)
|
||||
// FIXME: Interface inheritance. (#2616)
|
||||
fn add(&&other: self) -> self;
|
||||
fn sub(&&other: self) -> self;
|
||||
fn mul(&&other: self) -> self;
|
||||
|
@ -36,7 +36,7 @@ export last_os_error;
|
||||
export set_exit_status;
|
||||
export walk_dir;
|
||||
|
||||
// FIXME: move these to str perhaps?
|
||||
// FIXME: move these to str perhaps? #2620
|
||||
export as_c_charp, fill_charp_buf;
|
||||
|
||||
native mod rustrt {
|
||||
@ -86,7 +86,7 @@ mod win32 {
|
||||
fn fill_utf16_buf_and_decode(f: fn(*mut u16, dword) -> dword)
|
||||
-> option<str> {
|
||||
|
||||
// FIXME: remove these when export globs work properly.
|
||||
// FIXME: remove these when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::consts::os::extra::*;
|
||||
|
||||
@ -167,7 +167,7 @@ mod global_env {
|
||||
sched: some({
|
||||
mode: task::single_threaded,
|
||||
// FIXME: This would be a good place to use
|
||||
// a very small native stack
|
||||
// a very small native stack (#2621)
|
||||
native_stack_size: none
|
||||
})
|
||||
with task::get_opts(builder)
|
||||
@ -227,7 +227,7 @@ mod global_env {
|
||||
#[cfg(unix)]
|
||||
fn setenv(n: str, v: str) {
|
||||
|
||||
// FIXME: remove this when export globs work properly.
|
||||
// FIXME: remove this when export globs work properly. #1238
|
||||
import libc::funcs::posix01::unistd::setenv;
|
||||
str::as_c_str(n) {|nbuf|
|
||||
str::as_c_str(v) {|vbuf|
|
||||
@ -239,7 +239,7 @@ mod global_env {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn setenv(n: str, v: str) {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import win32::*;
|
||||
as_utf16_p(n) {|nbuf|
|
||||
@ -329,7 +329,7 @@ fn pipe() -> {in: c_int, out: c_int} {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn pipe() -> {in: c_int, out: c_int} {
|
||||
// FIXME: remove this when export globs work properly.
|
||||
// FIXME: remove this when export globs work properly. #1238
|
||||
import libc::consts::os::extra::*;
|
||||
// Windows pipes work subtly differently than unix pipes, and their
|
||||
// inheritance has to be handled in a different way that I do not fully
|
||||
@ -387,7 +387,7 @@ fn self_exe_path() -> option<path> {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn load_self() -> option<path> unsafe {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::*;
|
||||
fill_charp_buf() {|buf, sz|
|
||||
_NSGetExecutablePath(buf, ptr::mut_addr_of(sz as u32))
|
||||
@ -397,7 +397,7 @@ fn self_exe_path() -> option<path> {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn load_self() -> option<path> unsafe {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import win32::*;
|
||||
@ -500,7 +500,7 @@ fn path_exists(p: path) -> bool {
|
||||
}
|
||||
|
||||
// FIXME: under Windows, we should prepend the current drive letter to paths
|
||||
// that start with a slash.
|
||||
// that start with a slash. #2622
|
||||
#[doc = "
|
||||
Convert a relative path to an absolute path
|
||||
|
||||
@ -526,11 +526,11 @@ fn make_dir(p: path, mode: c_int) -> bool {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn mkdir(p: path, _mode: c_int) -> bool unsafe {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import win32::*;
|
||||
// FIXME: turn mode into something useful?
|
||||
// FIXME: turn mode into something useful? #2623
|
||||
as_utf16_p(p) {|buf|
|
||||
CreateDirectoryW(buf, unsafe::reinterpret_cast(0))
|
||||
!= (0 as BOOL)
|
||||
@ -588,7 +588,7 @@ fn remove_dir(p: path) -> bool {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn rmdir(p: path) -> bool {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::types::os::arch::extra::*;
|
||||
import win32::*;
|
||||
@ -610,7 +610,7 @@ fn change_dir(p: path) -> bool {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn chdir(p: path) -> bool {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::types::os::arch::extra::*;
|
||||
import win32::*;
|
||||
@ -633,7 +633,7 @@ fn copy_file(from: path, to: path) -> bool {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn do_copy_file(from: path, to: path) -> bool {
|
||||
// FIXME: remove imports when export globs work properly.
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::types::os::arch::extra::*;
|
||||
import win32::*;
|
||||
|
@ -12,20 +12,20 @@ export split;
|
||||
export splitext;
|
||||
export normalize;
|
||||
|
||||
// FIXME: This type should probably be constrained
|
||||
// FIXME: This type should probably be constrained (#2624)
|
||||
#[doc = "A path or fragment of a filesystem path"]
|
||||
type path = str;
|
||||
|
||||
#[cfg(unix)]
|
||||
mod consts {
|
||||
#[doc = "
|
||||
The primary path seperator character for the platform
|
||||
The primary path separator character for the platform
|
||||
|
||||
On all platforms it is '/'
|
||||
"]
|
||||
const path_sep: char = '/';
|
||||
#[doc = "
|
||||
The secondary path seperator character for the platform
|
||||
The secondary path separator character for the platform
|
||||
|
||||
On Unixes it is '/'. On Windows it is '\\'.
|
||||
"]
|
||||
@ -98,7 +98,6 @@ fn basename(pp: path) -> path {
|
||||
ret split_dirname_basename(pp).basename;
|
||||
}
|
||||
|
||||
// FIXME: Need some typestate to avoid bounds check when len(pre) == 0
|
||||
#[doc = "
|
||||
Connects to path segments
|
||||
|
||||
|
@ -287,7 +287,7 @@ fn program_output(prog: str, args: [str]) ->
|
||||
// Spawn two entire schedulers to read both stdout and sterr
|
||||
// in parallel so we don't deadlock while blocking on one
|
||||
// or the other. FIXME: Surely there's a much more clever way
|
||||
// to do this.
|
||||
// to do this. (#2625)
|
||||
let p = comm::port();
|
||||
let ch = comm::chan(p);
|
||||
task::spawn_sched(task::single_threaded) {||
|
||||
@ -387,7 +387,7 @@ mod tests {
|
||||
import io::writer_util;
|
||||
|
||||
// Regression test for memory leaks
|
||||
#[ignore(cfg(windows))] // FIXME
|
||||
#[ignore(cfg(windows))] // FIXME (#2626)
|
||||
fn test_leaks() {
|
||||
run::run_program("echo", []);
|
||||
run::start_program("echo", []);
|
||||
|
@ -594,7 +594,7 @@ Section: Comparing strings
|
||||
#[doc = "Bytewise string equality"]
|
||||
pure fn eq(&&a: str, &&b: str) -> bool {
|
||||
// FIXME: This should just be "a == b" but that calls into the shape code
|
||||
// :(
|
||||
// :( (#2627)
|
||||
let a_len = a.len();
|
||||
let b_len = b.len();
|
||||
if a_len != b_len { ret false; }
|
||||
|
@ -879,7 +879,7 @@ fn test_avoid_copying_the_body_spawn() {
|
||||
#[test]
|
||||
fn test_avoid_copying_the_body_spawn_listener() {
|
||||
avoid_copying_the_body {|f|
|
||||
spawn_listener(fn~[move f](_po: comm::port<int>) {
|
||||
spawn_listener(fn~(move f, _po: comm::port<int>) {
|
||||
f();
|
||||
});
|
||||
}
|
||||
@ -899,7 +899,7 @@ fn test_avoid_copying_the_body_run() {
|
||||
fn test_avoid_copying_the_body_run_listener() {
|
||||
avoid_copying_the_body {|f|
|
||||
let buildr = builder();
|
||||
run_listener(buildr, fn~[move f](_po: comm::port<int>) {
|
||||
run_listener(buildr, fn~(move f, _po: comm::port<int>) {
|
||||
f();
|
||||
});
|
||||
}
|
||||
|
@ -1249,8 +1249,7 @@ mod unsafe {
|
||||
#[inline(always)]
|
||||
unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn([T]/&) -> U) -> U {
|
||||
let pair = (p, len * sys::size_of::<T>());
|
||||
// FIXME: should use &blk not &static here, but a snapshot is req'd
|
||||
let v : *([T]/&static) =
|
||||
let v : *([T]/&blk) =
|
||||
::unsafe::reinterpret_cast(ptr::addr_of(pair));
|
||||
f(*v)
|
||||
}
|
||||
@ -1335,7 +1334,7 @@ impl extensions/&<A:copy> for [const A]/& {
|
||||
fn map_to_vec<B>(op: fn(A) -> B) -> [B] { iter::map_to_vec(self, op) }
|
||||
fn to_vec() -> [A] { iter::to_vec(self) }
|
||||
|
||||
// FIXME--bug in resolve prevents this from working
|
||||
// FIXME--bug in resolve prevents this from working (#2611)
|
||||
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> [B] {
|
||||
// iter::flat_map_to_vec(self, op)
|
||||
// }
|
||||
|
@ -39,7 +39,7 @@ fn map_slices<A: copy send, B: copy send>(
|
||||
log(info, "spawning tasks");
|
||||
while base < len {
|
||||
let end = uint::min(len, base + items_per_task);
|
||||
// FIXME: why is the ::<A, ()> annotation required here?
|
||||
// FIXME: why is the ::<A, ()> annotation required here? (#2617)
|
||||
vec::unpack_slice::<A, ()>(xs) {|p, _len|
|
||||
let f = f();
|
||||
futures += [future::spawn() {|copy base|
|
||||
|
@ -25,8 +25,6 @@ for *at least* that period of time.
|
||||
"]
|
||||
fn delayed_send<T: copy send>(iotask: iotask,
|
||||
msecs: uint, ch: comm::chan<T>, val: T) {
|
||||
// FIME: Looks like we don't need to spawn here
|
||||
task::spawn() {||
|
||||
unsafe {
|
||||
let timer_done_po = comm::port::<()>();
|
||||
let timer_done_ch = comm::chan(timer_done_po);
|
||||
@ -59,7 +57,6 @@ fn delayed_send<T: copy send>(iotask: iotask,
|
||||
comm::send(ch, copy(val));
|
||||
// uv_close for this timer has been processed
|
||||
comm::recv(timer_done_po);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,7 +103,7 @@ fn recv_timeout<T: copy send>(iotask: iotask,
|
||||
let timeout_po = comm::port::<()>();
|
||||
let timeout_ch = comm::chan(timeout_po);
|
||||
delayed_send(iotask, msecs, timeout_ch, ());
|
||||
// FIXME: This could be written clearer
|
||||
// FIXME: This could be written clearer (#2618)
|
||||
either::either(
|
||||
{|left_val|
|
||||
log(debug, #fmt("recv_time .. left_val %?",
|
||||
|
@ -9,6 +9,7 @@ import diagnostic::span_handler;
|
||||
enum path_elt { path_mod(ident), path_name(ident) }
|
||||
type path = [path_elt];
|
||||
|
||||
/* FIXMEs that say "bad" are as per #2543 */
|
||||
fn path_to_str_with_sep(p: path, sep: str) -> str {
|
||||
let strs = vec::map(p) {|e|
|
||||
alt e {
|
||||
@ -291,6 +292,7 @@ fn node_id_to_str(map: map, id: node_id) -> str {
|
||||
#fmt["expr %s (id=%?)",
|
||||
pprust::expr_to_str(expr), id]
|
||||
}
|
||||
// FIXMEs are as per #2410
|
||||
some(node_export(_, path)) {
|
||||
#fmt["export %s (id=%?)", // FIXME: add more info here
|
||||
path_to_str(*path), id]
|
||||
|
@ -24,7 +24,7 @@ pure fn dummy_sp() -> span { ret mk_sp(0u, 0u); }
|
||||
pure fn path_name(p: @path) -> str { path_name_i(p.idents) }
|
||||
|
||||
pure fn path_name_i(idents: [ident]) -> str {
|
||||
// FIXME: Bad copies
|
||||
// FIXME: Bad copies (#2543 -- same for everything else that says "bad")
|
||||
str::connect(idents.map({|i|*i}), "::")
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ fn get_attr_name(attr: ast::attribute) -> ast::ident {
|
||||
get_meta_item_name(@attr.node.value)
|
||||
}
|
||||
|
||||
// All "bad" FIXME copies are as per #2543
|
||||
fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident {
|
||||
alt meta.node {
|
||||
ast::meta_word(n) { /* FIXME bad */ copy n }
|
||||
@ -372,7 +373,7 @@ fn require_unique_names(diagnostic: span_handler,
|
||||
for metas.each {|meta|
|
||||
let name = get_meta_item_name(meta);
|
||||
|
||||
// FIXME: How do I silence the warnings? --pcw
|
||||
// FIXME: How do I silence the warnings? --pcw (#2619)
|
||||
if map.contains_key(*name) {
|
||||
diagnostic.span_fatal(meta.span,
|
||||
#fmt["duplicate meta item `%s`", *name]);
|
||||
|
@ -59,7 +59,7 @@ fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
||||
let p = parse::new_parser_from_file(cx.parse_sess(), cx.cfg(),
|
||||
res_rel_file(cx, sp, file),
|
||||
parse::parser::SOURCE_FILE);
|
||||
ret parse::parser::parse_expr(p)
|
||||
ret p.parse_expr();
|
||||
}
|
||||
|
||||
fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
||||
|
@ -16,8 +16,6 @@ import dvec::{dvec, extensions};
|
||||
|
||||
export file_type;
|
||||
export parser;
|
||||
export parse_expr;
|
||||
export parse_pat;
|
||||
|
||||
// FIXME: #ast expects to find this here but it's actually defined in `parse`
|
||||
// Fixing this will be easier when we have export decls on individual items --
|
||||
@ -26,12 +24,6 @@ export parse_pat;
|
||||
import parse_from_source_str;
|
||||
export parse_from_source_str;
|
||||
|
||||
// TODO: remove these once we go around a snapshot cycle.
|
||||
// These are here for the old way that #ast (qquote.rs) worked
|
||||
fn parse_expr(p: parser) -> @ast::expr { p.parse_expr() }
|
||||
fn parse_pat(p: parser) -> @ast::pat { p.parse_pat() }
|
||||
|
||||
|
||||
enum restriction {
|
||||
UNRESTRICTED,
|
||||
RESTRICT_STMT_EXPR,
|
||||
@ -1231,8 +1223,6 @@ class parser {
|
||||
fn parse_fn_expr(proto: proto) -> @expr {
|
||||
let lo = self.last_span.lo;
|
||||
|
||||
let cc_old = self.parse_old_skool_capture_clause();
|
||||
|
||||
// if we want to allow fn expression argument types to be inferred in
|
||||
// the future, just have to change parse_arg to parse_fn_block_arg.
|
||||
let (decl, capture_clause) =
|
||||
@ -1241,8 +1231,7 @@ class parser {
|
||||
|
||||
let body = self.parse_block();
|
||||
ret self.mk_expr(lo, body.span.hi,
|
||||
expr_fn(proto, decl, body,
|
||||
@(*capture_clause + cc_old)));
|
||||
expr_fn(proto, decl, body, capture_clause));
|
||||
}
|
||||
|
||||
fn parse_fn_block_expr() -> @expr {
|
||||
@ -1731,55 +1720,6 @@ class parser {
|
||||
} else { [] }
|
||||
}
|
||||
|
||||
// FIXME Remove after snapshot
|
||||
fn parse_old_skool_capture_clause() -> [capture_item] {
|
||||
fn expect_opt_trailing_semi(p: parser) {
|
||||
if !p.eat(token::SEMI) {
|
||||
if p.token != token::RBRACKET {
|
||||
p.fatal("expecting ; or ]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eat_ident_list(p: parser, is_move: bool) -> [capture_item] {
|
||||
let mut res = [];
|
||||
loop {
|
||||
alt p.token {
|
||||
token::IDENT(_, _) {
|
||||
let id = p.get_id();
|
||||
let sp = mk_sp(p.span.lo, p.span.hi);
|
||||
let ident = p.parse_ident();
|
||||
res += [@{id:id, is_move: is_move, name:ident, span:sp}];
|
||||
if !p.eat(token::COMMA) {
|
||||
ret res;
|
||||
}
|
||||
}
|
||||
|
||||
_ { ret res; }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let mut cap_items = [];
|
||||
|
||||
if self.eat(token::LBRACKET) {
|
||||
while !self.eat(token::RBRACKET) {
|
||||
if self.eat_keyword("copy") {
|
||||
cap_items += eat_ident_list(self, false);
|
||||
expect_opt_trailing_semi(self);
|
||||
} else if self.eat_keyword("move") {
|
||||
cap_items += eat_ident_list(self, true);
|
||||
expect_opt_trailing_semi(self);
|
||||
} else {
|
||||
let s: str = "expecting send, copy, or move clause";
|
||||
self.fatal(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret cap_items;
|
||||
}
|
||||
|
||||
fn parse_fn_decl(purity: purity,
|
||||
parse_arg_fn: fn(parser) -> arg_or_capture_item)
|
||||
-> (fn_decl, capture_clause) {
|
||||
|
@ -706,12 +706,6 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
|
||||
let bcx = drop_ty(bcx, body, body_mt.ty);
|
||||
trans_free(bcx, v)
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_box) {
|
||||
let v = PointerCast(bcx, v, type_of(ccx, t));
|
||||
trans_free(bcx, v)
|
||||
}
|
||||
|
||||
ty::ty_opaque_box {
|
||||
let v = PointerCast(bcx, v, type_of(ccx, t));
|
||||
let td = Load(bcx, GEPi(bcx, v, [0u, abi::box_field_tydesc]));
|
||||
@ -725,8 +719,11 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
|
||||
uniq::make_free_glue(bcx, v, t)
|
||||
}
|
||||
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) |
|
||||
ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) |
|
||||
ty::ty_vec(_) | ty::ty_str {
|
||||
tvec::make_free_glue(bcx, PointerCast(bcx, v, type_of(ccx, t)), t)
|
||||
make_free_glue(bcx, v,
|
||||
tvec::expand_boxed_vec_ty(bcx.tcx(), t));
|
||||
ret;
|
||||
}
|
||||
ty::ty_evec(_, _) {
|
||||
bcx.sess().unimpl("trans::base::make_free_glue on other evec");
|
||||
@ -794,6 +791,9 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
|
||||
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) {
|
||||
free_ty(bcx, Load(bcx, v0), t)
|
||||
}
|
||||
ty::ty_unboxed_vec(_) {
|
||||
tvec::make_drop_glue_unboxed(bcx, v0, t)
|
||||
}
|
||||
ty::ty_res(did, inner, substs) {
|
||||
trans_res_drop(bcx, v0, did, inner, substs.tps)
|
||||
}
|
||||
@ -1634,11 +1634,38 @@ fn cast_shift_rhs(op: ast::binop,
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_if_zero(cx: block, span: span, divmod: ast::binop,
|
||||
rhs: ValueRef, rhs_t: ty::t) -> block {
|
||||
let text = if divmod == ast::div {
|
||||
"divide by zero"
|
||||
} else {
|
||||
"modulo zero"
|
||||
};
|
||||
let is_zero = alt ty::get(rhs_t).struct {
|
||||
ty::ty_int(t) {
|
||||
let zero = C_integral(T_int_ty(cx.ccx(), t), 0u64, False);
|
||||
ICmp(cx, lib::llvm::IntEQ, rhs, zero)
|
||||
}
|
||||
ty::ty_uint(t) {
|
||||
let zero = C_integral(T_uint_ty(cx.ccx(), t), 0u64, False);
|
||||
ICmp(cx, lib::llvm::IntEQ, rhs, zero)
|
||||
}
|
||||
_ {
|
||||
cx.tcx().sess.bug("fail-if-zero on unexpected type: " +
|
||||
ty_to_str(cx.ccx().tcx, rhs_t));
|
||||
}
|
||||
};
|
||||
with_cond(cx, is_zero) {|bcx|
|
||||
trans_fail(bcx, some(span), text)
|
||||
}
|
||||
}
|
||||
|
||||
// Important to get types for both lhs and rhs, because one might be _|_
|
||||
// and the other not.
|
||||
fn trans_eager_binop(cx: block, op: ast::binop, lhs: ValueRef,
|
||||
fn trans_eager_binop(cx: block, span: span, op: ast::binop, lhs: ValueRef,
|
||||
lhs_t: ty::t, rhs: ValueRef, rhs_t: ty::t, dest: dest)
|
||||
-> block {
|
||||
let mut cx = cx;
|
||||
let _icx = cx.insn_ctxt("trans_eager_binop");
|
||||
if dest == ignore { ret cx; }
|
||||
let intype = {
|
||||
@ -1667,16 +1694,30 @@ fn trans_eager_binop(cx: block, op: ast::binop, lhs: ValueRef,
|
||||
else { Mul(cx, lhs, rhs) }
|
||||
}
|
||||
ast::div {
|
||||
if is_float { FDiv(cx, lhs, rhs) }
|
||||
else if ty::type_is_signed(intype) {
|
||||
SDiv(cx, lhs, rhs)
|
||||
} else { UDiv(cx, lhs, rhs) }
|
||||
if is_float {
|
||||
FDiv(cx, lhs, rhs)
|
||||
} else {
|
||||
// Only zero-check integers; fp /0 is NaN
|
||||
cx = fail_if_zero(cx, span, op, rhs, rhs_t);
|
||||
if ty::type_is_signed(intype) {
|
||||
SDiv(cx, lhs, rhs)
|
||||
} else {
|
||||
UDiv(cx, lhs, rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::rem {
|
||||
if is_float { FRem(cx, lhs, rhs) }
|
||||
else if ty::type_is_signed(intype) {
|
||||
SRem(cx, lhs, rhs)
|
||||
} else { URem(cx, lhs, rhs) }
|
||||
if is_float {
|
||||
FRem(cx, lhs, rhs)
|
||||
} else {
|
||||
// Only zero-check integers; fp %0 is NaN
|
||||
cx = fail_if_zero(cx, span, op, rhs, rhs_t);
|
||||
if ty::type_is_signed(intype) {
|
||||
SRem(cx, lhs, rhs)
|
||||
} else {
|
||||
URem(cx, lhs, rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::bitor { Or(cx, lhs, rhs) }
|
||||
ast::bitand { And(cx, lhs, rhs) }
|
||||
@ -1744,7 +1785,8 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
ret trans_eager_binop(bcx, op, Load(bcx, lhs_res.val), t, rhs_val, t,
|
||||
ret trans_eager_binop(bcx, ex.span,
|
||||
op, Load(bcx, lhs_res.val), t, rhs_val, t,
|
||||
save_in(lhs_res.val));
|
||||
}
|
||||
|
||||
@ -1885,7 +1927,8 @@ fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr,
|
||||
// Remaining cases are eager:
|
||||
let lhs_res = trans_temp_expr(bcx, lhs);
|
||||
let rhs_res = trans_temp_expr(lhs_res.bcx, rhs);
|
||||
ret trans_eager_binop(rhs_res.bcx, op, lhs_res.val,
|
||||
ret trans_eager_binop(rhs_res.bcx, ex.span,
|
||||
op, lhs_res.val,
|
||||
expr_ty(bcx, lhs), rhs_res.val,
|
||||
expr_ty(bcx, rhs), dest);
|
||||
}
|
||||
|
@ -156,6 +156,7 @@ impl methods for reflector {
|
||||
}
|
||||
|
||||
// FIXME: fetch constants out of intrinsic:: for the numbers.
|
||||
// (#2594)
|
||||
ty::ty_fn(fty) {
|
||||
let pureval = alt fty.purity {
|
||||
ast::pure_fn { 0u }
|
||||
@ -217,7 +218,7 @@ impl methods for reflector {
|
||||
// FIXME: visiting all the variants in turn is probably
|
||||
// not ideal. It'll work but will get costly on big enums.
|
||||
// Maybe let the visitor tell us if it wants to visit only
|
||||
// a particular variant?
|
||||
// a particular variant? (#2595)
|
||||
ty::ty_enum(did, substs) {
|
||||
let bcx = self.bcx;
|
||||
let tcx = bcx.ccx().tcx;
|
||||
|
@ -277,8 +277,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
}
|
||||
ty::ty_evec(mt, ty::vstore_uniq) |
|
||||
ty::ty_vec(mt) {
|
||||
shape_of(ccx,
|
||||
ty::mk_imm_uniq(ccx.tcx, ty::mk_unboxed_vec(ccx.tcx, mt)))
|
||||
shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t))
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_fixed(n)) {
|
||||
|
@ -5,13 +5,35 @@ import back::abi;
|
||||
import base::{call_memmove,
|
||||
INIT, copy_val, load_if_immediate, get_tydesc,
|
||||
sub_block, do_spill_noroot,
|
||||
dest, bcx_icx, non_gc_box_cast};
|
||||
dest, bcx_icx, non_gc_box_cast,
|
||||
heap, heap_exchange, heap_shared};
|
||||
import syntax::codemap::span;
|
||||
import shape::llsize_of;
|
||||
import build::*;
|
||||
import common::*;
|
||||
import util::ppaux::ty_to_str;
|
||||
|
||||
// Boxed vector types are in some sense currently a "shorthand" for a box
|
||||
// containing an unboxed vector. This expands a boxed vector type into such an
|
||||
// expanded type. It doesn't respect mutability, but that doesn't matter at
|
||||
// this point.
|
||||
fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
|
||||
let unit_ty = ty::sequence_element_type(tcx, t);
|
||||
let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty);
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_vec(_) | ty::ty_str |
|
||||
ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) {
|
||||
ty::mk_imm_uniq(tcx, unboxed_vec_ty)
|
||||
}
|
||||
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) {
|
||||
ty::mk_imm_box(tcx, unboxed_vec_ty)
|
||||
}
|
||||
_ { tcx.sess.bug("non boxed-vec type \
|
||||
in tvec::expand_boxed_vec_ty");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt("tvec::get_fill");
|
||||
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]))
|
||||
@ -40,21 +62,25 @@ fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
||||
ret PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
|
||||
}
|
||||
|
||||
fn alloc_uniq_raw(bcx: block, unit_ty: ty::t,
|
||||
fill: ValueRef, alloc: ValueRef) -> result {
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq_raw");
|
||||
fn alloc_raw(bcx: block, unit_ty: ty::t,
|
||||
fill: ValueRef, alloc: ValueRef, heap: heap) -> result {
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);
|
||||
let vecsize = Add(bcx, alloc, llsize_of(ccx, ccx.opaque_vec_type));
|
||||
|
||||
let {box, body} = base::malloc_unique_dyn(bcx, vecbodyty, vecsize);
|
||||
let {box, body} = base::malloc_general_dyn(bcx, vecbodyty, heap, vecsize);
|
||||
Store(bcx, fill, GEPi(bcx, body, [0u, abi::vec_elt_fill]));
|
||||
Store(bcx, alloc, GEPi(bcx, body, [0u, abi::vec_elt_alloc]));
|
||||
ret {bcx: bcx, val: box};
|
||||
}
|
||||
fn alloc_uniq_raw(bcx: block, unit_ty: ty::t,
|
||||
fill: ValueRef, alloc: ValueRef) -> result {
|
||||
alloc_raw(bcx, unit_ty, fill, alloc, heap_exchange)
|
||||
}
|
||||
|
||||
fn alloc_uniq(bcx: block, unit_ty: ty::t, elts: uint) -> result {
|
||||
fn alloc_vec(bcx: block, unit_ty: ty::t, elts: uint, heap: heap) -> result {
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
|
||||
let ccx = bcx.ccx();
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
@ -63,7 +89,7 @@ fn alloc_uniq(bcx: block, unit_ty: ty::t, elts: uint) -> result {
|
||||
let fill = Mul(bcx, C_uint(ccx, elts), unit_sz);
|
||||
let alloc = if elts < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
|
||||
else { fill };
|
||||
let {bcx: bcx, val: vptr} = alloc_uniq_raw(bcx, unit_ty, fill, alloc);
|
||||
let {bcx: bcx, val: vptr} = alloc_raw(bcx, unit_ty, fill, alloc, heap);
|
||||
ret {bcx: bcx, val: vptr};
|
||||
}
|
||||
|
||||
@ -79,20 +105,18 @@ fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> result {
|
||||
call_memmove(bcx, new_data_ptr, data_ptr, fill);
|
||||
|
||||
let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) {
|
||||
iter_vec(bcx, newptr, vec_ty, base::take_ty)
|
||||
iter_vec_raw(bcx, new_data_ptr, vec_ty, fill, base::take_ty)
|
||||
} else { bcx };
|
||||
ret rslt(bcx, newptr);
|
||||
}
|
||||
fn make_free_glue(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
|
||||
|
||||
fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
|
||||
block {
|
||||
let _icx = bcx.insn_ctxt("tvec::make_free_glue");
|
||||
let _icx = bcx.insn_ctxt("tvec::make_drop_glue_unboxed");
|
||||
let tcx = bcx.tcx(), unit_ty = ty::sequence_element_type(tcx, vec_ty);
|
||||
base::with_cond(bcx, IsNotNull(bcx, vptr)) {|bcx|
|
||||
let bcx = if ty::type_needs_drop(tcx, unit_ty) {
|
||||
iter_vec(bcx, vptr, vec_ty, base::drop_ty)
|
||||
} else { bcx };
|
||||
base::trans_unique_free(bcx, vptr)
|
||||
}
|
||||
if ty::type_needs_drop(tcx, unit_ty) {
|
||||
iter_vec_unboxed(bcx, vptr, vec_ty, base::drop_ty)
|
||||
} else { bcx }
|
||||
}
|
||||
|
||||
fn trans_evec(bcx: block, args: [@ast::expr],
|
||||
@ -141,13 +165,18 @@ fn trans_evec(bcx: block, args: [@ast::expr],
|
||||
{bcx: bcx, val: p, dataptr: vp}
|
||||
}
|
||||
ast::vstore_uniq {
|
||||
let {bcx, val} = alloc_uniq(bcx, unit_ty, args.len());
|
||||
let {bcx, val} = alloc_vec(bcx, unit_ty, args.len(),
|
||||
heap_exchange);
|
||||
add_clean_free(bcx, val, true);
|
||||
let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val));
|
||||
{bcx: bcx, val: val, dataptr: dataptr}
|
||||
}
|
||||
ast::vstore_box {
|
||||
bcx.ccx().sess.unimpl("unhandled tvec::trans_evec");
|
||||
let {bcx, val} = alloc_vec(bcx, unit_ty, args.len(),
|
||||
heap_shared);
|
||||
add_clean_free(bcx, val, true);
|
||||
let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val));
|
||||
{bcx: bcx, val: val, dataptr: dataptr}
|
||||
}
|
||||
};
|
||||
|
||||
@ -223,13 +252,11 @@ fn get_base_and_len(cx: block, v: ValueRef, e_ty: ty::t)
|
||||
let len = Load(cx, GEPi(cx, v, [0u, abi::slice_elt_len]));
|
||||
(base, len)
|
||||
}
|
||||
ty::vstore_uniq {
|
||||
ty::vstore_uniq | ty::vstore_box {
|
||||
#debug["get_base_and_len: %s", val_str(ccx.tn, v)];
|
||||
let body = tvec::get_bodyptr(cx, v);
|
||||
(tvec::get_dataptr(cx, body), tvec::get_fill(cx, body))
|
||||
}
|
||||
ty::vstore_box {
|
||||
cx.ccx().sess.unimpl("unhandled tvec::get_base_and_len");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,7 +415,7 @@ type iter_vec_block = fn(block, ValueRef, ty::t) -> block;
|
||||
|
||||
fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
|
||||
fill: ValueRef, f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec_uniq");
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec_raw");
|
||||
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
|
||||
@ -422,11 +449,12 @@ fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||
iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
|
||||
}
|
||||
|
||||
fn iter_vec(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||
f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec");
|
||||
let fill = get_fill(bcx, get_bodyptr(bcx, vptr));
|
||||
ret iter_vec_uniq(bcx, vptr, vec_ty, fill, f);
|
||||
fn iter_vec_unboxed(bcx: block, body_ptr: ValueRef, vec_ty: ty::t,
|
||||
f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec_unboxed");
|
||||
let fill = get_fill(bcx, body_ptr);
|
||||
let dataptr = get_dataptr(bcx, body_ptr);
|
||||
ret iter_vec_raw(bcx, dataptr, vec_ty, fill, f);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -76,10 +76,13 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
// this then, e.g. `option<{myfield: bool}>` would be a different
|
||||
// type than `option<myrec>`.
|
||||
let t_norm = ty::normalize_ty(cx.tcx, t);
|
||||
let llty = if t != t_norm {
|
||||
type_of(cx, t_norm)
|
||||
|
||||
let mut llty;
|
||||
if t != t_norm {
|
||||
llty = type_of(cx, t_norm);
|
||||
cx.lltypes.insert(t, llty);
|
||||
} else {
|
||||
alt ty::get(t).struct {
|
||||
llty = alt ty::get(t).struct {
|
||||
ty::ty_nil | ty::ty_bot { T_nil() }
|
||||
ty::ty_bool { T_bool() }
|
||||
ty::ty_int(t) { T_int_ty(cx, t) }
|
||||
@ -91,7 +94,9 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
}
|
||||
ty::ty_enum(did, _) { type_of_enum(cx, did, t) }
|
||||
ty::ty_estr(ty::vstore_box) { T_box_ptr(T_box(cx, T_i8())) }
|
||||
ty::ty_evec(mt, ty::vstore_box) |
|
||||
ty::ty_evec(mt, ty::vstore_box) {
|
||||
T_box_ptr(T_box(cx, T_vec(cx, type_of(cx, mt.ty))))
|
||||
}
|
||||
ty::ty_box(mt) { T_box_ptr(T_box(cx, type_of(cx, mt.ty))) }
|
||||
ty::ty_opaque_box { T_box_ptr(T_box(cx, T_i8())) }
|
||||
ty::ty_uniq(mt) { T_unique_ptr(T_unique(cx, type_of(cx, mt.ty))) }
|
||||
@ -147,20 +152,12 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
}
|
||||
ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) }
|
||||
ty::ty_constr(subt,_) { type_of(cx, subt) }
|
||||
ty::ty_class(did, ts) {
|
||||
// only instance vars are record fields at runtime
|
||||
let fields = lookup_class_fields(cx.tcx, did);
|
||||
let tys = vec::map(fields) {|f|
|
||||
let t = ty::lookup_field_type(cx.tcx, did, f.id, ts);
|
||||
type_of(cx, t)
|
||||
};
|
||||
if ty::ty_dtor(cx.tcx, did) == none {
|
||||
T_struct(tys)
|
||||
}
|
||||
else {
|
||||
// resource type
|
||||
T_struct([T_i8(), T_struct(tys)])
|
||||
}
|
||||
ty::ty_class(*) {
|
||||
// Only create the named struct, but don't fill it in. We fill it
|
||||
// in *after* placing it into the type cache. This prevents
|
||||
// infinite recursion with recursive class types.
|
||||
|
||||
common::T_named_struct(llvm_type_name(cx, t))
|
||||
}
|
||||
ty::ty_self { cx.tcx.sess.unimpl("type_of: ty_self"); }
|
||||
ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); }
|
||||
@ -168,9 +165,33 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
ty::ty_var_integral(_) {
|
||||
cx.tcx.sess.bug("type_of shouldn't see a ty_var_integral");
|
||||
}
|
||||
};
|
||||
|
||||
cx.lltypes.insert(t, llty);
|
||||
|
||||
// If this was a class, fill in the type now.
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_class(did, ts) {
|
||||
// Only instance vars are record fields at runtime.
|
||||
let fields = lookup_class_fields(cx.tcx, did);
|
||||
let mut tys = vec::map(fields) {|f|
|
||||
let t = ty::lookup_field_type(cx.tcx, did, f.id, ts);
|
||||
type_of(cx, t)
|
||||
};
|
||||
|
||||
if ty::ty_dtor(cx.tcx, did) != none {
|
||||
// resource type
|
||||
tys = [T_i8(), T_struct(tys)];
|
||||
}
|
||||
|
||||
common::set_struct_body(llty, tys);
|
||||
}
|
||||
_ {
|
||||
// Nothing more to do.
|
||||
}
|
||||
}
|
||||
};
|
||||
cx.lltypes.insert(t, llty);
|
||||
|
||||
ret llty;
|
||||
}
|
||||
|
||||
@ -212,6 +233,9 @@ fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str {
|
||||
ty::ty_enum(did, substs) {
|
||||
("enum", did, substs.tps)
|
||||
}
|
||||
ty::ty_class(did, substs) {
|
||||
("class", did, substs.tps)
|
||||
}
|
||||
};
|
||||
ret #fmt(
|
||||
"%s %s[#%d]",
|
||||
|
@ -1112,7 +1112,7 @@ fn type_is_str(ty: t) -> bool {
|
||||
fn sequence_element_type(cx: ctxt, ty: t) -> t {
|
||||
alt get(ty).struct {
|
||||
ty_str | ty_estr(_) { ret mk_mach_uint(cx, ast::ty_u8); }
|
||||
ty_vec(mt) | ty_evec(mt, _) { ret mt.ty; }
|
||||
ty_vec(mt) | ty_evec(mt, _) | ty_unboxed_vec(mt) { ret mt.ty; }
|
||||
_ { cx.sess.bug("sequence_element_type called on non-sequence value"); }
|
||||
}
|
||||
}
|
||||
@ -1134,7 +1134,8 @@ pure fn type_is_box(ty: t) -> bool {
|
||||
|
||||
pure fn type_is_boxed(ty: t) -> bool {
|
||||
alt get(ty).struct {
|
||||
ty_box(_) | ty_opaque_box { true }
|
||||
ty_box(_) | ty_opaque_box |
|
||||
ty_evec(_, vstore_box) | ty_estr(vstore_box) { true }
|
||||
_ { false }
|
||||
}
|
||||
}
|
||||
@ -1212,6 +1213,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
|
||||
ty_estr(vstore_fixed(_)) | ty_estr(vstore_slice(_)) |
|
||||
ty_evec(_, vstore_slice(_)) { false }
|
||||
ty_evec(mt, vstore_fixed(_)) { type_needs_drop(cx, mt.ty) }
|
||||
ty_unboxed_vec(mt) { type_needs_drop(cx, mt.ty) }
|
||||
ty_rec(flds) {
|
||||
for flds.each {|f| if type_needs_drop(cx, f.mt.ty) { accum = true; } }
|
||||
accum
|
||||
@ -2693,9 +2695,11 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
|
||||
let result = if ast::local_crate != id.crate {
|
||||
@csearch::get_enum_variants(cx, id)
|
||||
} else {
|
||||
// FIXME: Now that the variants are run through the type checker (to
|
||||
// check the disr_expr if it exists), this code should likely be
|
||||
// moved there to avoid having to call eval_const_expr twice.
|
||||
/*
|
||||
Although both this code and check_enum_variants in typeck/check
|
||||
call eval_const_expr, it should never get called twice for the same
|
||||
expr, since check_enum_variants also updates the enum_var_cache
|
||||
*/
|
||||
alt cx.items.get(id.node) {
|
||||
ast_map::node_item(@{node: ast::item_enum(variants, _, _), _}, _) {
|
||||
let mut disr_val = -1;
|
||||
@ -3032,9 +3036,16 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
|
||||
alt r.self_r {
|
||||
some(_) {
|
||||
// This enum has a self region. Get rid of it
|
||||
mk_enum(cx, did, {self_r: none,
|
||||
self_ty: none,
|
||||
tps: r.tps})
|
||||
mk_enum(cx, did, {self_r: none, self_ty: none, tps: r.tps})
|
||||
}
|
||||
none { t }
|
||||
}
|
||||
}
|
||||
ty_class(did, r) {
|
||||
alt r.self_r {
|
||||
some(_) {
|
||||
// Ditto.
|
||||
mk_class(cx, did, {self_r: none, self_ty: none, tps: r.tps})
|
||||
}
|
||||
none { t }
|
||||
}
|
||||
|
@ -1201,14 +1201,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
none {
|
||||
alt sty {
|
||||
ty::ty_enum(*) {
|
||||
tcx.sess.span_fatal(
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
"can only dereference enums \
|
||||
with a single variant which has a \
|
||||
single argument");
|
||||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
#fmt["type %s cannot be dereferenced",
|
||||
fcx.infcx.ty_to_str(oper_t)]);
|
||||
@ -1893,6 +1893,7 @@ fn check_enum_variants(ccx: @crate_ctxt,
|
||||
let fcx = blank_fn_ctxt(ccx, rty);
|
||||
let mut disr_vals: [int] = [];
|
||||
let mut disr_val = 0;
|
||||
let mut variants = [];
|
||||
for vs.each {|v|
|
||||
alt v.node.disr_expr {
|
||||
some(e) {
|
||||
@ -1921,9 +1922,19 @@ fn check_enum_variants(ccx: @crate_ctxt,
|
||||
"discriminator value already exists.");
|
||||
}
|
||||
disr_vals += [disr_val];
|
||||
let ctor_ty = ty::node_id_to_type(ccx.tcx, v.node.id);
|
||||
let arg_tys = if v.node.args.len() > 0u {
|
||||
ty::ty_fn_args(ctor_ty).map {|a| a.ty }
|
||||
} else { [] };
|
||||
variants += [@{args: arg_tys, ctor_ty: ctor_ty,
|
||||
name: v.node.name, id: local_def(v.node.id),
|
||||
disr_val: disr_val}];
|
||||
disr_val += 1;
|
||||
}
|
||||
|
||||
// cache so that ty::enum_variants won't repeat this work
|
||||
ccx.tcx.enum_var_cache.insert(local_def(id), @variants);
|
||||
|
||||
// Check that it is possible to represent this enum:
|
||||
let mut outer = true, did = local_def(id);
|
||||
if ty::type_structurally_contains(ccx.tcx, rty, {|sty|
|
||||
|
@ -97,7 +97,7 @@ fn exec<T:send>(
|
||||
) -> T {
|
||||
let po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
let msg = handle_request(fn~[move f](ctxt: ctxt) {
|
||||
let msg = handle_request(fn~(move f, ctxt: ctxt) {
|
||||
comm::send(ch, f(ctxt))
|
||||
});
|
||||
comm::send(srv.ch, msg);
|
||||
|
@ -22,7 +22,7 @@ type section = {
|
||||
|
||||
// FIXME: We currently give topmod the name of the crate. There would
|
||||
// probably be fewer special cases if the crate had its own name and
|
||||
// topmod's name was the empty string.
|
||||
// topmod's name was the empty string. (#2596)
|
||||
type cratedoc = {
|
||||
topmod: moddoc,
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ fn build_reexport_def_map(
|
||||
def_map: ast_util::new_def_hash()
|
||||
};
|
||||
|
||||
// FIXME: Do a parallel fold
|
||||
// FIXME: Do a parallel fold (#2597)
|
||||
let fold = fold::fold({
|
||||
fold_mod: fold_mod,
|
||||
fold_nmod: fold_nmod
|
||||
|
@ -122,7 +122,7 @@ fn make_sequence_processor(sz: uint, from_parent: comm::port<[u8]>, to_parent: c
|
||||
fn main(args: [str]) {
|
||||
let rdr = if os::getenv("RUST_BENCH").is_some() {
|
||||
// FIXME: Using this compile-time env variable is a crummy way to
|
||||
// get to this massive data set, but #include_bin chokes on it
|
||||
// get to this massive data set, but #include_bin chokes on it (#2598)
|
||||
let path = path::connect(
|
||||
#env("CFG_SRC_DIR"),
|
||||
"src/test/bench/shootout-k-nucleotide.data"
|
||||
|
@ -59,14 +59,12 @@ fn solve_grid(g: grid_t) {
|
||||
drop_colors(g, avail, row, col);
|
||||
|
||||
// find first remaining color that is available
|
||||
let mut i = 1 as uint;
|
||||
while i < (10 as uint) { /* FIXME llvm ctlhd */
|
||||
for uint::range(1u, 10u) {|i|
|
||||
if bitv::get(avail, i) {
|
||||
g[row][col] = i as u8;
|
||||
ret true;
|
||||
}
|
||||
i += 1 as uint; /* else */
|
||||
}
|
||||
};
|
||||
}
|
||||
g[row][col] = 0u8;
|
||||
ret false;
|
||||
@ -131,6 +129,7 @@ fn write_grid(f: io::writer, g: grid_t) {
|
||||
fn main(args: [str]) {
|
||||
let grid = if vec::len(args) == 1u {
|
||||
// FIXME create sudoku inline since nested vec consts dont work yet
|
||||
// (#571)
|
||||
let g = vec::from_fn(10u, {|_i|
|
||||
vec::to_mut(vec::from_elem(10u, 0 as u8))
|
||||
});
|
||||
|
@ -77,8 +77,7 @@ mod map_reduce {
|
||||
|
||||
type putter<K: send, V: send> = fn(K, V);
|
||||
|
||||
// FIXME: the first K1 parameter should probably be a -, but that
|
||||
// doesn't parse at the moment.
|
||||
// FIXME: the first K1 parameter should probably be a - (#2599)
|
||||
type mapper<K1: send, K2: send, V: send> = fn~(K1, putter<K2, V>);
|
||||
|
||||
type getter<V: send> = fn() -> option<V>;
|
||||
|
5
src/test/run-fail/divide-by-zero.rs
Normal file
5
src/test/run-fail/divide-by-zero.rs
Normal file
@ -0,0 +1,5 @@
|
||||
// error-pattern:divide by zero
|
||||
fn main() {
|
||||
let y = 0;
|
||||
let z = 1 / y;
|
||||
}
|
5
src/test/run-fail/mod-zero.rs
Normal file
5
src/test/run-fail/mod-zero.rs
Normal file
@ -0,0 +1,5 @@
|
||||
// error-pattern:modulo zero
|
||||
fn main() {
|
||||
let y = 0;
|
||||
let z = 1 % y;
|
||||
}
|
@ -1,8 +1,4 @@
|
||||
// FIXME: Autobind doesn't work for bare functions currently
|
||||
// because it would have to convert them to shared closures
|
||||
// xfail-test
|
||||
|
||||
fn f<T>(x: [T]) -> T { ret x[0]; }
|
||||
fn f<T: copy>(x: [T]) -> T { ret x[0]; }
|
||||
|
||||
fn g(act: fn([int]) -> int) -> int { ret act([1, 2, 3]); }
|
||||
|
||||
|
@ -39,7 +39,7 @@ fn main() {
|
||||
log(debug, x);
|
||||
n = recv(p);
|
||||
n = recv(p);
|
||||
// FIXME: use signal-channel for this.
|
||||
// FIXME: use signal-channel for this. (#2600)
|
||||
#debug("children finished, root finishing");
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ fn test_box() {
|
||||
}
|
||||
|
||||
fn test_port() {
|
||||
// FIXME: Re-enable this once we can compare resources.
|
||||
// FIXME: Re-enable this once we can compare resources. (#2601)
|
||||
/*
|
||||
let p1 = comm::port::<int>();
|
||||
let p2 = comm::port::<int>();
|
||||
|
@ -1,5 +1,3 @@
|
||||
// xfail-fast
|
||||
// (Not sure why, though -- FIXME (tjc)
|
||||
import to_str::*;
|
||||
import to_str::to_str;
|
||||
|
||||
|
10
src/test/run-pass/classes-self-referential.rs
Normal file
10
src/test/run-pass/classes-self-referential.rs
Normal file
@ -0,0 +1,10 @@
|
||||
class kitten {
|
||||
let cat: option<cat>;
|
||||
new(cat: option<cat>) {
|
||||
self.cat = cat;
|
||||
}
|
||||
}
|
||||
|
||||
type cat = @kitten;
|
||||
|
||||
fn main() {}
|
@ -1,6 +1,6 @@
|
||||
fn main() {
|
||||
let x = 1;
|
||||
let y = fn@[move x]() -> int {
|
||||
let y = fn@(move x) -> int {
|
||||
x
|
||||
}();
|
||||
}
|
||||
|
11
src/test/run-pass/issue-2611.rs
Normal file
11
src/test/run-pass/issue-2611.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// xfail-test
|
||||
import iter;
|
||||
import iter::base_iter;
|
||||
|
||||
impl Q<A> for base_iter<A> {
|
||||
fn flat_map_to_vec<B:copy, IB:base_iter<B>>(op: fn(B) -> IB) -> [B] {
|
||||
iter::flat_map_to_vec(self, op)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -2,6 +2,7 @@
|
||||
// FIXME: This test is no longer testing what it was intended to. It should
|
||||
// be testing spawning of a native function, but is actually testing
|
||||
// spawning some other function, then executing a native function.
|
||||
// #2602
|
||||
|
||||
/*
|
||||
A reduced test case for Issue #506, provided by Rob Arnold.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// xfail-test FIXME I don't know how to test this
|
||||
// xfail-test FIXME I don't know how to test this (#2604)
|
||||
// compile-flags:-L.
|
||||
// The -L flag is also used for linking native libraries
|
||||
|
||||
|
@ -1,12 +1,6 @@
|
||||
// FIXME should be in run-pass
|
||||
|
||||
// -*- rust -*-
|
||||
|
||||
// error-pattern: Non-boolean return type
|
||||
|
||||
// this checks that a pred with a non-bool return
|
||||
// type is rejected, even if the pred is never used
|
||||
|
||||
pure fn bad(a: int) -> int { ret 37; }
|
||||
pure fn bad(a: int) -> int { ret 37; } //! ERROR Non-boolean return type
|
||||
|
||||
fn main() { }
|
||||
|
@ -15,7 +15,7 @@ fn test05() {
|
||||
log(error, *three + n); // will copy x into the closure
|
||||
assert(*three == 3);
|
||||
};
|
||||
task::spawn(fn~[move fn_to_send]() {
|
||||
task::spawn(fn~(move fn_to_send) {
|
||||
test05_start(fn_to_send);
|
||||
});
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ fn test_tag() {
|
||||
send(ch, tag2(10));
|
||||
send(ch, tag3(10, 11u8, 'A'));
|
||||
// FIXME: Do port semantics really guarantee these happen in order?
|
||||
// (#2605)
|
||||
let mut t1: t;
|
||||
t1 = recv(po);
|
||||
assert (t1 == tag1);
|
||||
|
@ -2,7 +2,7 @@
|
||||
A test case for issue #577, which also exposes #588
|
||||
*/
|
||||
|
||||
// FIXME: This won't work until we can compare resources
|
||||
// FIXME: This won't work until we can compare resources (#2601)
|
||||
// xfail-test
|
||||
|
||||
use std;
|
||||
|
@ -8,7 +8,7 @@ fn main() {
|
||||
let y = ~2;
|
||||
let y_in_parent = ptr::addr_of(*y) as uint;
|
||||
|
||||
task::spawn(fn~[copy ch, y; move x]() {
|
||||
task::spawn(fn~(copy ch, copy y, move x) {
|
||||
let x_in_child = ptr::addr_of(*x) as uint;
|
||||
comm::send(ch, x_in_child);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
fn main() {
|
||||
let x = ~1;
|
||||
let lam_move = fn@[move x]() { };
|
||||
let lam_move = fn@(move x) { };
|
||||
lam_move();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user