diff --git a/Makefile.in b/Makefile.in index 8ab704ebe1719..9b59c46e5e831 100644 --- a/Makefile.in +++ b/Makefile.in @@ -122,6 +122,10 @@ endif ifdef TRACE CFG_RUSTC_FLAGS += -Z trace endif +ifndef DEBUG_BORROWS + RUSTFLAGS_STAGE1 += -Z no-debug-borrows + RUSTFLAGS_STAGE2 += -Z no-debug-borrows +endif # platform-specific auto-configuration include $(CFG_SRC_DIR)mk/platform.mk diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs index 9c1e566f218f6..4ba54f2ad8dfb 100644 --- a/src/libcore/rt/context.rs +++ b/src/libcore/rt/context.rs @@ -45,7 +45,7 @@ pub impl Context { // The C-ABI function that is the task entry point extern fn task_start_wrapper(f: &~fn()) { (*f)() } - let fp: *c_void = task_start_wrapper as *c_void; + let fp: *c_void = unsafe { transmute(task_start_wrapper) }; let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) }; let sp: *uint = stack.end(); let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) }; diff --git a/src/libcore/rt/local_services.rs b/src/libcore/rt/local_services.rs index bc945707e624f..0b265cdd1b435 100644 --- a/src/libcore/rt/local_services.rs +++ b/src/libcore/rt/local_services.rs @@ -138,7 +138,14 @@ impl Unwinder { extern { #[rust_stack] + #[cfg(stage0)] fn rust_try(f: *u8, code: *c_void, data: *c_void) -> uintptr_t; + #[rust_stack] + #[cfg(not(stage0))] + fn rust_try(f: extern "C" fn(code: *c_void, env: *c_void), + code: *c_void, + data: *c_void) + -> uintptr_t; } } diff --git a/src/libcore/rt/uv/net.rs b/src/libcore/rt/uv/net.rs index 3e6aa657c57dd..e62a2c2a57bdf 100644 --- a/src/libcore/rt/uv/net.rs +++ b/src/libcore/rt/uv/net.rs @@ -62,7 +62,6 @@ pub type AllocCallback = ~fn(uint) -> Buf; impl Callback for AllocCallback { } pub impl StreamWatcher { - fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) { // XXX: Borrowchk problems let data = get_watcher_data(unsafe { transmute_mut_region(self) }); @@ -70,7 +69,9 @@ pub impl StreamWatcher { data.read_cb = Some(cb); let handle = self.native_handle(); - unsafe { uvll::read_start(handle, alloc_cb, read_cb); } + unsafe { + uvll::read_start(handle, alloc_cb, read_cb); + } extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf { let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream); @@ -112,8 +113,9 @@ pub impl StreamWatcher { let bufs = [buf]; unsafe { assert!(0 == uvll::write(req.native_handle(), - self.native_handle(), - bufs, write_cb)); + self.native_handle(), + bufs, + write_cb)); } extern fn write_cb(req: *uvll::uv_write_t, status: c_int) { @@ -147,7 +149,9 @@ pub impl StreamWatcher { data.close_cb = Some(cb); } - unsafe { uvll::close(self.native_handle(), close_cb); } + unsafe { + uvll::close(self.native_handle(), close_cb); + } extern fn close_cb(handle: *uvll::uv_stream_t) { let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle); @@ -219,8 +223,9 @@ pub impl TcpWatcher { do ip4_as_uv_ip4(address) |addr| { rtdebug!("connect_t: %x", connect_handle as uint); assert!(0 == uvll::tcp_connect(connect_handle, - self.native_handle(), - addr, connect_cb)); + self.native_handle(), + addr, + connect_cb)); } } _ => fail!() @@ -251,7 +256,8 @@ pub impl TcpWatcher { static BACKLOG: c_int = 128; // XXX should be configurable // XXX: This can probably fail assert!(0 == uvll::listen(self.native_handle(), - BACKLOG, connection_cb)); + BACKLOG, + connection_cb)); } extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) { diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs index 0d298bde6b508..070f27bdd3993 100644 --- a/src/libcore/rt/uvll.rs +++ b/src/libcore/rt/uvll.rs @@ -54,7 +54,10 @@ pub type uv_timer_t = c_void; pub type uv_stream_t = c_void; pub type uv_fs_t = c_void; +#[cfg(stage0)] pub type uv_idle_cb = *u8; +#[cfg(not(stage0))] +pub type uv_idle_cb = extern "C" fn(*c_void, i32); pub type sockaddr_in = c_void; pub type sockaddr_in6 = c_void; @@ -146,10 +149,17 @@ pub unsafe fn run(loop_handle: *c_void) { rust_uv_run(loop_handle); } +#[cfg(stage0)] pub unsafe fn close(handle: *T, cb: *u8) { rust_uv_close(handle as *c_void, cb); } +#[cfg(not(stage0))] +pub unsafe fn close(handle: *T, + callback: extern "C" fn(handle: *uv_stream_t)) { + rust_uv_close(handle as *c_void, callback); +} + pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) { rust_uv_walk(loop_handle, cb, arg); } @@ -179,12 +189,29 @@ pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int { } // FIXME ref #2064 +#[cfg(stage0)] +pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + addr_ptr: *sockaddr_in, + after_connect_cb: *u8) + -> c_int { + return rust_uv_tcp_connect(connect_ptr, + tcp_handle_ptr, + after_connect_cb, + addr_ptr); +} + +// FIXME ref #2064 +#[cfg(not(stage0))] pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in, - after_connect_cb: *u8) -> c_int { - return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, - after_connect_cb, addr_ptr); + after_connect_cb: extern "C" fn(*c_void, i32)) + -> c_int { + return rust_uv_tcp_connect(connect_ptr, + tcp_handle_ptr, + after_connect_cb, + addr_ptr); } // FIXME ref #2064 pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, @@ -211,20 +238,64 @@ pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) - return rust_uv_tcp_getpeername6(tcp_handle_ptr, name); } +#[cfg(stage0)] pub unsafe fn listen(stream: *T, backlog: c_int, cb: *u8) -> c_int { return rust_uv_listen(stream as *c_void, backlog, cb); } +#[cfg(not(stage0))] +pub unsafe fn listen(stream: *T, + backlog: c_int, + callback: extern "C" fn(a: *c_void, b: i32)) + -> c_int { + return rust_uv_listen(stream as *c_void, backlog, callback); +} + pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int { return rust_uv_accept(server as *c_void, client as *c_void); } -pub unsafe fn write(req: *uv_write_t, stream: *T, buf_in: &[uv_buf_t], cb: *u8) -> c_int { +#[cfg(stage0)] +pub unsafe fn write(req: *uv_write_t, + stream: *T, + buf_in: &[uv_buf_t], + callback: *u8) + -> c_int { let buf_ptr = vec::raw::to_ptr(buf_in); - let buf_cnt = buf_in.len() as i32; - return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb); + let buf_cnt = vec::len(buf_in) as i32; + return rust_uv_write(req as *c_void, + stream as *c_void, + buf_ptr, + buf_cnt, + callback); +} + +#[cfg(not(stage0))] +pub unsafe fn write(req: *uv_write_t, + stream: *T, + buf_in: &[uv_buf_t], + callback: extern "C" fn(*c_void, i32)) + -> c_int { + let buf_ptr = vec::raw::to_ptr(buf_in); + let buf_cnt = vec::len(buf_in) as i32; + return rust_uv_write(req as *c_void, + stream as *c_void, + buf_ptr, + buf_cnt, + callback); } -pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> c_int { + +#[cfg(stage0)] +pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) + -> c_int { + return rust_uv_read_start(stream as *c_void, on_alloc, on_read); +} + +#[cfg(not(stage0))] +pub unsafe fn read_start(stream: *uv_stream_t, + on_alloc: extern "C" fn(*c_void, u64) -> uv_buf_t, + on_read: extern "C" fn(*c_void, i64, uv_buf_t)) + -> c_int { return rust_uv_read_start(stream as *c_void, on_alloc, on_read); } @@ -361,7 +432,13 @@ extern { fn rust_uv_loop_new() -> *c_void; fn rust_uv_loop_delete(lp: *c_void); fn rust_uv_run(loop_handle: *c_void); + + #[cfg(stage0)] fn rust_uv_close(handle: *c_void, cb: *u8); + #[cfg(not(stage0))] + fn rust_uv_close(handle: *c_void, + callback: extern "C" fn(handle: *uv_stream_t)); + fn rust_uv_walk(loop_handle: *c_void, cb: *u8, arg: *c_void); fn rust_uv_idle_new() -> *uv_idle_t; @@ -390,11 +467,19 @@ extern { fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int; fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint; fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint; + // FIXME ref #2064 + #[cfg(stage0)] fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, after_cb: *u8, addr: *sockaddr_in) -> c_int; + #[cfg(not(stage0))] + fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + after_cb: extern "C" fn(*libc::c_void, i32), + addr: *sockaddr_in) -> c_int; + // FIXME ref #2064 fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int; // FIXME ref #2064 @@ -408,16 +493,39 @@ extern { name: *sockaddr_in) -> c_int; fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) ->c_int; + + #[cfg(stage0)] fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int; + #[cfg(not(stage0))] + fn rust_uv_listen(stream: *c_void, + backlog: c_int, + callback: extern "C" fn(a: *c_void, b: i32)) + -> c_int; + fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int; + + #[cfg(stage0)] fn rust_uv_write(req: *c_void, stream: *c_void, buf_in: *uv_buf_t, buf_cnt: c_int, cb: *u8) -> c_int; + + #[cfg(not(stage0))] + fn rust_uv_write(req: *c_void, + stream: *c_void, + buf_in: *uv_buf_t, + buf_cnt: c_int, + callback: extern "C" fn(*c_void, i32)) + -> c_int; + #[cfg(stage0)] + fn rust_uv_read_start(stream: *c_void, on_alloc: *u8, on_read: *u8) + -> c_int; + #[cfg(not(stage0))] fn rust_uv_read_start(stream: *c_void, - on_alloc: *u8, - on_read: *u8) -> c_int; + on_alloc: extern "C" fn(*c_void, u64) -> uv_buf_t, + on_read: extern "C" fn(*c_void, i64, uv_buf_t)) + -> c_int; fn rust_uv_read_stop(stream: *c_void) -> c_int; fn rust_uv_timer_init(loop_handle: *c_void, timer_handle: *uv_timer_t) -> c_int; diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index 766815a5e90b6..27a7e0b7a4e58 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -61,7 +61,7 @@ impl Eq for @LocalData { // proper map. type TaskLocalElement = (*libc::c_void, *libc::c_void, @LocalData); // Has to be a pointer at outermost layer; the foreign call returns void *. -type TaskLocalMap = @mut ~[Option]; +pub type TaskLocalMap = @mut ~[Option]; fn cleanup_task_local_map(map_ptr: *libc::c_void) { unsafe { @@ -82,7 +82,6 @@ unsafe fn get_local_map(handle: Handle) -> TaskLocalMap { } unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { - extern fn cleanup_task_local_map_extern_cb(map_ptr: *libc::c_void) { cleanup_task_local_map(map_ptr); } diff --git a/src/libcore/task/rt.rs b/src/libcore/task/rt.rs index 760812252bc73..2a4f3de023f21 100644 --- a/src/libcore/task/rt.rs +++ b/src/libcore/task/rt.rs @@ -17,6 +17,7 @@ The task interface to the runtime #[doc(hidden)]; // FIXME #3538 use libc; +use task::local_data_priv::TaskLocalMap; #[allow(non_camel_case_types)] // runtime type pub type sched_id = int; @@ -67,5 +68,11 @@ pub extern { #[rust_stack] fn rust_set_task_local_data(task: *rust_task, map: *libc::c_void); #[rust_stack] + #[cfg(stage0)] fn rust_task_local_data_atexit(task: *rust_task, cleanup_fn: *u8); + #[rust_stack] + #[cfg(not(stage0))] + fn rust_task_local_data_atexit( + task: *rust_task, + cleanup_fn: extern "C" fn(a: *libc::c_void)); } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 16eec0b10dea7..4c8ce8d1145e6 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -64,6 +64,7 @@ pub static debug_info: uint = 1 << 20; pub static extra_debug_info: uint = 1 << 21; pub static statik: uint = 1 << 22; pub static print_link_args: uint = 1 << 23; +pub static no_debug_borrows: uint = 1 << 24; pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ~[(~"verbose", ~"in general, enable more debug printouts", verbose), @@ -98,7 +99,10 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { extra_debug_info), (~"debug-info", ~"Produce debug info (experimental)", debug_info), (~"static", ~"Use or produce static libraries or binaries " + - "(experimental)", statik) + "(experimental)", statik), + (~"no-debug-borrows", + ~"do not show where borrow checks fail", + no_debug_borrows), ] } @@ -139,7 +143,7 @@ pub struct options { parse_only: bool, no_trans: bool, debugging_opts: uint, - android_cross_path: Option<~str> + android_cross_path: Option<~str>, } pub struct crate_metadata { @@ -281,6 +285,9 @@ pub impl Session_ { fn no_monomorphic_collapse(@self) -> bool { self.debugging_opt(no_monomorphic_collapse) } + fn debug_borrows(@self) -> bool { + self.opts.optimize == No && !self.debugging_opt(no_debug_borrows) + } fn str_of(@self, id: ast::ident) -> @~str { self.parse_sess.interner.get(id) @@ -318,7 +325,7 @@ pub fn basic_options() -> @options { parse_only: false, no_trans: false, debugging_opts: 0u, - android_cross_path: None + android_cross_path: None, } } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index e6b8432854d32..51f4ca3532e81 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -64,7 +64,7 @@ pub fn each_lang_item(cstore: @mut cstore::CStore, #[cfg(stage0)] pub fn each_path(cstore: @mut cstore::CStore, cnum: ast::crate_num, - f: &fn(&str, decoder::def_like) -> bool) { + f: &fn(&str, decoder::def_like, ast::visibility) -> bool) { let crate_data = cstore::get_crate_data(cstore, cnum); let get_crate_data: decoder::GetCrateDataCb = |cnum| { cstore::get_crate_data(cstore, cnum) @@ -75,7 +75,8 @@ pub fn each_path(cstore: @mut cstore::CStore, #[cfg(not(stage0))] pub fn each_path(cstore: @mut cstore::CStore, cnum: ast::crate_num, - f: &fn(&str, decoder::def_like) -> bool) -> bool { + f: &fn(&str, decoder::def_like, ast::visibility) -> bool) + -> bool { let crate_data = cstore::get_crate_data(cstore, cnum); let get_crate_data: decoder::GetCrateDataCb = |cnum| { cstore::get_crate_data(cstore, cnum) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 2592875cd5753..8f9e50da0d7bf 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -328,8 +328,7 @@ fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident { } fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num) - -> def_like -{ + -> def_like { let fam = item_family(item); match fam { Const => dl_def(ast::def_const(did)), @@ -500,9 +499,11 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool { } /// Iterates over all the paths in the given crate. -pub fn _each_path(intr: @ident_interner, cdata: cmd, +pub fn _each_path(intr: @ident_interner, + cdata: cmd, get_crate_data: GetCrateDataCb, - f: &fn(&str, def_like) -> bool) -> bool { + f: &fn(&str, def_like, ast::visibility) -> bool) + -> bool { let root = reader::Doc(cdata.data); let items = reader::get_doc(root, tag_items); let items_data = reader::get_doc(items, tag_items_data); @@ -523,8 +524,10 @@ pub fn _each_path(intr: @ident_interner, cdata: cmd, debug!("(each_path) yielding explicit item: %s", path); let def_like = item_to_def_like(item_doc, def_id, cdata.cnum); + let vis = item_visibility(item_doc); + // Hand the information off to the iteratee. - if !f(path, def_like) { + if !f(path, def_like, vis) { broken = true; // FIXME #4572: This is awful. } } @@ -574,7 +577,7 @@ pub fn _each_path(intr: @ident_interner, cdata: cmd, debug!("(each_path) yielding reexported \ item: %s", reexport_path); - if (!f(reexport_path, def_like)) { + if (!f(reexport_path, def_like, ast::public)) { broken = true; // FIXME #4572: This is awful. } } @@ -588,15 +591,18 @@ pub fn _each_path(intr: @ident_interner, cdata: cmd, } #[cfg(stage0)] -pub fn each_path(intr: @ident_interner, cdata: cmd, +pub fn each_path(intr: @ident_interner, + cdata: cmd, get_crate_data: GetCrateDataCb, - f: &fn(&str, def_like) -> bool) { + f: &fn(&str, def_like, ast::visibility) -> bool) { _each_path(intr, cdata, get_crate_data, f); } #[cfg(not(stage0))] -pub fn each_path(intr: @ident_interner, cdata: cmd, +pub fn each_path(intr: @ident_interner, + cdata: cmd, get_crate_data: GetCrateDataCb, - f: &fn(&str, def_like) -> bool) -> bool { + f: &fn(&str, def_like, ast::visibility) -> bool) + -> bool { _each_path(intr, cdata, get_crate_data, f) } @@ -1160,7 +1166,7 @@ pub fn get_crate_vers(data: @~[u8]) -> @~str { fn iter_crate_items(intr: @ident_interner, cdata: cmd, get_crate_data: GetCrateDataCb, proc: &fn(path: &str, ast::def_id)) { - for each_path(intr, cdata, get_crate_data) |path_string, def_like| { + for each_path(intr, cdata, get_crate_data) |path_string, def_like, _| { match def_like { dl_impl(*) | dl_field => {} dl_def(def) => { diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index d27bfd081bc65..7ffc22501c693 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -316,6 +316,7 @@ fn encode_enum_variant_info(ecx: @EncodeContext, encode_family(ebml_w, 'v'); encode_name(ecx, ebml_w, variant.node.name); encode_parent_item(ebml_w, local_def(id)); + encode_visibility(ebml_w, variant.node.vis); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, variant.node.id)); match variant.node.kind { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 0d8d4baaa8061..3b010d58ecf90 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -56,6 +56,7 @@ use syntax::ast::{variant, view_item, view_item_extern_mod}; use syntax::ast::{view_item_use, view_path_glob, view_path_list}; use syntax::ast::{view_path_simple, anonymous, named, not}; use syntax::ast::{unsafe_fn}; +use syntax::ast; use syntax::ast_util::{def_id_of_def, local_def}; use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{Privacy, Public, Private}; @@ -290,8 +291,20 @@ pub enum AllowCapturingSelfFlag { #[deriving(Eq)] enum NameSearchType { - SearchItemsAndPublicImports, //< Search items and public imports. - SearchItemsAndAllImports, //< Search items and all imports. + /// We're doing a name search in order to resolve a `use` directive. + ImportSearch, + + /// We're doing a name search in order to resolve a path type, a path + /// expression, or a path pattern. We can select public or private + /// names. + /// + /// XXX: This should be ripped out of resolve and handled later, in + /// the privacy checking phase. + PathPublicOrPrivateSearch, + + /// We're doing a name search in order to resolve a path type, a path + /// expression, or a path pattern. Allow only public names to be selected. + PathPublicOnlySearch, } pub enum BareIdentifierPatternResolution { @@ -425,7 +438,10 @@ pub struct ImportState { } pub fn ImportState() -> ImportState { - ImportState{ used: false, warned: false } + ImportState { + used: false, + warned: false, + } } /// The link from a module up to its nearest parent node. @@ -440,6 +456,7 @@ pub enum ModuleKind { NormalModuleKind, ExternModuleKind, TraitModuleKind, + ImplModuleKind, AnonymousModuleKind, } @@ -470,7 +487,6 @@ pub struct Module { // // There will be an anonymous module created around `g` with the ID of the // entry block for `f`. - anonymous_children: @mut HashMap, // The status of resolving each import in this module. @@ -560,6 +576,40 @@ pub impl NameBindings { } } + /// Sets the kind of the module, creating a new one if necessary. + fn set_module_kind(@mut self, + privacy: Privacy, + parent_link: ParentLink, + def_id: Option, + kind: ModuleKind, + sp: span) { + match self.type_def { + None => { + let module = @mut Module(parent_link, def_id, kind); + self.type_def = Some(TypeNsDef { + privacy: privacy, + module_def: Some(module), + type_def: None, + type_span: None, + }) + } + Some(type_def) => { + match type_def.module_def { + None => { + let module = @mut Module(parent_link, def_id, kind); + self.type_def = Some(TypeNsDef { + privacy: privacy, + module_def: Some(module), + type_def: type_def.type_def, + type_span: None, + }) + } + Some(module_def) => module_def.kind = kind, + } + } + } + } + /// Records a type definition. fn define_type(@mut self, privacy: Privacy, def: def, sp: span) { // Merges the type with the existing type def or creates a new one. @@ -1234,7 +1284,7 @@ pub impl Resolver { name_bindings.define_module(Public, parent_link, Some(def_id), - TraitModuleKind, + ImplModuleKind, sp); let new_parent = ModuleReducedGraphParent( @@ -1383,10 +1433,8 @@ pub impl Resolver { } } - /** - * Constructs the reduced graph for one 'view item'. View items consist - * of imports and use directives. - */ + /// Constructs the reduced graph for one 'view item'. View items consist + /// of imports and use directives. fn build_reduced_graph_for_view_item(@mut self, view_item: @view_item, parent: ReducedGraphParent, @@ -1539,11 +1587,13 @@ pub impl Resolver { fn handle_external_def(@mut self, def: def, + visibility: ast::visibility, modules: &mut HashMap, child_name_bindings: @mut NameBindings, final_ident: &str, ident: ident, new_parent: ReducedGraphParent) { + let privacy = visibility_to_privacy(visibility); match def { def_mod(def_id) | def_foreign_mod(def_id) => { match child_name_bindings.type_def { @@ -1561,7 +1611,7 @@ pub impl Resolver { // FIXME (#5074): this should be a match on find if !modules.contains_key(&def_id) { - child_name_bindings.define_module(Public, + child_name_bindings.define_module(privacy, parent_link, Some(def_id), NormalModuleKind, @@ -1570,12 +1620,12 @@ pub impl Resolver { child_name_bindings.get_module()); } else { let existing_module = *modules.get(&def_id); - // Create an import resolution to - // avoid creating cycles in the - // module graph. + + // Create an import resolution to avoid creating cycles in + // the module graph. let resolution = - @mut ImportResolution(Public, + @mut ImportResolution(privacy, dummy_sp(), @mut ImportState()); resolution.outstanding_references = 0; @@ -1601,11 +1651,19 @@ pub impl Resolver { } } } - def_fn(*) | def_static_method(*) | def_const(*) | def_variant(*) => { + debug!("(building reduced graph for external crate) building \ + variant %s", + final_ident); + // We assume the parent is visible, or else we wouldn't have seen + // it. + let privacy = variant_visibility_to_privacy(visibility, true); + child_name_bindings.define_value(privacy, def, dummy_sp()); + } + def_fn(*) | def_static_method(*) | def_const(*) => { debug!("(building reduced graph for external \ crate) building value %s", final_ident); - child_name_bindings.define_value(Public, def, dummy_sp()); + child_name_bindings.define_value(privacy, def, dummy_sp()); } def_trait(def_id) => { debug!("(building reduced graph for external \ @@ -1614,8 +1672,8 @@ pub impl Resolver { // If this is a trait, add all the method names // to the trait info. - let method_def_ids = get_trait_method_def_ids(self.session.cstore, - def_id); + let method_def_ids = + get_trait_method_def_ids(self.session.cstore, def_id); let mut interned_method_names = HashSet::new(); for method_def_ids.each |&method_def_id| { let (method_name, explicit_self) = @@ -1634,19 +1692,27 @@ pub impl Resolver { } self.trait_info.insert(def_id, interned_method_names); - child_name_bindings.define_type(Public, def, dummy_sp()); + child_name_bindings.define_type(privacy, def, dummy_sp()); + + // Define a module if necessary. + let parent_link = self.get_parent_link(new_parent, ident); + child_name_bindings.set_module_kind(privacy, + parent_link, + Some(def_id), + TraitModuleKind, + dummy_sp()) } def_ty(_) => { debug!("(building reduced graph for external \ crate) building type %s", final_ident); - child_name_bindings.define_type(Public, def, dummy_sp()); + child_name_bindings.define_type(privacy, def, dummy_sp()); } def_struct(def_id) => { debug!("(building reduced graph for external \ crate) building type %s", final_ident); - child_name_bindings.define_type(Public, def, dummy_sp()); + child_name_bindings.define_type(privacy, def, dummy_sp()); self.structs.insert(def_id); } def_self(*) | def_arg(*) | def_local(*) | @@ -1667,7 +1733,7 @@ pub impl Resolver { // Create all the items reachable by paths. for each_path(self.session.cstore, root.def_id.get().crate) - |path_string, def_like| { + |path_string, def_like, visibility| { debug!("(building reduced graph for external crate) found path \ entry: %s (%?)", @@ -1735,6 +1801,7 @@ pub impl Resolver { dummy_sp()); self.handle_external_def(def, + visibility, &mut modules, child_name_bindings, *self.session.str_of( @@ -1777,6 +1844,10 @@ pub impl Resolver { // We already have a module. This // is OK. type_module = module_def; + + // Mark it as an impl module if + // necessary. + type_module.kind = ImplModuleKind; } Some(_) | None => { let parent_link = @@ -1786,7 +1857,7 @@ pub impl Resolver { Public, parent_link, Some(def), - NormalModuleKind, + ImplModuleKind, dummy_sp()); type_module = child_name_bindings. @@ -1897,10 +1968,8 @@ pub impl Resolver { // remain or unsuccessfully when no forward progress in resolving imports // is made. - /** - * Resolves all imports for the crate. This method performs the fixed- - * point iteration. - */ + /// Resolves all imports for the crate. This method performs the fixed- + /// point iteration. fn resolve_imports(@mut self) { let mut i = 0; let mut prev_unresolved_imports = 0; @@ -2022,9 +2091,10 @@ pub impl Resolver { /// don't know whether the name exists at the moment due to other /// currently-unresolved imports, or success if we know the name exists. /// If successful, the resolved bindings are written into the module. - fn resolve_import_for_module(@mut self, module_: @mut Module, + fn resolve_import_for_module(@mut self, + module_: @mut Module, import_directive: @ImportDirective) - -> ResolveResult<()> { + -> ResolveResult<()> { let mut resolution_result = Failed; let module_path = &import_directive.module_path; @@ -2038,10 +2108,11 @@ pub impl Resolver { // Use the crate root. Some(self.graph_root.get_module()) } else { - match self.resolve_module_path_for_import(module_, - *module_path, - DontUseLexicalScope, - import_directive.span) { + match self.resolve_module_path(module_, + *module_path, + DontUseLexicalScope, + import_directive.span, + ImportSearch) { Failed => None, Indeterminate => { @@ -2129,7 +2200,7 @@ pub impl Resolver { target: ident, source: ident, span: span) - -> ResolveResult<()> { + -> ResolveResult<()> { debug!("(resolving single import) resolving `%s` = `%s::%s` from \ `%s`", *self.session.str_of(target), @@ -2166,9 +2237,7 @@ pub impl Resolver { // Unless we managed to find a result in both namespaces (unlikely), // search imports as well. match (value_result, type_result) { - (BoundResult(*), BoundResult(*)) => { - // Continue. - } + (BoundResult(*), BoundResult(*)) => {} // Continue. _ => { // If there is an unresolved glob at this point in the // containing module, bail out. We don't know enough to be @@ -2496,7 +2565,6 @@ pub impl Resolver { // Resolve the module part of the path. This does not involve looking // upward though scope chains; we simply resolve names directly in // modules as we go. - while index < module_path_len { let name = module_path[index]; match self.resolve_name_in_module(search_module, @@ -2506,12 +2574,17 @@ pub impl Resolver { Failed => { let segment_name = self.session.str_of(name); let module_name = self.module_to_str(search_module); - if module_name == ~"???" { - self.session.span_err(span {lo: span.lo, hi: span.lo + - BytePos(str::len(*segment_name)), expn_info: - span.expn_info}, fmt!("unresolved import. maybe \ - a missing `extern mod %s`?", - *segment_name)); + if "???" == module_name { + let span = span { + lo: span.lo, + hi: span.lo + BytePos(str::len(*segment_name)), + expn_info: span.expn_info, + }; + self.session.span_err(span, + fmt!("unresolved import. maybe \ + a missing `extern mod \ + %s`?", + *segment_name)); return Failed; } self.session.span_err(span, fmt!("unresolved import: could not find `%s` in \ @@ -2540,8 +2613,22 @@ pub impl Resolver { name))); return Failed; } - Some(copy module_def) => { - search_module = module_def; + Some(module_def) => { + // If we're doing the search for an + // import, do not allow traits and impls + // to be selected. + match (name_search_type, + module_def.kind) { + (ImportSearch, TraitModuleKind) | + (ImportSearch, ImplModuleKind) => { + self.session.span_err( + span, + ~"cannot import from a trait \ + or type implementation"); + return Failed; + } + (_, _) => search_module = module_def, + } } } } @@ -2559,18 +2646,13 @@ pub impl Resolver { index += 1; - // After the first element of the path, allow searching through - // items and imports unconditionally. This allows things like: + // After the first element of the path, allow searching only + // through public identifiers. // - // pub mod core { - // pub use vec; - // } - // - // pub mod something_else { - // use core::vec; - // } - - name_search_type = SearchItemsAndPublicImports; + // XXX: Rip this out and move it to the privacy checker. + if name_search_type == PathPublicOrPrivateSearch { + name_search_type = PathPublicOnlySearch + } } return Success(search_module); @@ -2578,12 +2660,13 @@ pub impl Resolver { /// Attempts to resolve the module part of an import directive or path /// rooted at the given module. - fn resolve_module_path_for_import(@mut self, - module_: @mut Module, - module_path: &[ident], - use_lexical_scope: UseLexicalScopeFlag, - span: span) - -> ResolveResult<@mut Module> { + fn resolve_module_path(@mut self, + module_: @mut Module, + module_path: &[ident], + use_lexical_scope: UseLexicalScopeFlag, + span: span, + name_search_type: NameSearchType) + -> ResolveResult<@mut Module> { let module_path_len = module_path.len(); assert!(module_path_len > 0); @@ -2666,7 +2749,7 @@ pub impl Resolver { module_path, start_index, span, - SearchItemsAndPublicImports) + name_search_type) } /// Invariant: This must only be called during main resolution, not during @@ -2758,6 +2841,7 @@ pub impl Resolver { } ExternModuleKind | TraitModuleKind | + ImplModuleKind | AnonymousModuleKind => { search_module = parent_module_node; } @@ -2777,7 +2861,7 @@ pub impl Resolver { match self.resolve_name_in_module(search_module, name, namespace, - SearchItemsAndAllImports) { + PathPublicOrPrivateSearch) { Failed => { // Continue up the search chain. } @@ -2858,6 +2942,7 @@ pub impl Resolver { NormalModuleKind => return Some(new_module), ExternModuleKind | TraitModuleKind | + ImplModuleKind | AnonymousModuleKind => module_ = new_module, } } @@ -2874,7 +2959,10 @@ pub impl Resolver { -> @mut Module { match module_.kind { NormalModuleKind => return module_, - ExternModuleKind | TraitModuleKind | AnonymousModuleKind => { + ExternModuleKind | + TraitModuleKind | + ImplModuleKind | + AnonymousModuleKind => { match self.get_nearest_normal_module_parent(module_) { None => module_, Some(new_module) => new_module @@ -2958,7 +3046,8 @@ pub impl Resolver { // If this is a search of all imports, we should be done with glob // resolution at this point. - if name_search_type == SearchItemsAndAllImports { + if name_search_type == PathPublicOrPrivateSearch || + name_search_type == PathPublicOnlySearch { assert!(module_.glob_count == 0); } @@ -2980,7 +3069,7 @@ pub impl Resolver { } Some(target) if name_search_type == - SearchItemsAndAllImports || + PathPublicOrPrivateSearch || import_resolution.privacy == Public => { debug!("(resolving name in module) resolved to \ import"); @@ -4506,10 +4595,11 @@ pub impl Resolver { let module_path_idents = self.intern_module_part_of_path(path); let containing_module; - match self.resolve_module_path_for_import(self.current_module, - module_path_idents, - UseLexicalScope, - path.span) { + match self.resolve_module_path(self.current_module, + module_path_idents, + UseLexicalScope, + path.span, + PathPublicOnlySearch) { Failed => { self.session.span_err(path.span, fmt!("use of undeclared module `%s`", @@ -4558,7 +4648,7 @@ pub impl Resolver { module_path_idents, 0, path.span, - SearchItemsAndAllImports) { + PathPublicOrPrivateSearch) { Failed => { self.session.span_err(path.span, fmt!("use of undeclared module `::%s`", diff --git a/src/librustc/middle/resolve_stage0.rs b/src/librustc/middle/resolve_stage0.rs index a404dcf7249b2..2c27928a94252 100644 --- a/src/librustc/middle/resolve_stage0.rs +++ b/src/librustc/middle/resolve_stage0.rs @@ -57,6 +57,7 @@ use syntax::ast::{variant, view_item, view_item_extern_mod}; use syntax::ast::{view_item_use, view_path_glob, view_path_list}; use syntax::ast::{view_path_simple, anonymous, named, not}; use syntax::ast::{unsafe_fn}; +use syntax::ast; use syntax::ast_util::{def_id_of_def, local_def}; use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{Privacy, Public, Private}; @@ -1393,10 +1394,8 @@ pub impl Resolver { } } - /** - * Constructs the reduced graph for one 'view item'. View items consist - * of imports and use directives. - */ + /// Constructs the reduced graph for one 'view item'. View items consist + /// of imports and use directives. fn build_reduced_graph_for_view_item(@mut self, view_item: @view_item, parent: ReducedGraphParent, @@ -1549,11 +1548,13 @@ pub impl Resolver { fn handle_external_def(@mut self, def: def, + visibility: ast::visibility, modules: &mut HashMap, child_name_bindings: @mut NameBindings, final_ident: &str, ident: ident, new_parent: ReducedGraphParent) { + let privacy = visibility_to_privacy(visibility); match def { def_mod(def_id) | def_foreign_mod(def_id) => { match child_name_bindings.type_def { @@ -1571,7 +1572,7 @@ pub impl Resolver { // FIXME (#5074): this should be a match on find if !modules.contains_key(&def_id) { - child_name_bindings.define_module(Public, + child_name_bindings.define_module(privacy, parent_link, Some(def_id), NormalModuleKind, @@ -1580,12 +1581,12 @@ pub impl Resolver { child_name_bindings.get_module()); } else { let existing_module = *modules.get(&def_id); - // Create an import resolution to - // avoid creating cycles in the - // module graph. + + // Create an import resolution to avoid creating cycles in + // the module graph. let resolution = - @mut ImportResolution(Public, + @mut ImportResolution(privacy, dummy_sp(), @mut ImportState()); resolution.outstanding_references = 0; @@ -1615,7 +1616,7 @@ pub impl Resolver { def_variant(*) => { debug!("(building reduced graph for external \ crate) building value %s", final_ident); - child_name_bindings.define_value(Public, def, dummy_sp()); + child_name_bindings.define_value(privacy, def, dummy_sp()); } def_trait(def_id) => { debug!("(building reduced graph for external \ @@ -1650,13 +1651,13 @@ pub impl Resolver { debug!("(building reduced graph for external \ crate) building type %s", final_ident); - child_name_bindings.define_type(Public, def, dummy_sp()); + child_name_bindings.define_type(privacy, def, dummy_sp()); } def_struct(def_id) => { debug!("(building reduced graph for external \ crate) building type %s", final_ident); - child_name_bindings.define_type(Public, def, dummy_sp()); + child_name_bindings.define_type(privacy, def, dummy_sp()); self.structs.insert(def_id); } def_self(*) | def_arg(*) | def_local(*) | @@ -1677,7 +1678,7 @@ pub impl Resolver { // Create all the items reachable by paths. for each_path(self.session.cstore, root.def_id.get().crate) - |path_string, def_like| { + |path_string, def_like, visibility| { debug!("(building reduced graph for external crate) found path \ entry: %s (%?)", @@ -1745,6 +1746,7 @@ pub impl Resolver { dummy_sp()); self.handle_external_def(def, + visibility, &mut modules, child_name_bindings, *self.session.str_of( diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 8000484c0550f..f01cb58d7aac4 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1089,8 +1089,7 @@ pub fn T_opaque_trait(cx: @CrateContext, store: ty::TraitStore) -> TypeRef { } ty::UniqTraitStore => { T_struct(~[T_ptr(cx.tydesc_type), - T_unique_ptr(T_unique(cx, T_i8())), - T_ptr(cx.tydesc_type)], + T_unique_ptr(T_unique(cx, T_i8()))], false) } ty::RegionTraitStore(_) => { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 59526ffbe498d..08a5fb9ff1be0 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1644,10 +1644,16 @@ fn trans_imm_cast(bcx: block, expr: @ast::expr, val_ty(lldiscrim_a), lldiscrim_a, true), cast_float => SIToFP(bcx, lldiscrim_a, ll_t_out), - _ => ccx.sess.bug(~"translating unsupported cast.") + _ => { + ccx.sess.span_bug(expr.span, + ~"translating unsupported cast.") + } } } - _ => ccx.sess.bug(~"translating unsupported cast.") + _ => { + ccx.sess.span_bug(expr.span, + ~"translating unsupported cast.") + } }; return immediate_rvalue_bcx(bcx, newval, t_out); } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 585d9d8420cd7..fec3b9482776c 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -545,9 +545,18 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { } ty::ty_trait(_, _, ty::UniqTraitStore, _) => { let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]); - let lltydesc = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_tydesc])); - call_tydesc_glue_full(bcx, lluniquevalue, lltydesc, - abi::tydesc_field_free_glue, None); + let llvtable = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable])); + + // Cast the vtable to a pointer to a pointer to a tydesc. + let llvtable = PointerCast(bcx, + llvtable, + T_ptr(T_ptr(ccx.tydesc_type))); + let lltydesc = Load(bcx, llvtable); + call_tydesc_glue_full(bcx, + lluniquevalue, + lltydesc, + abi::tydesc_field_free_glue, + None); bcx } ty::ty_opaque_closure_ptr(ck) => { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index bdbb45bf2755a..28ed4f8d1e476 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -39,9 +39,13 @@ for non-monomorphized methods only. Other methods will be generated once they are invoked with specific type parameters, see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`. */ -pub fn trans_impl(ccx: @CrateContext, path: path, name: ast::ident, - methods: &[@ast::method], generics: &ast::Generics, - self_ty: Option, id: ast::node_id) { +pub fn trans_impl(ccx: @CrateContext, + path: path, + name: ast::ident, + methods: &[@ast::method], + generics: &ast::Generics, + self_ty: Option, + id: ast::node_id) { let _icx = ccx.insn_ctxt("impl::trans_impl"); let tcx = ccx.tcx; @@ -718,7 +722,10 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Load the function from the vtable and cast it to the expected type. debug!("(translating trait callee) loading method"); let llcallee_ty = type_of_fn_from_ty(ccx, callee_ty); - let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method])); + + // Plus one in order to skip past the type descriptor. + let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method + 1])); + let mptr = PointerCast(bcx, mptr, T_ptr(llcallee_ty)); return Callee { @@ -756,26 +763,41 @@ pub fn vtable_id(ccx: @CrateContext, } } +/// Creates a returns a dynamic vtable for the given type and vtable origin. +/// This is used only for objects. pub fn get_vtable(ccx: @CrateContext, + self_ty: ty::t, origin: typeck::vtable_origin) - -> ValueRef { + -> ValueRef { // XXX: Bad copy. let hash_id = vtable_id(ccx, copy origin); match ccx.vtables.find(&hash_id) { - Some(&val) => val, - None => match origin { - typeck::vtable_static(id, substs, sub_vtables) => { - make_impl_vtable(ccx, id, substs, sub_vtables) + Some(&val) => val, + None => { + match origin { + typeck::vtable_static(id, substs, sub_vtables) => { + make_impl_vtable(ccx, id, self_ty, substs, sub_vtables) + } + _ => fail!("get_vtable: expected a static origin"), + } } - _ => fail!("get_vtable: expected a static origin") - } } } -pub fn make_vtable(ccx: @CrateContext, ptrs: ~[ValueRef]) -> ValueRef { +/// Helper function to declare and initialize the vtable. +pub fn make_vtable(ccx: @CrateContext, + tydesc: @mut tydesc_info, + ptrs: &[ValueRef]) + -> ValueRef { unsafe { let _icx = ccx.insn_ctxt("impl::make_vtable"); - let tbl = C_struct(ptrs); + + let mut components = ~[ tydesc.tydesc ]; + for ptrs.each |&ptr| { + components.push(ptr) + } + + let tbl = C_struct(components); let vtable = ccx.sess.str_of((ccx.names)("vtable")); let vt_gvar = do str::as_c_str(*vtable) |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf) @@ -787,11 +809,13 @@ pub fn make_vtable(ccx: @CrateContext, ptrs: ~[ValueRef]) -> ValueRef { } } +/// Generates a dynamic vtable for objects. pub fn make_impl_vtable(ccx: @CrateContext, impl_id: ast::def_id, + self_ty: ty::t, substs: ~[ty::t], vtables: typeck::vtable_res) - -> ValueRef { + -> ValueRef { let _icx = ccx.insn_ctxt("impl::make_impl_vtable"); let tcx = ccx.tcx; @@ -800,9 +824,13 @@ pub fn make_impl_vtable(ccx: @CrateContext, let has_tps = !ty::lookup_item_type(ccx.tcx, impl_id).generics.type_param_defs.is_empty(); - make_vtable(ccx, ty::trait_method_def_ids(tcx, trt_id).map(|method_def_id| { + + let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id); + let methods = do trait_method_def_ids.map |method_def_id| { let im = ty::method(tcx, *method_def_id); - let fty = ty::subst_tps(tcx, substs, None, + let fty = ty::subst_tps(tcx, + substs, + None, ty::mk_bare_fn(tcx, copy im.fty)); if im.generics.has_type_params() || ty::type_has_self(fty) { debug!("(making impl vtable) method has self or type params: %s", @@ -828,7 +856,13 @@ pub fn make_impl_vtable(ccx: @CrateContext, trans_external_path(ccx, m_id, fty) } } - })) + }; + + // Generate a type descriptor for the vtable. + let tydesc = get_tydesc(ccx, self_ty); + glue::lazily_emit_all_tydesc_glue(ccx, tydesc); + + make_vtable(ccx, tydesc, methods) } pub fn trans_trait_cast(bcx: block, @@ -850,40 +884,19 @@ pub fn trans_trait_cast(bcx: block, let ccx = bcx.ccx(); let v_ty = expr_ty(bcx, val); - match store { - ty::RegionTraitStore(_) | ty::BoxTraitStore => { - let mut llboxdest = GEPi(bcx, lldest, [0u, abi::trt_field_box]); - // Just store the pointer into the pair. (Region/borrowed - // and boxed trait objects are represented as pairs, and - // have no type descriptor field.) - llboxdest = PointerCast(bcx, - llboxdest, - T_ptr(type_of(bcx.ccx(), v_ty))); - bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); - } - ty::UniqTraitStore => { - // Translate the uniquely-owned value in the - // triple. (Unique trait objects are represented as - // triples.) - let mut llvaldest = GEPi(bcx, lldest, [0, abi::trt_field_box]); - llvaldest = PointerCast(bcx, - llvaldest, - T_ptr(type_of(bcx.ccx(), v_ty))); - bcx = expr::trans_into(bcx, val, SaveIn(llvaldest)); - - // Get the type descriptor of the wrapped value and store - // it in the triple as well. - let tydesc = get_tydesc(bcx.ccx(), v_ty); - glue::lazily_emit_all_tydesc_glue(bcx.ccx(), tydesc); - let lltydescdest = GEPi(bcx, lldest, [0, abi::trt_field_tydesc]); - Store(bcx, tydesc.tydesc, lltydescdest); - } - } + let mut llboxdest = GEPi(bcx, lldest, [0u, abi::trt_field_box]); + // Just store the pointer into the pair. (Region/borrowed + // and boxed trait objects are represented as pairs, and + // have no type descriptor field.) + llboxdest = PointerCast(bcx, + llboxdest, + T_ptr(type_of(bcx.ccx(), v_ty))); + bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); // Store the vtable into the pair or triple. let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0]; let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig); - let vtable = get_vtable(bcx.ccx(), orig); + let vtable = get_vtable(bcx.ccx(), v_ty, orig); Store(bcx, vtable, PointerCast(bcx, GEPi(bcx, lldest, [0u, abi::trt_field_vtable]), T_ptr(val_ty(vtable)))); diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 18f21b489b0b8..78e55837cc36d 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -23,7 +23,6 @@ use middle::trans::common::*; use middle::trans::datum::*; use middle::trans::expr; use middle::ty; -use driver::session; use syntax::codemap::span; use syntax::ast; @@ -74,7 +73,7 @@ pub fn return_to_mut(mut bcx: block, let bits_val = Load(bcx, bits_val_ref); - if bcx.tcx().sess.opts.optimize == session::No { + if bcx.tcx().sess.debug_borrows() { bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.unrecord_borrow_fn(), @@ -160,7 +159,7 @@ fn root(datum: &Datum, ], expr::SaveIn(scratch_bits.val)); - if bcx.tcx().sess.opts.optimize == session::No { + if bcx.tcx().sess.debug_borrows() { bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.record_borrow_fn(), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e85c7d00c58e0..60dd30a07a0d1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1760,6 +1760,15 @@ pub fn type_is_unique(ty: t) -> bool { } } +pub fn type_is_castable(ty: t) -> bool { + match get(ty).sty { + ty_nil | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) | + ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | ty_type | + ty_ptr(_) => true, + _ => false + } +} + /* A scalar type is one that denotes an atomic datum, with no sub-components. (A ty_ptr is scalar because it represents a non-managed pointer, so its diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 548b9e454ce95..5ca0b39acea13 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2639,9 +2639,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, }, t_e, None); } - let t_1_is_scalar = type_is_scalar(fcx, expr.span, t_1); + let t_1_is_castable = type_is_castable(fcx, + expr.span, + t_1); if type_is_c_like_enum(fcx,expr.span,t_e) - && t_1_is_scalar { + && t_1_is_castable { /* this case is allowed */ } else if type_is_region_ptr(fcx, expr.span, t_e) && type_is_unsafe_ptr(fcx, expr.span, t_1) { @@ -2684,8 +2686,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, demand::coerce(fcx, e.span, t_1, e); } } - } else if !(type_is_scalar(fcx,expr.span,t_e) - && t_1_is_scalar) { + } else if !(type_is_castable(fcx,expr.span,t_e) + && t_1_is_castable) { /* If more type combinations should be supported than are supported here, then file an enhancement issue and @@ -3208,21 +3210,6 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, let typ = fcx.local_ty(sp, nid); return no_params(typ); } - ast::def_fn(_, ast::extern_fn) => { - // extern functions are just u8 pointers - return ty_param_bounds_and_ty { - generics: ty::Generics { - type_param_defs: @~[], - region_param: None - }, - ty: ty::mk_ptr( - fcx.ccx.tcx, - ty::mt { - ty: ty::mk_mach_uint(ast::ty_u8), - mutbl: ast::m_imm - }) - }; - } ast::def_fn(id, ast::unsafe_fn) | ast::def_static_method(id, _, ast::unsafe_fn) => { @@ -3242,7 +3229,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) | - ast::def_ty_param(*)=> { + ast::def_ty_param(*) => { fcx.ccx.tcx.sess.span_bug(sp, "expected value but found type"); } ast::def_mod(*) | ast::def_foreign_mod(*) => { @@ -3354,6 +3341,11 @@ pub fn type_is_integral(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> bool { return ty::type_is_integral(typ_s); } +pub fn type_is_castable(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> bool { + let typ_s = structurally_resolved_type(fcx, sp, typ); + return ty::type_is_castable(typ_s); +} + pub fn type_is_scalar(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> bool { let typ_s = structurally_resolved_type(fcx, sp, typ); return ty::type_is_scalar(typ_s); diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index c64a0235eb1f0..ba458179cdcce 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -996,7 +996,7 @@ pub impl CoherenceChecker { def_id { crate: crate_number, node: 0 }); - for each_path(crate_store, crate_number) |_p, def_like| { + for each_path(crate_store, crate_number) |_, def_like, _| { match def_like { dl_def(def_mod(def_id)) => { self.add_impls_for_module(&mut impls_seen, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 4773e637c3521..c67a253db7129 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1065,10 +1065,14 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item) ast::item_fn(ref decl, purity, _, ref generics, _) => { assert!(rp.is_none()); let ty_generics = ty_generics(ccx, None, generics, 0); + let abi = match purity { + ast::extern_fn => AbiSet::C(), + _ => AbiSet::Rust(), + }; let tofd = astconv::ty_of_bare_fn(ccx, &empty_rscope, purity, - AbiSet::Rust(), + abi, &generics.lifetimes, decl); let tpt = ty_param_bounds_and_ty { diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index a69613776efdc..c0fe5e6ed222e 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -602,7 +602,6 @@ impl PkgSrc { /// Infers crates to build. Called only in the case where there /// is no custom build logic fn find_crates(&mut self) { - use PkgSrc::push_crate; use conditions::missing_pkg_files::cond; let dir = self.check_dir(); @@ -610,14 +609,18 @@ impl PkgSrc { debug!("Matching against %?", self.id.local_path.filestem()); for os::walk_dir(&dir) |pth| { match pth.filename() { - Some(~"lib.rs") => push_crate(&mut self.libs, - prefix, pth), - Some(~"main.rs") => push_crate(&mut self.mains, - prefix, pth), - Some(~"test.rs") => push_crate(&mut self.tests, - prefix, pth), - Some(~"bench.rs") => push_crate(&mut self.benchs, - prefix, pth), + Some(~"lib.rs") => PkgSrc::push_crate(&mut self.libs, + prefix, + pth), + Some(~"main.rs") => PkgSrc::push_crate(&mut self.mains, + prefix, + pth), + Some(~"test.rs") => PkgSrc::push_crate(&mut self.tests, + prefix, + pth), + Some(~"bench.rs") => PkgSrc::push_crate(&mut self.benchs, + prefix, + pth), _ => () } } diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 37578e42baff4..ec684c4d977c9 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -1408,7 +1408,8 @@ extern fn tcp_connect_on_connect_cb(connect_req_ptr: *uv::ll::uv_connect_t, result_ch.send(ConnFailure(err_data)); uv::ll::set_data_for_uv_handle(tcp_stream_ptr, conn_data_ptr); - uv::ll::close(tcp_stream_ptr, stream_error_close_cb); + uv::ll::close(tcp_stream_ptr as *uv::ll::uv_tcp_t, + stream_error_close_cb); } } debug!("leaving tcp_connect_on_connect_cb"); diff --git a/src/libstd/rl.rs b/src/libstd/rl.rs index d15a8fc0136d4..d94fdc91fb36b 100644 --- a/src/libstd/rl.rs +++ b/src/libstd/rl.rs @@ -22,8 +22,13 @@ pub mod rustrt { pub unsafe fn linenoiseHistorySetMaxLen(len: c_int) -> c_int; pub unsafe fn linenoiseHistorySave(file: *c_char) -> c_int; pub unsafe fn linenoiseHistoryLoad(file: *c_char) -> c_int; - pub unsafe fn linenoiseSetCompletionCallback(callback: *u8); pub unsafe fn linenoiseAddCompletion(completions: *(), line: *c_char); + + #[cfg(stage0)] + pub unsafe fn linenoiseSetCompletionCallback(callback: *u8); + #[cfg(not(stage0))] + pub unsafe fn linenoiseSetCompletionCallback( + callback: extern "C" fn(a: *i8, b: *())); } } diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index 2922f403f34a6..b8f214c488fa4 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -175,7 +175,7 @@ fn begin_teardown(data: *IoTaskLoopData) { unsafe { debug!("iotask begin_teardown() called, close async_handle"); let async_handle = (*data).async_handle; - ll::close(async_handle as *c_void, tear_down_close_cb); + ll::close(async_handle as *ll::uv_async_t, tear_down_close_cb); } } extern fn tear_down_walk_cb(handle: *libc::c_void, arg: *libc::c_void) { diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index 37052f7d1b7fa..ee00de4259072 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -735,9 +735,21 @@ extern { unsafe fn rust_uv_loop_new() -> *libc::c_void; unsafe fn rust_uv_loop_delete(lp: *libc::c_void); unsafe fn rust_uv_run(loop_handle: *libc::c_void); + + #[cfg(stage0)] unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8); + #[cfg(not(stage0))] + unsafe fn rust_uv_close(handle: *libc::c_void, + cb: extern "C" fn(a: *c_void)); + + #[cfg(stage0)] unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void); + #[cfg(not(stage0))] + unsafe fn rust_uv_walk(loop_handle: *libc::c_void, + cb: extern "C" fn(a: *libc::c_void, + b: *libc::c_void), + arg: *libc::c_void); unsafe fn rust_uv_idle_new() -> *uv_idle_t; unsafe fn rust_uv_idle_delete(handle: *uv_idle_t); @@ -748,9 +760,18 @@ extern { unsafe fn rust_uv_idle_stop(handle: *uv_idle_t) -> libc::c_int; unsafe fn rust_uv_async_send(handle: *uv_async_t); + + #[cfg(stage0)] unsafe fn rust_uv_async_init(loop_handle: *libc::c_void, - async_handle: *uv_async_t, - cb: *u8) -> libc::c_int; + async_handle: *uv_async_t, + cb: *u8) + -> libc::c_int; + #[cfg(not(stage0))] + unsafe fn rust_uv_async_init(loop_handle: *libc::c_void, + async_handle: *uv_async_t, + cb: extern "C" fn(a: *uv_async_t, b: int)) + -> libc::c_int; + unsafe fn rust_uv_tcp_init( loop_handle: *libc::c_void, handle_ptr: *uv_tcp_t) -> libc::c_int; @@ -776,53 +797,114 @@ extern { -> libc::c_int; unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; + // FIXME ref #2064 + #[cfg(stage0)] unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, after_cb: *u8, addr: *sockaddr_in) -> libc::c_int; + + // FIXME ref #2064 + #[cfg(not(stage0))] + unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + after_cb: extern "C" fn(a: *uv_connect_t, + b: i32), + addr: *sockaddr_in) + -> libc::c_int; + // FIXME ref #2064 unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> libc::c_int; + // FIXME ref #2064 + #[cfg(stage0)] unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, after_cb: *u8, addr: *sockaddr_in6) -> libc::c_int; // FIXME ref #2064 + #[cfg(not(stage0))] + unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + after_cb: extern "C" fn(a: *uv_connect_t, + b: i32), + addr: *sockaddr_in6) + -> libc::c_int; + + // FIXME ref #2064 unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> libc::c_int; unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in) -> libc::c_int; unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) ->libc::c_int; + + #[cfg(stage0)] unsafe fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int, cb: *u8) -> libc::c_int; + #[cfg(not(stage0))] + unsafe fn rust_uv_listen(stream: *libc::c_void, + backlog: libc::c_int, + cb: extern "C" fn(a: *uv_tcp_t, b: i32)) + -> libc::c_int; + unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) -> libc::c_int; + + #[cfg(stage0)] unsafe fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void, buf_in: *uv_buf_t, buf_cnt: libc::c_int, cb: *u8) -> libc::c_int; + #[cfg(not(stage0))] + unsafe fn rust_uv_write(req: *libc::c_void, + stream: *libc::c_void, + buf_in: *uv_buf_t, + buf_cnt: libc::c_int, + cb: extern "C" fn(*uv_write_t, i32)) + -> libc::c_int; + + #[cfg(stage0)] unsafe fn rust_uv_read_start(stream: *libc::c_void, on_alloc: *u8, on_read: *u8) -> libc::c_int; + #[cfg(not(stage0))] + unsafe fn rust_uv_read_start(stream: *libc::c_void, + on_alloc: extern "C" fn(a: *c_void, b: u64) + -> uv_buf_t, + on_read: extern "C" fn(a: *uv_stream_t, + b: i64, + c: uv_buf_t)) + -> libc::c_int; + unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int; unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void, timer_handle: *uv_timer_t) -> libc::c_int; + + #[cfg(stage0)] unsafe fn rust_uv_timer_start( timer_handle: *uv_timer_t, cb: *u8, timeout: libc::c_uint, repeat: libc::c_uint) -> libc::c_int; + #[cfg(not(stage0))] + unsafe fn rust_uv_timer_start( + timer_handle: *uv_timer_t, + cb: extern "C" fn(a: *uv_timer_t, b: i32), + timeout: libc::c_uint, + repeat: libc::c_uint) -> libc::c_int; + unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int; + #[cfg(stage0)] unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, handle: *uv_getaddrinfo_t, cb: *u8, @@ -830,7 +912,21 @@ extern { service_name_ptr: *u8, // should probably only pass ptr::null() hints: *addrinfo) - -> libc::c_int; + -> libc::c_int; + + #[cfg(not(stage0))] + unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, + handle: *uv_getaddrinfo_t, + cb: extern "C" fn( + a: *uv_getaddrinfo_t, + b: i32, + c: *addrinfo_impl::addrinfo), + node_name_ptr: *u8, + service_name_ptr: *u8, + // should probably only pass ptr::null() + hints: *addrinfo) + -> libc::c_int; + unsafe fn rust_uv_freeaddrinfo(res: *addrinfo); // data accessors/helpers for rust-mapped uv structs @@ -894,14 +990,28 @@ pub unsafe fn run(loop_handle: *libc::c_void) { rust_uv_run(loop_handle); } +#[cfg(stage0)] pub unsafe fn close(handle: *T, cb: *u8) { rust_uv_close(handle as *libc::c_void, cb); } +#[cfg(not(stage0))] +pub unsafe fn close(handle: *T, cb: extern "C" fn(a: *T)) { + rust_uv_close(handle as *libc::c_void, ::core::cast::transmute(cb)); +} + +#[cfg(stage0)] pub unsafe fn walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void) { rust_uv_walk(loop_handle, cb, arg); } +#[cfg(not(stage0))] +pub unsafe fn walk(loop_handle: *libc::c_void, + cb: extern "C" fn(a: *c_void, b: *c_void), + arg: *libc::c_void) { + rust_uv_walk(loop_handle, cb, arg); +} + pub unsafe fn idle_new() -> *uv_idle_t { rust_uv_idle_new() } @@ -927,16 +1037,36 @@ pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t) -> libc::c_int { return rust_uv_tcp_init(loop_handle, handle); } + // FIXME ref #2064 +#[cfg(stage0)] pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, - tcp_handle_ptr: *uv_tcp_t, - addr_ptr: *sockaddr_in, - after_connect_cb: *u8) --> libc::c_int { - return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, - after_connect_cb, addr_ptr); + tcp_handle_ptr: *uv_tcp_t, + addr_ptr: *sockaddr_in, + after_connect_cb: *u8) + -> libc::c_int { + return rust_uv_tcp_connect(connect_ptr, + tcp_handle_ptr, + after_connect_cb, + addr_ptr); +} + +// FIXME ref #2064 +#[cfg(not(stage0))] +pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + addr_ptr: *sockaddr_in, + after_connect_cb: extern "C" fn(a: *uv_connect_t, + b: i32)) + -> libc::c_int { + return rust_uv_tcp_connect(connect_ptr, + tcp_handle_ptr, + after_connect_cb, + addr_ptr); } + // FIXME ref #2064 +#[cfg(stage0)] pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6, @@ -945,6 +1075,21 @@ pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr); } + +// FIXME ref #2064 +#[cfg(not(stage0))] +pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + addr_ptr: *sockaddr_in6, + after_connect_cb: extern "C" fn(a: *uv_connect_t, + b: i32)) + -> libc::c_int { + return rust_uv_tcp_connect6(connect_ptr, + tcp_handle_ptr, + after_connect_cb, + addr_ptr); +} + // FIXME ref #2064 pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> libc::c_int { @@ -968,30 +1113,64 @@ pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, return rust_uv_tcp_getpeername6(tcp_handle_ptr, name); } +#[cfg(stage0)] pub unsafe fn listen(stream: *T, backlog: libc::c_int, cb: *u8) -> libc::c_int { return rust_uv_listen(stream as *libc::c_void, backlog, cb); } +#[cfg(not(stage0))] +pub unsafe fn listen(stream: *T, backlog: libc::c_int, + cb: extern "C" fn(a: *uv_tcp_t, b: i32)) -> libc::c_int { + return rust_uv_listen(stream as *libc::c_void, backlog, cb); +} + pub unsafe fn accept(server: *libc::c_void, client: *libc::c_void) -> libc::c_int { return rust_uv_accept(server as *libc::c_void, client as *libc::c_void); } -pub unsafe fn write(req: *uv_write_t, stream: *T, - buf_in: *~[uv_buf_t], cb: *u8) -> libc::c_int { +#[cfg(stage0)] +pub unsafe fn write(req: *uv_write_t, + stream: *T, + buf_in: *~[uv_buf_t], + cb: *u8) -> libc::c_int { let buf_ptr = vec::raw::to_ptr(*buf_in); let buf_cnt = vec::len(*buf_in) as i32; return rust_uv_write(req as *libc::c_void, stream as *libc::c_void, buf_ptr, buf_cnt, cb); } +#[cfg(not(stage0))] +pub unsafe fn write(req: *uv_write_t, + stream: *T, + buf_in: *~[uv_buf_t], + cb: extern "C" fn(*uv_write_t, i32)) -> libc::c_int { + let buf_ptr = vec::raw::to_ptr(*buf_in); + let buf_cnt = vec::len(*buf_in) as i32; + return rust_uv_write(req as *libc::c_void, + stream as *libc::c_void, + buf_ptr, buf_cnt, cb); +} + +#[cfg(stage0)] pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> libc::c_int { return rust_uv_read_start(stream as *libc::c_void, on_alloc, on_read); } +#[cfg(not(stage0))] +pub unsafe fn read_start(stream: *uv_stream_t, + on_alloc: extern "C" fn(a: *c_void, b: u64) + -> uv_buf_t, + on_read: extern "C" fn(a: *uv_stream_t, + b: i64, + c: uv_buf_t)) + -> libc::c_int { + return rust_uv_read_start(stream as *libc::c_void, + on_alloc, on_read); +} pub unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int { return rust_uv_read_stop(stream as *libc::c_void); @@ -1008,12 +1187,23 @@ pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char { return rust_uv_err_name(err); } +#[cfg(stage0)] +pub unsafe fn async_init(loop_handle: *libc::c_void, + async_handle: *uv_async_t, + cb: *u8) + -> libc::c_int { + return rust_uv_async_init(loop_handle, + async_handle, + cb); +} +#[cfg(not(stage0))] pub unsafe fn async_init(loop_handle: *libc::c_void, - async_handle: *uv_async_t, - cb: *u8) -> libc::c_int { + async_handle: *uv_async_t, + cb: extern "C" fn(a: *uv_async_t, b: int)) + -> libc::c_int { return rust_uv_async_init(loop_handle, - async_handle, - cb); + async_handle, + cb); } pub unsafe fn async_send(async_handle: *uv_async_t) { @@ -1082,27 +1272,60 @@ pub unsafe fn timer_init(loop_ptr: *libc::c_void, timer_ptr: *uv_timer_t) -> libc::c_int { return rust_uv_timer_init(loop_ptr, timer_ptr); } + +#[cfg(stage0)] pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint, repeat: uint) -> libc::c_int { return rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint, repeat as libc::c_uint); } +#[cfg(not(stage0))] +pub unsafe fn timer_start(timer_ptr: *uv_timer_t, + cb: extern "C" fn(a: *uv_timer_t, b: i32), + timeout: uint, + repeat: uint) -> libc::c_int { + return rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint, + repeat as libc::c_uint); +} + pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int { return rust_uv_timer_stop(timer_ptr); } + +#[cfg(stage0)] +pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void, + handle: *uv_getaddrinfo_t, + cb: *u8, + node_name_ptr: *u8, + service_name_ptr: *u8, + hints: *addrinfo) + -> libc::c_int { + rust_uv_getaddrinfo(loop_ptr, + handle, + cb, + node_name_ptr, + service_name_ptr, + hints) +} + +#[cfg(not(stage0))] pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void, - handle: *uv_getaddrinfo_t, - cb: *u8, - node_name_ptr: *u8, - service_name_ptr: *u8, - hints: *addrinfo) -> libc::c_int { + handle: *uv_getaddrinfo_t, + cb: extern "C" fn(*uv_getaddrinfo_t, + i32, + *addrinfo), + node_name_ptr: *u8, + service_name_ptr: *u8, + hints: *addrinfo) + -> libc::c_int { rust_uv_getaddrinfo(loop_ptr, - handle, - cb, - node_name_ptr, - service_name_ptr, - hints) + handle, + cb, + node_name_ptr, + service_name_ptr, + hints) } + pub unsafe fn freeaddrinfo(res: *addrinfo) { rust_uv_freeaddrinfo(res); } diff --git a/src/test/auxiliary/extern-crosscrate-source.rs b/src/test/auxiliary/extern-crosscrate-source.rs index d59057f01f2de..c7e8e89913595 100644 --- a/src/test/auxiliary/extern-crosscrate-source.rs +++ b/src/test/auxiliary/extern-crosscrate-source.rs @@ -15,8 +15,10 @@ pub mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) - -> libc::uintptr_t; + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; } } diff --git a/src/test/auxiliary/private_variant_xc.rs b/src/test/auxiliary/private_variant_xc.rs new file mode 100644 index 0000000000000..d7d55c691b683 --- /dev/null +++ b/src/test/auxiliary/private_variant_xc.rs @@ -0,0 +1,5 @@ +pub enum Foo { + pub Bar, + priv Baz, +} + diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs new file mode 100644 index 0000000000000..2ab95c271aec7 --- /dev/null +++ b/src/test/auxiliary/use_from_trait_xc.rs @@ -0,0 +1,10 @@ +pub trait Trait { + fn foo(); +} + +struct Foo; + +impl Foo { + pub fn new() {} +} + diff --git a/src/test/compile-fail/private-variant-xc.rs b/src/test/compile-fail/private-variant-xc.rs new file mode 100644 index 0000000000000..c7838b9885508 --- /dev/null +++ b/src/test/compile-fail/private-variant-xc.rs @@ -0,0 +1,9 @@ +// aux-build:private_variant_xc.rs + +extern mod private_variant_xc; + +pub fn main() { + let _ = private_variant_xc::Bar; + let _ = private_variant_xc::Baz; //~ ERROR unresolved name +} + diff --git a/src/test/compile-fail/use-from-trait-xc.rs b/src/test/compile-fail/use-from-trait-xc.rs new file mode 100644 index 0000000000000..56805f58ad29a --- /dev/null +++ b/src/test/compile-fail/use-from-trait-xc.rs @@ -0,0 +1,12 @@ +// aux-build:use_from_trait_xc.rs + +extern mod use_from_trait_xc; + +use use_from_trait_xc::Trait::foo; //~ ERROR cannot import from a trait or type implementation +//~^ ERROR failed to resolve import +use use_from_trait_xc::Foo::new; //~ ERROR cannot import from a trait or type implementation +//~^ ERROR failed to resolve import + +fn main() { +} + diff --git a/src/test/compile-fail/use-from-trait.rs b/src/test/compile-fail/use-from-trait.rs new file mode 100644 index 0000000000000..10a30f0a266b3 --- /dev/null +++ b/src/test/compile-fail/use-from-trait.rs @@ -0,0 +1,17 @@ +use Trait::foo; //~ ERROR cannot import from a trait or type implementation +//~^ ERROR failed to resolve import +use Foo::new; //~ ERROR cannot import from a trait or type implementation +//~^ ERROR failed to resolve import + +pub trait Trait { + fn foo(); +} + +struct Foo; + +impl Foo { + fn new() {} +} + +fn main() {} + diff --git a/src/test/run-pass/const-cast.rs b/src/test/run-pass/const-cast.rs index d35ad9d2da3e1..2c127917343be 100644 --- a/src/test/run-pass/const-cast.rs +++ b/src/test/run-pass/const-cast.rs @@ -10,7 +10,7 @@ extern fn foo() {} -static x: *u8 = foo; +static x: extern "C" fn() = foo; static y: *libc::c_void = x as *libc::c_void; static a: &'static int = &10; static b: *int = a as *int; diff --git a/src/test/run-pass/const-cross-crate-extern.rs b/src/test/run-pass/const-cross-crate-extern.rs index bac84d12e4ce1..7016f034455ef 100644 --- a/src/test/run-pass/const-cross-crate-extern.rs +++ b/src/test/run-pass/const-cross-crate-extern.rs @@ -13,7 +13,7 @@ extern mod cci_const; use cci_const::bar; -static foo: *u8 = bar; +static foo: extern "C" fn() = bar; pub fn main() { assert!(foo == cci_const::bar); diff --git a/src/test/run-pass/const-extern-function.rs b/src/test/run-pass/const-extern-function.rs index a9d036f121921..f45a63ad83f24 100644 --- a/src/test/run-pass/const-extern-function.rs +++ b/src/test/run-pass/const-extern-function.rs @@ -10,7 +10,7 @@ extern fn foopy() {} -static f: *u8 = foopy; +static f: extern "C" fn() = foopy; static s: S = S { f: foopy }; struct S { diff --git a/src/test/run-pass/extern-call-deep.rs b/src/test/run-pass/extern-call-deep.rs index c29eb2613ad21..edd229aaf80bc 100644 --- a/src/test/run-pass/extern-call-deep.rs +++ b/src/test/run-pass/extern-call-deep.rs @@ -10,8 +10,10 @@ mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) - -> libc::uintptr_t; + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; } } diff --git a/src/test/run-pass/extern-call-deep2.rs b/src/test/run-pass/extern-call-deep2.rs index 4e807f0f169ec..579ae2b72a438 100644 --- a/src/test/run-pass/extern-call-deep2.rs +++ b/src/test/run-pass/extern-call-deep2.rs @@ -10,8 +10,10 @@ mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) - -> libc::uintptr_t; + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; } } diff --git a/src/test/run-pass/extern-call-scrub.rs b/src/test/run-pass/extern-call-scrub.rs index eafdd3c5e9946..cce56cd49e82d 100644 --- a/src/test/run-pass/extern-call-scrub.rs +++ b/src/test/run-pass/extern-call-scrub.rs @@ -14,8 +14,10 @@ mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) - -> libc::uintptr_t; + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; } } diff --git a/src/test/run-pass/extern-call.rs b/src/test/run-pass/extern-call.rs index 37e531eaa8e60..a305c5c427d99 100644 --- a/src/test/run-pass/extern-call.rs +++ b/src/test/run-pass/extern-call.rs @@ -10,7 +10,9 @@ mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) -> libc::uintptr_t; } } diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs index 0b640c8c62360..5b71bb42f7422 100644 --- a/src/test/run-pass/extern-stress.rs +++ b/src/test/run-pass/extern-stress.rs @@ -13,8 +13,10 @@ mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) - -> libc::uintptr_t; + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; } } diff --git a/src/test/run-pass/extern-take-value.rs b/src/test/run-pass/extern-take-value.rs index c3815cf2a67f6..f850ff0ddb598 100644 --- a/src/test/run-pass/extern-take-value.rs +++ b/src/test/run-pass/extern-take-value.rs @@ -15,10 +15,10 @@ extern fn g() { } pub fn main() { - // extern functions are *u8 types - let a: *u8 = f; - let b: *u8 = f; - let c: *u8 = g; + // extern functions are extern function types + let a: extern "C" fn() = f; + let b: extern "C" fn() = f; + let c: extern "C" fn() = g; assert!(a == b); assert!(a != c); diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs index bde3f5dd52ff6..436bf2a3d3821 100644 --- a/src/test/run-pass/extern-yield.rs +++ b/src/test/run-pass/extern-yield.rs @@ -10,8 +10,10 @@ mod rustrt { pub extern { - pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) - -> libc::uintptr_t; + pub fn rust_dbg_call(cb: extern "C" fn(data: libc::uintptr_t) + -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; } } diff --git a/src/test/run-pass/float-nan.rs b/src/test/run-pass/float-nan.rs index 08523de3ccd81..9bbb253ccce8f 100644 --- a/src/test/run-pass/float-nan.rs +++ b/src/test/run-pass/float-nan.rs @@ -10,16 +10,14 @@ extern mod std; -use core::num::Float::{ - NaN, infinity, neg_infinity -}; +use core::num::Float; pub fn main() { - let nan = NaN::(); + let nan = Float::NaN::(); assert!((nan).is_NaN()); - let inf = infinity::(); - assert!(-inf == neg_infinity::()); + let inf = Float::infinity::(); + assert!(-inf == Float::neg_infinity::()); assert!( nan != nan); assert!( nan != -nan); diff --git a/src/test/run-pass/foreign-call-no-runtime.rs b/src/test/run-pass/foreign-call-no-runtime.rs index 08cb8db5131ff..207030d9a8a9d 100644 --- a/src/test/run-pass/foreign-call-no-runtime.rs +++ b/src/test/run-pass/foreign-call-no-runtime.rs @@ -1,7 +1,8 @@ use core::unstable::run_in_bare_thread; extern { - pub fn rust_dbg_call(cb: *u8, + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) + -> libc::uintptr_t, data: libc::uintptr_t) -> libc::uintptr_t; } diff --git a/src/test/run-pass/static-method-xcrate.rs b/src/test/run-pass/static-method-xcrate.rs index aa4f65669ad90..462ba64b74042 100644 --- a/src/test/run-pass/static-method-xcrate.rs +++ b/src/test/run-pass/static-method-xcrate.rs @@ -13,11 +13,10 @@ extern mod static_methods_crate; use static_methods_crate::read; -use readMaybeRenamed = static_methods_crate::read::readMaybe; pub fn main() { let result: int = read(~"5"); assert!(result == 5); - assert!(readMaybeRenamed(~"false") == Some(false)); - assert!(readMaybeRenamed(~"foo") == None::); + assert!(read::readMaybe(~"false") == Some(false)); + assert!(read::readMaybe(~"foo") == None::); } diff --git a/src/test/run-pass/trait-inheritance-num.rs b/src/test/run-pass/trait-inheritance-num.rs index 5179d13813cea..9135b458f95eb 100644 --- a/src/test/run-pass/trait-inheritance-num.rs +++ b/src/test/run-pass/trait-inheritance-num.rs @@ -13,13 +13,13 @@ extern mod std; use core::cmp::{Eq, Ord}; -use core::num::NumCast::from; +use core::num::NumCast; pub trait NumExt: Num + NumCast + Eq + Ord {} pub trait FloatExt: NumExt + ApproxEq {} -fn greater_than_one(n: &T) -> bool { *n > from(1) } -fn greater_than_one_float(n: &T) -> bool { *n > from(1) } +fn greater_than_one(n: &T) -> bool { *n > NumCast::from(1) } +fn greater_than_one_float(n: &T) -> bool { *n > NumCast::from(1) } pub fn main() {} diff --git a/src/test/run-pass/trait-inheritance-num0.rs b/src/test/run-pass/trait-inheritance-num0.rs index aae430dc4cdf9..3e31b8067f9c3 100644 --- a/src/test/run-pass/trait-inheritance-num0.rs +++ b/src/test/run-pass/trait-inheritance-num0.rs @@ -12,7 +12,7 @@ // Extending Num and using inherited static methods -use core::num::NumCast::from; +use core::num::NumCast; trait Num { fn from_int(i: int) -> Self; @@ -22,7 +22,7 @@ trait Num { pub trait NumExt: Num + NumCast { } fn greater_than_one(n: &T) -> bool { - n.gt(&from(1)) + n.gt(&NumCast::from(1)) } pub fn main() {} diff --git a/src/test/run-pass/trait-inheritance-num1.rs b/src/test/run-pass/trait-inheritance-num1.rs index d580b99012fa5..25741518f66eb 100644 --- a/src/test/run-pass/trait-inheritance-num1.rs +++ b/src/test/run-pass/trait-inheritance-num1.rs @@ -9,12 +9,12 @@ // except according to those terms. use core::cmp::Ord; -use core::num::NumCast::from; +use core::num::NumCast; pub trait NumExt: Num + NumCast + Ord { } fn greater_than_one(n: &T) -> bool { - *n > from(1) + *n > NumCast::from(1) } pub fn main() {} diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index f7edd2855a4cd..2963a815e0519 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -15,7 +15,6 @@ extern mod std; use core::cmp::{Eq, Ord}; -use core::num::NumCast::from; pub trait TypeExt {} diff --git a/src/test/run-pass/trait-inheritance-num3.rs b/src/test/run-pass/trait-inheritance-num3.rs index 5f1fef80ef201..667fd335ac4a4 100644 --- a/src/test/run-pass/trait-inheritance-num3.rs +++ b/src/test/run-pass/trait-inheritance-num3.rs @@ -9,13 +9,15 @@ // except according to those terms. use core::cmp::{Eq, Ord}; -use core::num::NumCast::from; +use core::num::NumCast; pub trait NumExt: Eq + Ord + Num + NumCast {} impl NumExt for f32 {} -fn num_eq_one(n: T) { io::println(fmt!("%?", n == from(1))) } +fn num_eq_one(n: T) { + io::println(fmt!("%?", n == NumCast::from(1))) +} pub fn main() { num_eq_one(1f32); // you need to actually use the function to trigger the ICE diff --git a/src/test/run-pass/trait-inheritance-num5.rs b/src/test/run-pass/trait-inheritance-num5.rs index 02cc9a3d221f8..f1897636c8aa6 100644 --- a/src/test/run-pass/trait-inheritance-num5.rs +++ b/src/test/run-pass/trait-inheritance-num5.rs @@ -9,7 +9,7 @@ // except according to those terms. use core::cmp::{Eq, Ord}; -use core::num::NumCast::from; +use core::num::NumCast; pub trait NumExt: Eq + Num + NumCast {} @@ -17,7 +17,7 @@ impl NumExt for f32 {} impl NumExt for int {} fn num_eq_one() -> T { - from(1) + NumCast::from(1) } pub fn main() {