Merge branch 'incoming' into newsnap

This commit is contained in:
Eric Holk 2012-06-14 19:36:22 -07:00
commit 52c38ba886
52 changed files with 337 additions and 254 deletions

View File

@ -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)

View File

@ -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 \

View File

@ -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: $$@)

View File

@ -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))

View File

@ -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.

View File

@ -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.

View File

@ -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() {

View File

@ -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)
// }

View File

@ -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;

View File

@ -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::*;

View File

@ -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

View File

@ -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", []);

View File

@ -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; }

View File

@ -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();
});
}

View File

@ -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)
// }

View File

@ -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|

View File

@ -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 %?",

View File

@ -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]

View File

@ -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}), "::")
}

View File

@ -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]);

View File

@ -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,

View File

@ -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) {

View File

@ -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);
}

View File

@ -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;

View File

@ -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)) {

View File

@ -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);
}
//

View File

@ -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]",

View File

@ -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 }
}

View File

@ -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|

View File

@ -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);

View File

@ -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,
};

View File

@ -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

View File

@ -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"

View File

@ -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))
});

View File

@ -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>;

View File

@ -0,0 +1,5 @@
// error-pattern:divide by zero
fn main() {
let y = 0;
let z = 1 / y;
}

View File

@ -0,0 +1,5 @@
// error-pattern:modulo zero
fn main() {
let y = 0;
let z = 1 % y;
}

View File

@ -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]); }

View File

@ -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");
}

View File

@ -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>();

View File

@ -1,5 +1,3 @@
// xfail-fast
// (Not sure why, though -- FIXME (tjc)
import to_str::*;
import to_str::to_str;

View File

@ -0,0 +1,10 @@
class kitten {
let cat: option<cat>;
new(cat: option<cat>) {
self.cat = cat;
}
}
type cat = @kitten;
fn main() {}

View File

@ -1,6 +1,6 @@
fn main() {
let x = 1;
let y = fn@[move x]() -> int {
let y = fn@(move x) -> int {
x
}();
}

View 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() {}

View File

@ -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.

View File

@ -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

View File

@ -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() { }

View File

@ -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);
});
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -1,5 +1,5 @@
fn main() {
let x = ~1;
let lam_move = fn@[move x]() { };
let lam_move = fn@(move x) { };
lam_move();
}