From ac83f4b7325eea6ec82db73fb5c1ece7d8320908 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 14 Jun 2013 16:58:55 -0700 Subject: [PATCH 01/96] std: add a fixme to note performance issues in vec::from_elem. --- src/libstd/vec.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 19233c533481..f6f5b98df67d 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -155,8 +155,10 @@ pub fn from_fn(n_elts: uint, op: old_iter::InitOp) -> ~[T] { * to the value `t`. */ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { - // hack: manually inline from_fn for 2x plus speedup (sadly very important, from_elem is a - // bottleneck in borrowck!) + // FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very + // important, from_elem is a bottleneck in borrowck!). Unfortunately it + // still is substantially slower than using the unsafe + // vec::with_capacity/ptr::set_memory for primitive types. unsafe { let mut v = with_capacity(n_elts); do as_mut_buf(v) |p, _len| { From 07f5ab10096718a296825b3b628081559d738810 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 14 Jun 2013 18:27:35 -0700 Subject: [PATCH 02/96] Implement a deriving(Zero) attribute --- src/libsyntax/ext/deriving/mod.rs | 2 + src/libsyntax/ext/deriving/zero.rs | 96 ++++++++++++++++++++++++++++++ src/test/run-pass/deriving-zero.rs | 40 +++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 src/libsyntax/ext/deriving/zero.rs create mode 100644 src/test/run-pass/deriving-zero.rs diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 606e372a25da..690690268011 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -32,6 +32,7 @@ pub mod encodable; pub mod decodable; pub mod rand; pub mod to_str; +pub mod zero; #[path="cmp/eq.rs"] pub mod eq; @@ -99,6 +100,7 @@ pub fn expand_meta_deriving(cx: @ExtCtxt, "Rand" => expand!(rand::expand_deriving_rand), "ToStr" => expand!(to_str::expand_deriving_to_str), + "Zero" => expand!(zero::expand_deriving_zero), ref tname => { cx.span_err(titem.span, fmt!("unknown \ diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs new file mode 100644 index 000000000000..121d8351ee47 --- /dev/null +++ b/src/libsyntax/ext/deriving/zero.rs @@ -0,0 +1,96 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use ast::{meta_item, item, expr}; +use codemap::span; +use ext::base::ExtCtxt; +use ext::build::AstBuilder; +use ext::deriving::generic::*; + +use core::vec; + +pub fn expand_deriving_zero(cx: @ExtCtxt, + span: span, + mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + let trait_def = TraitDef { + path: Path::new(~["std", "num", "Zero"]), + additional_bounds: ~[], + generics: LifetimeBounds::empty(), + methods: ~[ + MethodDef { + name: "zero", + generics: LifetimeBounds::empty(), + explicit_self: None, + args: ~[], + ret_ty: Self, + const_nonmatching: false, + combine_substructure: zero_substructure + }, + MethodDef { + name: "is_zero", + generics: LifetimeBounds::empty(), + explicit_self: borrowed_explicit_self(), + args: ~[], + ret_ty: Literal(Path::new(~["bool"])), + const_nonmatching: false, + combine_substructure: |cx, span, substr| { + cs_and(|cx, span, _, _| cx.span_bug(span, + "Non-matching enum \ + variant in \ + deriving(Zero)"), + cx, span, substr) + } + } + ] + }; + trait_def.expand(cx, span, mitem, in_items) +} + +fn zero_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { + let zero_ident = ~[ + cx.ident_of("std"), + cx.ident_of("num"), + cx.ident_of("Zero"), + cx.ident_of("zero") + ]; + let zero_call = || { + cx.expr_call_global(span, copy zero_ident, ~[]) + }; + + return match *substr.fields { + StaticStruct(_, ref summary) => { + match *summary { + Left(count) => { + if count == 0 { + cx.expr_ident(span, substr.type_ident) + } else { + let exprs = vec::from_fn(count, |_| zero_call()); + cx.expr_call_ident(span, substr.type_ident, exprs) + } + } + Right(ref fields) => { + let zero_fields = do fields.map |ident| { + cx.field_imm(span, *ident, zero_call()) + }; + cx.expr_struct_ident(span, substr.type_ident, zero_fields) + } + } + } + StaticEnum(*) => { + cx.span_fatal(span, "`Zero` cannot be derived for enums, \ + only structs") + } + _ => cx.bug("Non-static method in `deriving(Zero)`") + }; +} diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs new file mode 100644 index 000000000000..2ee57624112f --- /dev/null +++ b/src/test/run-pass/deriving-zero.rs @@ -0,0 +1,40 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::util; +use std::num::Zero; + +#[deriving(Zero)] +struct A; +#[deriving(Zero)] +struct B(int); +#[deriving(Zero)] +struct C(int, int); +#[deriving(Zero)] +struct D { a: int } +#[deriving(Zero)] +struct E { a: int, b: int } + +#[deriving(Zero)] +struct Lots { + a: ~str, + b: @str, + c: Option, + d: u8, + e: char, + f: float, + g: (f32, char), + h: ~[util::NonCopyable], + i: @mut (int, int), +} + +fn main() { + assert!(Zero::zero::().is_zero()); +} From 893c70d7bc670054ef646b71d4d503298cc50d76 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 14 Jun 2013 18:27:52 -0700 Subject: [PATCH 03/96] Add Zero impls for lots of common types --- src/libstd/char.rs | 10 ++++++++-- src/libstd/num/num.rs | 15 +++++++++++++++ src/libstd/option.rs | 5 +++++ src/libstd/str.rs | 11 +++++++++++ src/libstd/tuple.rs | 13 +++++++++++++ src/libstd/vec.rs | 11 +++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 073ced8988ad..7bfac2927c8d 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -17,8 +17,8 @@ use u32; use uint; use unicode::{derived_property, general_category}; -#[cfg(not(test))] -use cmp::{Eq, Ord}; +#[cfg(not(test))] use cmp::{Eq, Ord}; +#[cfg(not(test))] use num::Zero; /* Lu Uppercase_Letter an uppercase letter @@ -328,6 +328,12 @@ impl Ord for char { fn ge(&self, other: &char) -> bool { *self >= *other } } +#[cfg(not(test))] +impl Zero for char { + fn zero() -> char { 0 as char } + fn is_zero(&self) -> bool { *self == 0 as char } +} + #[test] fn test_is_lowercase() { assert!('a'.is_lowercase()); diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index a9893579721c..4681e4f4f53f 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -418,6 +418,21 @@ pub fn pow_with_uint+Mul>(radix: uint, pow total } +impl Zero for @mut T { + fn zero() -> @mut T { @mut Zero::zero() } + fn is_zero(&self) -> bool { (**self).is_zero() } +} + +impl Zero for @T { + fn zero() -> @T { @Zero::zero() } + fn is_zero(&self) -> bool { (**self).is_zero() } +} + +impl Zero for ~T { + fn zero() -> ~T { ~Zero::zero() } + fn is_zero(&self) -> bool { (**self).is_zero() } +} + /// Helper function for testing numeric operations #[cfg(test)] pub fn test_num(ten: T, two: T) { diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 80f4fb7643c8..762727064459 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -350,6 +350,11 @@ impl Option { } } +impl Zero for Option { + fn zero() -> Option { None } + fn is_zero(&self) -> bool { self.is_none() } +} + /// Immutable iterator over an `Option` pub struct OptionIterator<'self, A> { priv opt: Option<&'self A> diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 1086fcaa75cf..78ac0aae2f0b 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -28,6 +28,7 @@ use container::Container; use iter::Times; use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator}; use libc; +use num::Zero; use option::{None, Option, Some}; use old_iter::{BaseIter, EqIter}; use ptr; @@ -2250,6 +2251,16 @@ impl<'self> Iterator for StrBytesRevIterator<'self> { } } +impl Zero for ~str { + fn zero() -> ~str { ~"" } + fn is_zero(&self) -> bool { self.len() == 0 } +} + +impl Zero for @str { + fn zero() -> @str { @"" } + fn is_zero(&self) -> bool { self.len() == 0 } +} + #[cfg(test)] mod tests { use iterator::IteratorUtil; diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index 589c18de0abf..b80f152a5b1d 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -135,6 +135,7 @@ macro_rules! tuple_impls { pub mod inner { use clone::Clone; #[cfg(not(test))] use cmp::*; + #[cfg(not(test))] use num::Zero; $( pub trait $cloneable_trait<$($T),+> { @@ -210,6 +211,18 @@ macro_rules! tuple_impls { lexical_cmp!($(self.$get_ref_fn(), other.$get_ref_fn()),+) } } + + #[cfg(not(test))] + impl<$($T:Zero),+> Zero for ($($T),+) { + #[inline] + fn zero() -> ($($T),+) { + ($(Zero::zero::<$T>()),+) + } + #[inline] + fn is_zero(&self) -> bool { + $(self.$get_ref_fn().is_zero())&&+ + } + } )+ } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 19233c533481..b8f18ba47ca7 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -23,6 +23,7 @@ use iterator::{Iterator, IteratorUtil}; use iter::FromIter; use kinds::Copy; use libc; +use num::Zero; use old_iter::CopyableIter; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; @@ -2702,6 +2703,16 @@ impl Clone for ~[A] { } } +impl Zero for ~[A] { + fn zero() -> ~[A] { ~[] } + fn is_zero(&self) -> bool { self.len() == 0 } +} + +impl Zero for @[A] { + fn zero() -> @[A] { @[] } + fn is_zero(&self) -> bool { self.len() == 0 } +} + macro_rules! iterator { /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct. (struct $name:ident -> $ptr:ty, $elem:ty) => { From 5de67f9cc9674752bb6b9db6c2db790a19ec4e9c Mon Sep 17 00:00:00 2001 From: Steven Stewart-Gallus Date: Sat, 15 Jun 2013 00:43:19 -0700 Subject: [PATCH 04/96] Cleaned up driver.rs --- src/librustc/driver/driver.rs | 85 ++++++++++++++++------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 61254740dcda..f4e2a2dd2b88 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -65,34 +65,24 @@ pub fn source_name(input: &input) -> @str { pub fn default_configuration(sess: Session, argv0: @str, input: &input) -> ast::crate_cfg { - let libc = match sess.targ_cfg.os { - session::os_win32 => @"msvcrt.dll", - session::os_macos => @"libc.dylib", - session::os_linux => @"libc.so.6", - session::os_android => @"libc.so", - session::os_freebsd => @"libc.so.7" - // _ { "libc.so" } + let (libc, tos) = match sess.targ_cfg.os { + session::os_win32 => (@"msvcrt.dll", @"win32"), + session::os_macos => (@"libc.dylib", @"macos"), + session::os_linux => (@"libc.so.6", @"linux"), + session::os_android => (@"libc.so", @"android"), + session::os_freebsd => (@"libc.so.7", @"freebsd") }; - let tos = match sess.targ_cfg.os { - session::os_win32 => @"win32", - session::os_macos => @"macos", - session::os_linux => @"linux", - session::os_android => @"android", - session::os_freebsd => @"freebsd" - // _ { "libc.so" } - }; - - let mk = attr::mk_name_value_item_str; // ARM is bi-endian, however using NDK seems to default // to little-endian unless a flag is provided. let (end,arch,wordsz) = match sess.targ_cfg.arch { - abi::X86 => (@"little",@"x86",@"32"), - abi::X86_64 => (@"little",@"x86_64",@"64"), - abi::Arm => (@"little",@"arm",@"32"), - abi::Mips => (@"big",@"mips",@"32") + abi::X86 => (@"little", @"x86", @"32"), + abi::X86_64 => (@"little", @"x86_64", @"64"), + abi::Arm => (@"little", @"arm", @"32"), + abi::Mips => (@"big", @"mips", @"32") }; + let mk = attr::mk_name_value_item_str; return ~[ // Target bindings. attr::mk_word_item(os::FAMILY.to_managed()), mk(@"target_os", tos), @@ -463,36 +453,37 @@ pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input, } pub fn get_os(triple: &str) -> Option { - if triple.contains("win32") || - triple.contains("mingw32") { - Some(session::os_win32) - } else if triple.contains("darwin") { - Some(session::os_macos) - } else if triple.contains("android") { - Some(session::os_android) - } else if triple.contains("linux") { - Some(session::os_linux) - } else if triple.contains("freebsd") { - Some(session::os_freebsd) - } else { None } + for os_names.each |&(name, os)| { + if triple.contains(name) { return Some(os) } + } + None } +static os_names : &'static [(&'static str, session::os)] = &'static [ + ("win32", session::os_win32), + ("darwin", session::os_macos), + ("android", session::os_android), + ("linux", session::os_linux), + ("freebsd", session::os_freebsd)]; pub fn get_arch(triple: &str) -> Option { - if triple.contains("i386") || - triple.contains("i486") || - triple.contains("i586") || - triple.contains("i686") || - triple.contains("i786") { - Some(abi::X86) - } else if triple.contains("x86_64") { - Some(abi::X86_64) - } else if triple.contains("arm") || - triple.contains("xscale") { - Some(abi::Arm) - } else if triple.contains("mips") { - Some(abi::Mips) - } else { None } + for architecture_abis.each |&(arch, abi)| { + if triple.contains(arch) { return Some(abi) } + } + None } +static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [ + ("i386", abi::X86), + ("i486", abi::X86), + ("i586", abi::X86), + ("i686", abi::X86), + ("i786", abi::X86), + + ("x86_64", abi::X86_64), + + ("arm", abi::Arm), + ("xscale", abi::Arm), + + ("mips", abi::Mips)]; pub fn build_target_config(sopts: @session::options, demitter: diagnostic::Emitter) From c7013ba1fcad7fcc84d7e6e93d7a0306c13bce47 Mon Sep 17 00:00:00 2001 From: Philipp Brueschweiler Date: Sat, 15 Jun 2013 10:10:49 +0200 Subject: [PATCH 05/96] std::dynamic_lib: start fixing windows implementation The code compiles and runs under windows now, but I couldn't look up any symbol from the current executable (dlopen(NULL)), and calling looked up external function handles doesn't seem to work correctly under windows. --- src/libstd/unstable/dynamic_lib.rs | 49 ++++++++++++++++++++---------- src/libstd/unstable/mod.rs | 5 --- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index 96aba1d2971e..f5f88f2bb880 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -42,19 +42,15 @@ impl DynamicLibrary { /// Lazily open a dynamic library. When passed None it gives a /// handle to the calling process pub fn open(filename: Option<&path::Path>) -> Result { - let open_wrapper = |raw_ptr| { - do dl::check_for_errors_in { - unsafe { - DynamicLibrary { handle: dl::open(raw_ptr) } + do dl::check_for_errors_in { + unsafe { + DynamicLibrary { handle: + match filename { + Some(name) => dl::open_external(name), + None => dl::open_internal() + } } } - }; - - match filename { - Some(name) => do name.to_str().as_c_str |raw_name| { - open_wrapper(raw_name) - }, - None => open_wrapper(ptr::null()) } } @@ -74,6 +70,7 @@ impl DynamicLibrary { } #[test] +#[ignore(cfg(windows))] priv fn test_loading_cosine () { // The math library does not need to be loaded since it is already // statically linked in @@ -106,13 +103,20 @@ priv fn test_loading_cosine () { #[cfg(target_os = "freebsd")] mod dl { use libc; + use path; use ptr; use str; use task; use result::*; - pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void { - dlopen(filename, Lazy as libc::c_int) + pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void { + do filename.to_str().as_c_str |raw_name| { + dlopen(raw_name, Lazy as libc::c_int) + } + } + + pub unsafe fn open_internal() -> *libc::c_void { + dlopen(ptr::null(), Lazy as libc::c_int) } pub fn check_for_errors_in(f: &fn()->T) -> Result { @@ -159,11 +163,22 @@ mod dl { mod dl { use os; use libc; + use path; + use ptr; + use str; use task; use result::*; - pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void { - LoadLibrary(filename) + pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void { + do os::win32::as_utf16_p(filename.to_str()) |raw_name| { + LoadLibraryW(raw_name) + } + } + + pub unsafe fn open_internal() -> *libc::c_void { + let mut handle = ptr::null(); + GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void); + handle } pub fn check_for_errors_in(f: &fn()->T) -> Result { @@ -192,7 +207,9 @@ mod dl { #[link_name = "kernel32"] extern "stdcall" { fn SetLastError(error: u32); - fn LoadLibrary(name: *libc::c_char) -> *libc::c_void; + fn LoadLibraryW(name: *u16) -> *libc::c_void; + fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16, + handle: **libc::c_void) -> *libc::c_void; fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void; fn FreeLibrary(handle: *libc::c_void); } diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs index ae8780501425..0a46ef619afd 100644 --- a/src/libstd/unstable/mod.rs +++ b/src/libstd/unstable/mod.rs @@ -18,11 +18,6 @@ use task; pub mod at_exit; -// Currently only works for *NIXes -#[cfg(target_os = "linux")] -#[cfg(target_os = "android")] -#[cfg(target_os = "macos")] -#[cfg(target_os = "freebsd")] pub mod dynamic_lib; pub mod global; From 3f69e2004339c7bd1f5ca150e5506595bffc4997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sat, 15 Jun 2013 18:21:15 +0200 Subject: [PATCH 06/96] trans::glue: don't allocate a pointer variable if it already exists Removes one alloca and store from the drop glue of @ boxes. This speeds up the rustc build by 1s (might be noise, though). --- src/librustc/middle/trans/closure.rs | 2 +- src/librustc/middle/trans/glue.rs | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index d5d018c05435..4dcd2d9d6407 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -552,7 +552,7 @@ pub fn make_opaque_cbox_drop_glue( ast::BorrowedSigil => bcx, ast::ManagedSigil => { glue::decr_refcnt_maybe_free( - bcx, Load(bcx, cboxptr), + bcx, Load(bcx, cboxptr), Some(cboxptr), ty::mk_opaque_closure_ptr(bcx.tcx(), sigil)) } ast::OwnedSigil => { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index c982b26fe84b..5d0bbd72224d 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -103,7 +103,7 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { ty::ty_box(_) | ty::ty_opaque_box | ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { - decr_refcnt_maybe_free(bcx, v, t) + decr_refcnt_maybe_free(bcx, v, None, t) } _ => bcx.tcx().sess.bug("drop_ty_immediate: non-box ty") } @@ -520,7 +520,7 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { let bcx = match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => { - decr_refcnt_maybe_free(bcx, Load(bcx, v0), t) + decr_refcnt_maybe_free(bcx, Load(bcx, v0), Some(v0), t) } ty::ty_uniq(_) | ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { @@ -545,8 +545,10 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { closure::make_closure_glue(bcx, v0, t, drop_ty) } ty::ty_trait(_, _, ty::BoxTraitStore, _) => { - let llbox = Load(bcx, GEPi(bcx, v0, [0u, abi::trt_field_box])); - decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx)) + let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]); + let llbox = Load(bcx, llbox_ptr); + decr_refcnt_maybe_free(bcx, llbox, Some(llbox_ptr), + ty::mk_opaque_box(ccx.tcx)) } ty::ty_trait(_, _, ty::UniqTraitStore, _) => { let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]); @@ -580,7 +582,10 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { build_return(bcx); } -pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, t: ty::t) +// box_ptr_ptr is optional, it is constructed if not supplied. +pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, + box_ptr_ptr: Option, + t: ty::t) -> block { let _icx = bcx.insn_ctxt("decr_refcnt_maybe_free"); let ccx = bcx.ccx(); @@ -590,7 +595,12 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, t: ty::t) let rc = Sub(bcx, Load(bcx, rc_ptr), C_int(ccx, 1)); Store(bcx, rc, rc_ptr); let zero_test = ICmp(bcx, lib::llvm::IntEQ, C_int(ccx, 0), rc); - with_cond(bcx, zero_test, |bcx| free_ty_immediate(bcx, box_ptr, t)) + do with_cond(bcx, zero_test) |bcx| { + match box_ptr_ptr { + Some(p) => free_ty(bcx, p, t), + None => free_ty_immediate(bcx, box_ptr, t) + } + } } } From d22f417c74bf23c5a9c34d10ef5a327d2ab6ebab Mon Sep 17 00:00:00 2001 From: gareth Date: Sat, 15 Jun 2013 17:58:38 +0100 Subject: [PATCH 07/96] Add IterBytes impls for float/f32/f64. This allows creating HashMaps with floats as keys. --- src/libstd/hash.rs | 11 +++++++++++ src/libstd/to_bytes.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index e90224457863..2d33be03580c 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -558,4 +558,15 @@ mod tests { val & !(0xff << (byte * 8)) } } + + #[test] + fn test_float_hashes_differ() { + assert!(0.0.hash() != 1.0.hash()); + assert!(1.0.hash() != (-1.0).hash()); + } + + #[test] + fn test_float_hashes_of_zero() { + assert_eq!(0.0.hash(), (-0.0).hash()); + } } diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index c0c8b729f9ea..6d7820ffea5f 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -14,6 +14,7 @@ The `ToBytes` and `IterBytes` traits */ +use cast; use io; use io::Writer; use option::{None, Option, Some}; @@ -190,6 +191,35 @@ impl IterBytes for int { } } +impl IterBytes for float { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as f64).iter_bytes(lsb0, f) + } +} + +impl IterBytes for f32 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + let i: u32 = unsafe { + // 0.0 == -0.0 so they should also have the same hashcode + cast::transmute(if *self == -0.0 { 0.0 } else { *self }) + }; + i.iter_bytes(lsb0, f) + } +} + +impl IterBytes for f64 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + let i: u64 = unsafe { + // 0.0 == -0.0 so they should also have the same hashcode + cast::transmute(if *self == -0.0 { 0.0 } else { *self }) + }; + i.iter_bytes(lsb0, f) + } +} + impl<'self,A:IterBytes> IterBytes for &'self [A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { From 4ee99a1c0c8238eb253b23ed2fa5036517fd95f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sat, 15 Jun 2013 20:13:23 +0200 Subject: [PATCH 08/96] trans::glue: don't generate struct destructors in the free glue The free glue shouldn't be called for structs, and the drop glue already contains the destructor. --- src/librustc/middle/trans/glue.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index c982b26fe84b..037861ebc97e 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -450,15 +450,6 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_opaque_closure_ptr(ck) => { closure::make_opaque_cbox_free_glue(bcx, ck, v) } - ty::ty_struct(did, ref substs) => { - // Call the dtor if there is one - match ty::ty_dtor(bcx.tcx(), did) { - ty::NoDtor => bcx, - ty::TraitDtor(ref dt_id) => { - trans_struct_drop(bcx, t, v, *dt_id, did, substs) - } - } - } _ => bcx }; build_return(bcx); From f22580dd294fde86c399741cdd1d3519a74004d6 Mon Sep 17 00:00:00 2001 From: Steven Stewart-Gallus Date: Sat, 15 Jun 2013 11:26:02 -0700 Subject: [PATCH 09/96] Fix up mingw32 case --- src/librustc/driver/driver.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index f4e2a2dd2b88..777b06e1a88a 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -459,6 +459,7 @@ pub fn get_os(triple: &str) -> Option { None } static os_names : &'static [(&'static str, session::os)] = &'static [ + ("mingw32", session::os_win32), ("win32", session::os_win32), ("darwin", session::os_macos), ("android", session::os_android), From 9c4f9bb71bbac102621fb53efa8d41351a92350e Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 15 Jun 2013 14:20:34 -0700 Subject: [PATCH 10/96] Fix terminfo::param %i op --- src/libextra/terminfo/parm.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/libextra/terminfo/parm.rs b/src/libextra/terminfo/parm.rs index c395b57219c2..11f0fc23be51 100644 --- a/src/libextra/terminfo/parm.rs +++ b/src/libextra/terminfo/parm.rs @@ -224,9 +224,9 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) } } else { return Err(~"stack is empty") }, 'i' => match (copy mparams[0], copy mparams[1]) { - (Number(ref mut x), Number(ref mut y)) => { - *x += 1; - *y += 1; + (Number(x), Number(y)) => { + mparams[0] = Number(x+1); + mparams[1] = Number(y+1); }, (_, _) => return Err(~"first two params not numbers with %i") }, @@ -352,6 +352,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) #[cfg(test)] mod test { use super::*; + use core::result::Ok; #[test] fn test_basic_setabf() { @@ -366,6 +367,16 @@ mod test { bytes!("21").to_owned()); } + #[test] + fn test_op_i() { + let mut vars = Variables::new(); + assert_eq!(expand(bytes!("%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d"), + [Number(1),Number(2),Number(3)], &mut vars), + Ok(bytes!("123233").to_owned())); + assert_eq!(expand(bytes!("%p1%d%p2%d%i%p1%d%p2%d"), [], &mut vars), + Ok(bytes!("0011").to_owned())); + } + #[test] fn test_param_stack_failure_conditions() { let mut varstruct = Variables::new(); From eb5ac84c8e14184b9b76fe088b5f5120e887ee35 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 17:42:31 -0400 Subject: [PATCH 11/96] iterator: add a `find` adaptor --- src/libstd/iterator.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index e65904a68992..7aa273f7cd81 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -308,6 +308,9 @@ pub trait IteratorUtil { /// assert!(!it.any_(|&x| *x == 3)); /// ~~~ fn any_(&mut self, f: &fn(A) -> bool) -> bool; + + /// Return the first element satisfying the specified predicate + fn find(&mut self, predicate: &fn(&A) -> bool) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -421,7 +424,7 @@ impl> IteratorUtil for T { None => { break; } } } - return accum; + accum } /// Count the number of items yielded by an iterator @@ -431,13 +434,22 @@ impl> IteratorUtil for T { #[inline(always)] fn all(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if !f(x) { return false; } } - return true; + true } #[inline(always)] fn any_(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if f(x) { return true; } } - return false; + false + } + + /// Return the first element satisfying the specified predicate + #[inline(always)] + fn find(&mut self, predicate: &fn(&A) -> bool) -> Option { + for self.advance |x| { + if predicate(&x) { return Some(x) } + } + None } } @@ -1055,4 +1067,12 @@ mod tests { assert!(!v.iter().any_(|&x| x > 100)); assert!(!v.slice(0, 0).iter().any_(|_| fail!())); } + + #[test] + fn test_find() { + let v = &[1, 3, 9, 27, 103, 14, 11]; + assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14); + assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3); + assert!(v.iter().find(|x| *x % 12 == 0).is_none()); + } } From 2df66a84cd64211c22e58c48df07ce63bf5469a3 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 17:56:26 -0400 Subject: [PATCH 12/96] iterator: add a `position` adaptor --- src/libstd/iterator.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 7aa273f7cd81..a8969f1da6e2 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -311,6 +311,9 @@ pub trait IteratorUtil { /// Return the first element satisfying the specified predicate fn find(&mut self, predicate: &fn(&A) -> bool) -> Option; + + /// Return the index of the first element satisfying the specified predicate + fn position(&mut self, predicate: &fn(A) -> bool) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -451,6 +454,19 @@ impl> IteratorUtil for T { } None } + + /// Return the index of the first element satisfying the specified predicate + #[inline] + fn position(&mut self, predicate: &fn(A) -> bool) -> Option { + let mut i = 0; + for self.advance |x| { + if predicate(x) { + return Some(i); + } + i += 1; + } + None + } } /// A trait for iterators over elements which can be added together @@ -1075,4 +1091,12 @@ mod tests { assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3); assert!(v.iter().find(|x| *x % 12 == 0).is_none()); } + + #[test] + fn test_position() { + let v = &[1, 3, 9, 27, 103, 14, 11]; + assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5); + assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1); + assert!(v.iter().position(|x| *x % 12 == 0).is_none()); + } } From 79cd2dbe72781e14adb321483cfed1d861a598ce Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 18:02:05 -0400 Subject: [PATCH 13/96] iterator: work around method resolve bug --- src/libstd/iterator.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index a8969f1da6e2..a505c5523598 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -310,10 +310,10 @@ pub trait IteratorUtil { fn any_(&mut self, f: &fn(A) -> bool) -> bool; /// Return the first element satisfying the specified predicate - fn find(&mut self, predicate: &fn(&A) -> bool) -> Option; + fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option; /// Return the index of the first element satisfying the specified predicate - fn position(&mut self, predicate: &fn(A) -> bool) -> Option; + fn position_(&mut self, predicate: &fn(A) -> bool) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -448,7 +448,7 @@ impl> IteratorUtil for T { /// Return the first element satisfying the specified predicate #[inline(always)] - fn find(&mut self, predicate: &fn(&A) -> bool) -> Option { + fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option { for self.advance |x| { if predicate(&x) { return Some(x) } } @@ -457,7 +457,7 @@ impl> IteratorUtil for T { /// Return the index of the first element satisfying the specified predicate #[inline] - fn position(&mut self, predicate: &fn(A) -> bool) -> Option { + fn position_(&mut self, predicate: &fn(A) -> bool) -> Option { let mut i = 0; for self.advance |x| { if predicate(x) { @@ -1087,16 +1087,16 @@ mod tests { #[test] fn test_find() { let v = &[1, 3, 9, 27, 103, 14, 11]; - assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14); - assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3); - assert!(v.iter().find(|x| *x % 12 == 0).is_none()); + assert_eq!(*v.iter().find_(|x| *x & 1 == 0).unwrap(), 14); + assert_eq!(*v.iter().find_(|x| *x % 3 == 0).unwrap(), 3); + assert!(v.iter().find_(|x| *x % 12 == 0).is_none()); } #[test] fn test_position() { let v = &[1, 3, 9, 27, 103, 14, 11]; - assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5); - assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1); - assert!(v.iter().position(|x| *x % 12 == 0).is_none()); + assert_eq!(v.iter().position_(|x| *x & 1 == 0).unwrap(), 5); + assert_eq!(v.iter().position_(|x| *x % 3 == 0).unwrap(), 1); + assert!(v.iter().position_(|x| *x % 12 == 0).is_none()); } } From 0f9c191d8fd34a650166db70c307fd6869b4c4c5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 15 Jun 2013 15:22:22 -0700 Subject: [PATCH 14/96] std: Remove doc references to reinterpret_cast --- src/libstd/cast.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index 2109568a0a4e..4d79dea6052a 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -54,17 +54,14 @@ pub unsafe fn transmute_copy(src: &T) -> U { * * The forget function will take ownership of the provided value but neglect * to run any required cleanup or memory-management operations on it. This - * can be used for various acts of magick, particularly when using - * reinterpret_cast on pointer types. + * can be used for various acts of magick. */ #[inline(always)] pub unsafe fn forget(thing: T) { intrinsics::forget(thing); } /** * Force-increment the reference count on a shared box. If used - * carelessly, this can leak the box. Use this in conjunction with transmute - * and/or reinterpret_cast when such calls would otherwise scramble a box's - * reference count + * carelessly, this can leak the box. */ #[inline(always)] pub unsafe fn bump_box_refcount(t: @T) { forget(t); } From 069086cdb42d432d2354e6b894c5b1bf80320eec Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 15 Jun 2013 16:01:24 -0700 Subject: [PATCH 15/96] Remove the fuzzer It is suffering from a bad case of megabitrot. --- Makefile.in | 6 - mk/clean.mk | 6 - mk/dist.mk | 1 - mk/pp.mk | 1 - mk/tools.mk | 39 -- src/driver/driver.rs | 3 - src/libfuzzer/ast_match.rs | 42 --- src/libfuzzer/cycles.rs | 108 ------ src/libfuzzer/fuzzer.rc | 713 ------------------------------------- src/libfuzzer/ivec_fuzz.rs | 121 ------- src/libfuzzer/rand_util.rs | 106 ------ 11 files changed, 1146 deletions(-) delete mode 100644 src/libfuzzer/ast_match.rs delete mode 100644 src/libfuzzer/cycles.rs delete mode 100644 src/libfuzzer/fuzzer.rc delete mode 100644 src/libfuzzer/ivec_fuzz.rs delete mode 100644 src/libfuzzer/rand_util.rs diff --git a/Makefile.in b/Makefile.in index ca82f2960227..fa4c327f0614 100644 --- a/Makefile.in +++ b/Makefile.in @@ -208,7 +208,6 @@ CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std) CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra) CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc) CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax) -CFG_LIBFUZZER_$(1) :=$(call CFG_LIB_NAME_$(1),fuzzer) CFG_LIBRUSTPKG_$(1) :=$(call CFG_LIB_NAME_$(1),rustpkg) CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc) CFG_LIBRUSTI_$(1) :=$(call CFG_LIB_NAME_$(1),rusti) @@ -218,7 +217,6 @@ EXTRALIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),extra) STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std) LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc) LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax) -LIBFUZZER_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),fuzzer) LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg) LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc) LIBRUSTI_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rusti) @@ -227,7 +225,6 @@ EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra) STDLIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),std) LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc) LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax) -LIBFUZZER_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),fuzzer) LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg) LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc) LIBRUSTI_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rusti) @@ -402,12 +399,10 @@ SREQ$(1)_T_$(2)_H_$(3) = \ # Prerequisites for a working stageN compiler and libraries, for a specific target CSREQ$(1)_T_$(2)_H_$(3) = \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ - $$(HBIN$(1)_H_$(3))/fuzzer$$(X_$(3)) \ $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \ $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \ $$(HBIN$(1)_H_$(3))/rusti$$(X_$(3)) \ $$(HBIN$(1)_H_$(3))/rust$$(X_$(3)) \ - $$(HLIB$(1)_H_$(3))/$(CFG_LIBFUZZER_$(3)) \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTPKG_$(3)) \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTI_$(3)) \ @@ -416,7 +411,6 @@ CSREQ$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTI_$(2)) \ diff --git a/mk/clean.mk b/mk/clean.mk index 9a074b29d8b1..23efbb3ee15c 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -63,13 +63,11 @@ define CLEAN_HOST_STAGE_N clean$(1)_H_$(2): $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustc$(X_$(2)) - $(Q)rm -f $$(HBIN$(1)_H_$(2))/fuzzer$(X_$(2)) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X_$(2)) $(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X_$(2)) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X_$(2)) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X_$(2)) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X_$(2)) - $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBFUZZER_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME_$(2)) @@ -83,7 +81,6 @@ clean$(1)_H_$(2): $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_GLOB_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2)) - $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBFUZZER_GLOB_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB_$(2)) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB_$(2)) @@ -101,13 +98,11 @@ define CLEAN_TARGET_STAGE_N clean$(1)_T_$(2)_H_$(3): $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$(X_$(2)) - $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/fuzzer$(X_$(2)) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X_$(2)) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X_$(2)) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X_$(2)) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rusti$(X_$(2)) $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rust$(X_$(2)) - $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)) @@ -121,7 +116,6 @@ clean$(1)_T_$(2)_H_$(3): $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_GLOB_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2)) - $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBFUZZER_GLOB_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB_$(2)) $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTI_GLOB_$(2)) diff --git a/mk/dist.mk b/mk/dist.mk index 96f35031de93..912b692a247e 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -32,7 +32,6 @@ PKG_FILES := \ librustc \ compiletest \ etc \ - libfuzzer \ libextra \ libstd \ libsyntax \ diff --git a/mk/pp.mk b/mk/pp.mk index 0a24d9e87979..f86bbb7f2812 100644 --- a/mk/pp.mk +++ b/mk/pp.mk @@ -17,7 +17,6 @@ else $(wildcard $(addprefix $(S)src/rustc/,*.rs */*.rs */*/*.rs)) \ $(wildcard $(S)src/test/*/*.rs \ $(S)src/test/*/*/*.rs) \ - $(wildcard $(S)src/fuzzer/*.rs) \ $(wildcard $(S)src/rustpkg/*.rs) \ $(wildcard $(S)src/rusti/*.rs) \ $(wildcard $(S)src/rust/*.rs) diff --git a/mk/tools.mk b/mk/tools.mk index 018da2a64016..8319d8d4e483 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -11,9 +11,6 @@ # Rules for non-core tools built with the compiler, both for target # and host architectures -FUZZER_LIB := $(S)src/libfuzzer/fuzzer.rc -FUZZER_INPUTS := $(wildcard $(addprefix $(S)src/libfuzzer/, *.rs)) - # The test runner that runs the cfail/rfail/rpass and bxench tests COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs) @@ -38,21 +35,6 @@ RUST_INPUTS := $(wildcard $(S)src/librust/*.rs) # have tools that need to built for other targets. define TOOLS_STAGE_N_TARGET -$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4)): \ - $$(FUZZER_LIB) $$(FUZZER_INPUTS) \ - $$(TSREQ$(1)_T_$(4)_H_$(3)) \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) - @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@ - -$$(TBIN$(1)_T_$(4)_H_$(3))/fuzzer$$(X_$(4)): \ - $$(DRIVER_CRATE) \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4)) - @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg fuzzer -o $$@ $$< - $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)): \ $$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS) \ $$(TSREQ$(1)_T_$(4)_H_$(3)) \ @@ -128,27 +110,6 @@ endef define TOOLS_STAGE_N_HOST - -# Promote the stageN target to stageN+1 host -# FIXME: Shouldn't need to depend on host/librustc.so once -# rpath is working -$$(HLIB$(2)_H_$(4))/$(CFG_LIBFUZZER_$(4)): \ - $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4)) \ - $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \ - $$(HSREQ$(2)_H_$(4)) - @$$(call E, cp: $$@) - $$(Q)cp $$< $$@ - $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBFUZZER_GLOB_$(4)) \ - $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBFUZZER_DSYM_GLOB_$(4))) \ - $$(HLIB$(2)_H_$(4)) - -$$(HBIN$(2)_H_$(4))/fuzzer$$(X_$(4)): \ - $$(TBIN$(1)_T_$(4)_H_$(3))/fuzzer$$(X_$(4)) \ - $$(HLIB$(2)_H_$(4))/$(CFG_LIBFUZZER_$(4)) \ - $$(HSREQ$(2)_H_$(4)) - @$$(call E, cp: $$@) - $$(Q)cp $$< $$@ - $$(HBIN$(2)_H_$(4))/compiletest$$(X_$(4)): \ $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)) \ $$(HSREQ$(2)_H_$(4)) diff --git a/src/driver/driver.rs b/src/driver/driver.rs index 97e01d1bcdc0..ccedd3adbaa9 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -16,9 +16,6 @@ extern mod core(name = "std", vers = "0.7-pre"); #[cfg(rustpkg)] extern mod this(name = "rustpkg"); -#[cfg(fuzzer)] -extern mod this(name = "fuzzer"); - #[cfg(rustdoc)] extern mod this(name = "rustdoc"); diff --git a/src/libfuzzer/ast_match.rs b/src/libfuzzer/ast_match.rs deleted file mode 100644 index 7d623919ff93..000000000000 --- a/src/libfuzzer/ast_match.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::prelude::*; - -use vec; - -fn vec_equal(v: ~[T], - u: ~[T], - element_equality_test: @fn(&&T, &&T) -> bool) -> - bool { - let Lv = v.len(); - if Lv != u.len() { return false; } - let i = 0u; - while i < Lv { - if !element_equality_test(v[i], u[i]) { return false; } - i += 1u; - } - return true; -} - -fn builtin_equal(&&a: T, &&b: T) -> bool { return a == b; } -fn builtin_equal_int(&&a: int, &&b: int) -> bool { return a == b; } - -fn main() { - assert!((builtin_equal(5, 5))); - assert!((!builtin_equal(5, 4))); - assert!((!vec_equal(~[5, 5], ~[5], bind builtin_equal(_, _)))); - assert!((!vec_equal(~[5, 5], ~[5], builtin_equal_int))); - assert!((!vec_equal(~[5, 5], ~[5, 4], builtin_equal_int))); - assert!((!vec_equal(~[5, 5], ~[4, 5], builtin_equal_int))); - assert!((vec_equal(~[5, 5], ~[5, 5], builtin_equal_int))); - - error!("Pass"); -} diff --git a/src/libfuzzer/cycles.rs b/src/libfuzzer/cycles.rs deleted file mode 100644 index 2256325fa437..000000000000 --- a/src/libfuzzer/cycles.rs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::prelude::*; - -use extra; -use extra::rand; -use uint::range; - -// random uint less than n -fn under(r : rand::rng, n : uint) -> uint { - assert!(n != 0u); r.next() as uint % n -} - -// random choice from a vec -fn choice(r : rand::rng, v : ~[const T]) -> T { - assert!(v.len() != 0u); v[under(r, v.len())] -} - -// k in n chance of being true -fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k } - - -static iters : uint = 1000u; -static vlen : uint = 100u; - -enum maybe_pointy { - none, - p(@pointy) -} - -type pointy = { - mut a : maybe_pointy, - mut b : ~maybe_pointy, - mut c : @maybe_pointy, - - mut f : @fn()->(), - mut g : ~fn()->(), - - mut m : ~[maybe_pointy], - mut n : ~[maybe_pointy], - mut o : {x : int, y : maybe_pointy} -}; -// To add: objects; traits; anything type-parameterized? - -fn empty_pointy() -> @pointy { - return @{ - mut a : none, - mut b : ~none, - mut c : @none, - - mut f : || {}, - mut g : || {}, - - mut m : ~[], - mut n : ~[], - mut o : {x : 0, y : none} - } -} - -fn nopP(_x : @pointy) { } -fn nop(_x: T) { } - -fn test_cycles(r : rand::rng, k: uint, n: uint) -{ - let mut v : ~[@pointy] = ~[]; - - // Create a graph with no edges - range(0u, vlen) {|_i| - v.push(empty_pointy()); - } - - // Fill in the graph with random edges, with density k/n - range(0u, vlen) {|i| - if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); } - if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); } - if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); } - - if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); } - //if (false) { v[i].g = bind (|_: @pointy| { })( - // choice(r, v)); } - // https://github.com/mozilla/rust/issues/1899 - - if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; } - if (likelihood(r, k, n)) { v[i].n.push(mut p(choice(r, v))); } - if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; } - } - - // Drop refs one at a time - range(0u, vlen) {|i| - v[i] = empty_pointy() - } -} - -fn main() -{ - let r = rand::rng(); - range(0u, iters) {|i| - test_cycles(r, i, iters); - } -} diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc deleted file mode 100644 index 4e2103fcd704..000000000000 --- a/src/libfuzzer/fuzzer.rc +++ /dev/null @@ -1,713 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -#[link(name = "fuzzer", - vers = "0.7-pre", - uuid = "d6418797-2736-4833-bd82-d3c684b7c1b0", - url = "https://github.com/mozilla/rust/tree/master/src/libfuzzer")]; - -#[comment = "The Rust fuzzer library"]; -#[license = "MIT/ASL2"]; -#[crate_type = "lib"]; - -#[allow(non_camel_case_types)]; - -#[no_std]; - -extern mod std(name = "std", vers = "0.7-pre"); -extern mod extra(name = "extra", vers = "0.7-pre"); - -extern mod syntax(vers = "0.7-pre"); - -use std::prelude::*; - -use std::int; -use std::io; -use std::option; -use std::os; -use std::result; -use std::run; -use std::str; -use std::uint; - -use syntax::diagnostic; -use syntax::parse::token::ident_interner; -use syntax::parse::token; -use syntax::parse; -use syntax::print::pprust; -use syntax::{ast, fold, visit, codemap}; - -#[deriving(Eq)] -pub enum test_mode { tm_converge, tm_run, } - -pub struct Context { mode: test_mode } // + rng - -pub fn write_file(filename: &Path, content: &str) { - result::get(&io::file_writer(filename, [io::Create, io::Truncate])) - .write_str(content); -} - -pub fn contains(haystack: &str, needle: &str) -> bool { - haystack.contains(needle) -} - -pub fn find_rust_files(files: &mut ~[Path], path: &Path) { - if path.filetype() == Some(~".rs") && !contains(path.to_str(), "utf8") { - // ignoring "utf8" tests because something is broken - files.push(path.clone()); - } else if os::path_is_dir(path) - && !contains(path.to_str(), "compile-fail") - && !contains(path.to_str(), "build") { - for os::list_dir_path(path).each |p| { - find_rust_files(&mut *files, *p); - } - } -} - - -pub fn common_exprs() -> ~[@ast::expr] { - fn dse(e: ast::expr_) -> @ast::expr { - @ast::expr { - id: 0, - node: e, - span: codemap::dummy_sp(), - } - } - - fn dsl(l: ast::lit_) -> ast::lit { - codemap::spanned { node: l, span: codemap::dummy_sp() } - } - - ~[dse(ast::expr_break(option::None)), - dse(ast::expr_again(option::None)), - dse(ast::expr_ret(option::None)), - dse(ast::expr_lit(@dsl(ast::lit_nil))), - dse(ast::expr_lit(@dsl(ast::lit_bool(false)))), - dse(ast::expr_lit(@dsl(ast::lit_bool(true)))), - dse(ast::expr_unary(-1, ast::box(ast::m_imm), - dse(ast::expr_lit(@dsl(ast::lit_bool(true)))))), - dse(ast::expr_unary(-1, ast::uniq(ast::m_imm), - dse(ast::expr_lit(@dsl(ast::lit_bool(true)))))) - ] -} - -pub fn safe_to_steal_expr(e: @ast::expr, tm: test_mode) -> bool { - safe_to_use_expr(e, tm) -} - -pub fn safe_to_use_expr(e: @ast::expr, tm: test_mode) -> bool { - match tm { - tm_converge => { - match e.node { - // If the fuzzer moves a block-ending-in-semicolon into callee - // position, the pretty-printer can't preserve this even by - // parenthesizing!! See email to marijn. - ast::expr_if(*) | ast::expr_block(*) - | ast::expr_match(*) | ast::expr_while(*) => { false } - - // https://github.com/mozilla/rust/issues/929 - ast::expr_cast(*) | ast::expr_binary(*) | ast::expr_assign(*) | - ast::expr_assign_op(*) => { false } - - ast::expr_ret(option::None) => { false } - - // https://github.com/mozilla/rust/issues/953 - //ast::expr_fail(option::Some(_)) => { false } - - // https://github.com/mozilla/rust/issues/928 - //ast::expr_cast(_, _) { false } - - // https://github.com/mozilla/rust/issues/1458 - ast::expr_call(*) => { false } - - _ => { true } - } - } - tm_run => { true } - } -} - -pub fn safe_to_steal_ty(t: @ast::Ty, tm: test_mode) -> bool { - // Restrictions happen to be the same. - safe_to_replace_ty(&t.node, tm) -} - -// Not type-parameterized: https://github.com/mozilla/rust/issues/898 (FIXED) -pub fn stash_expr_if(c: @fn(@ast::expr, test_mode)->bool, - es: @mut ~[@ast::expr], - e: @ast::expr, - tm: test_mode) { - if c(e, tm) { - *es = *es + [e]; - } else { - /* now my indices are wrong :( */ - } -} - -pub fn stash_ty_if(c: @fn(@ast::Ty, test_mode) -> bool, - es: @mut ~[@ast::Ty], - e: @ast::Ty, - tm: test_mode) { - if c(e, tm) { - es.push(e); - } else { - /* now my indices are wrong :( */ - } -} - -pub struct StolenStuff { - exprs: ~[@ast::expr], - tys: ~[@ast::Ty] -} - -pub fn steal(crate: @ast::crate, tm: test_mode) -> StolenStuff { - let exprs = @mut ~[]; - let tys = @mut ~[]; - let v = visit::mk_simple_visitor(@visit::SimpleVisitor { - visit_expr: |a| stash_expr_if(safe_to_steal_expr, exprs, a, tm), - visit_ty: |a| stash_ty_if(safe_to_steal_ty, tys, a, tm), - .. *visit::default_simple_visitor() - }); - visit::visit_crate(crate, ((), v)); - StolenStuff { - exprs: (*exprs).clone(), - tys: (*tys).clone(), - } -} - - -pub fn safe_to_replace_expr(e: &ast::expr_, _tm: test_mode) -> bool { - match *e { - // https://github.com/mozilla/rust/issues/652 - ast::expr_if(*) => false, - ast::expr_block(_) => false, - - // expr_call is also missing a constraint - ast::expr_fn_block(*) => false, - - _ => true, - } -} - -pub fn safe_to_replace_ty(t: &ast::ty_, _tm: test_mode) -> bool { - match *t { - ast::ty_infer => { false } // always implicit, always top level - ast::ty_bot => { false } // in source, can only appear - // as the out type of a function - ast::ty_mac(_) => { false } - _ => { true } - } -} - -// Replace the |i|th expr (in fold order) of |crate| with |newexpr|. -pub fn replace_expr_in_crate(crate: @ast::crate, - i: uint, - newexpr: @ast::expr, - tm: test_mode) - -> @ast::crate { - let j: @mut uint = @mut 0u; - fn fold_expr_rep(j_: @mut uint, - i_: uint, - newexpr_: &ast::expr_, - original: &ast::expr_, - fld: @fold::ast_fold, - tm_: test_mode) - -> ast::expr_ { - *j_ += 1; - if i_ + 1 == *j_ && safe_to_replace_expr(original, tm_) { - copy *newexpr_ - } else { - fold::noop_fold_expr(original, fld) - } - } - let afp = @fold::AstFoldFns { - fold_expr: fold::wrap(|a,b| { - fold_expr_rep(j, i, &newexpr.node, a, b, tm) - }), - .. *fold::default_ast_fold() - }; - let af = fold::make_fold(afp); - let crate2: @ast::crate = @af.fold_crate(crate); - crate2 -} - - -// Replace the |i|th ty (in fold order) of |crate| with |newty|. -pub fn replace_ty_in_crate(crate: @ast::crate, - i: uint, - newty: @ast::Ty, - tm: test_mode) - -> @ast::crate { - let j: @mut uint = @mut 0u; - fn fold_ty_rep(j_: @mut uint, - i_: uint, - newty_: &ast::ty_, - original: &ast::ty_, - fld: @fold::ast_fold, - tm_: test_mode) - -> ast::ty_ { - *j_ += 1; - if i_ + 1 == *j_ && safe_to_replace_ty(original, tm_) { - copy *newty_ - } else { - fold::noop_fold_ty(original, fld) - } - } - let afp = @fold::AstFoldFns { - fold_ty: fold::wrap(|a,b| fold_ty_rep(j, i, &newty.node, a, b, tm)), - .. *fold::default_ast_fold() - }; - let af = fold::make_fold(afp); - let crate2: @ast::crate = @af.fold_crate(crate); - crate2 -} - -pub fn under(n: uint, it: &fn(uint)) { - let mut i: uint = 0u; - while i < n { it(i); i += 1u; } -} - -pub fn as_str(f: @fn(x: @io::Writer)) -> ~str { - io::with_str_writer(f) -} - -pub fn check_variants_of_ast(crate: @ast::crate, - codemap: @codemap::CodeMap, - filename: &Path, - cx: Context) { - let stolen = steal(crate, cx.mode); - let extra_exprs = do common_exprs().filtered |&a| { - safe_to_use_expr(a, cx.mode) - }; - check_variants_T(crate, - codemap, - filename, - ~"expr", - extra_exprs + stolen.exprs, - pprust::expr_to_str, - replace_expr_in_crate, - cx); - check_variants_T(crate, - codemap, - filename, - ~"ty", - stolen.tys, - pprust::ty_to_str, - replace_ty_in_crate, - cx); -} - -pub fn check_variants_T(crate: @ast::crate, - codemap: @codemap::CodeMap, - filename: &Path, - thing_label: ~str, - things: &[T], - stringifier: @fn(T, @ident_interner) -> ~str, - replacer: @fn(@ast::crate, - uint, - T, - test_mode) - -> @ast::crate, - cx: Context) { - error!("%s contains %u %s objects", filename.to_str(), - things.len(), thing_label); - - // Assuming we're not generating any token_trees - let intr = syntax::parse::token::mk_fake_ident_interner(); - - let L = things.len(); - - if L < 100 { - do under(uint::min(L, 20)) |i| { - error!("Replacing... #%?", uint::to_str(i)); - let fname = str::to_owned(filename.to_str()); - do under(uint::min(L, 30)) |j| { - let fname = fname.to_str(); - error!("With... %?", stringifier(things[j], intr)); - let crate2 = replacer(crate, i, things[j], cx.mode); - // It would be best to test the *crate* for stability, but - // testing the string for stability is easier and ok for now. - let handler = diagnostic::mk_handler(None); - let str3 = do io::with_str_reader("") |rdr| { - let fname = fname.to_str(); - let string = do as_str |a| { - let span_handler = - diagnostic::mk_span_handler(handler, codemap); - pprust::print_crate(codemap, - intr, - span_handler, - crate2, - fname.to_managed(), - rdr, - a, - pprust::no_ann(), - false) - }; - string.to_managed() - }; - match cx.mode { - tm_converge => check_roundtrip_convergence(str3, 1), - tm_run => { - let file_label = fmt!("rusttmp/%s_%s_%u_%u", - last_part(filename.to_str()), - thing_label, - i, - j); - let safe_to_run = !(content_is_dangerous_to_run(str3) - || has_raw_pointers(crate2)); - check_whole_compiler(str3, - &Path(file_label), - safe_to_run); - } - } - } - } - } -} - -pub fn last_part(filename: ~str) -> ~str { - let ix = filename.rfind('/').get(); - filename.slice(ix + 1u, filename.len() - 3u).to_owned() -} - -pub enum happiness { - passed, - cleanly_rejected(~str), - known_bug(~str), - failed(~str), -} - -// We'd find more bugs if we could take an AST here, but -// - that would find many "false positives" or unimportant bugs -// - that would be tricky, requiring use of tasks or serialization -// or randomness. -// This seems to find plenty of bugs as it is :) -pub fn check_whole_compiler(code: &str, - suggested_filename_prefix: &Path, - allow_running: bool) { - let filename = &suggested_filename_prefix.with_filetype("rs"); - write_file(filename, code); - - let compile_result = check_compiling(filename); - - let run_result = match (compile_result, allow_running) { - (passed, true) => { check_running(suggested_filename_prefix) } - (h, _) => { h } - }; - - match run_result { - passed | cleanly_rejected(_) | known_bug(_) => { - removeIfExists(suggested_filename_prefix); - removeIfExists(&suggested_filename_prefix.with_filetype("rs")); - removeDirIfExists(&suggested_filename_prefix.with_filetype("dSYM")); - } - failed(s) => { - error!("check_whole_compiler failure: %?", s); - error!("Saved as: %?", filename.to_str()); - } - } -} - -pub fn removeIfExists(filename: &Path) { - // So sketchy! - assert!(!contains(filename.to_str(), " ")); - run::process_status("bash", [~"-c", ~"rm " + filename.to_str()]); -} - -pub fn removeDirIfExists(filename: &Path) { - // So sketchy! - assert!(!contains(filename.to_str(), " ")); - run::process_status("bash", [~"-c", ~"rm -r " + filename.to_str()]); -} - -pub fn check_running(exe_filename: &Path) -> happiness { - let p = run::process_output( - "/Users/jruderman/scripts/timed_run_rust_program.py", - [exe_filename.to_str()]); - let comb = str::from_bytes(p.output) + "\n" + str::from_bytes(p.error); - if comb.len() > 1u { - error!("comb comb comb: %?", comb); - } - - if contains(comb, "Assertion failed:") { - failed(~"C++ assertion failure") - } else if contains(comb, "leaked memory in rust main loop") { - // might also use exit code 134 - //failed("Leaked") - known_bug(~"https://github.com/mozilla/rust/issues/910") - } else if contains(comb, "src/rt/") { - failed(~"Mentioned src/rt/") - } else if contains(comb, "malloc") { - failed(~"Mentioned malloc") - } else { - match p.status { - 0 => { passed } - 100 => { cleanly_rejected(~"running: explicit fail") } - 101 | 247 => { cleanly_rejected(~"running: timed out") } - 245 | 246 | 138 | 252 => { - known_bug(~"https://github.com/mozilla/rust/issues/1466") - } - 136 | 248 => { - known_bug( - ~"SIGFPE - https://github.com/mozilla/rust/issues/944") - } - rc => { - failed(~"Rust program ran but exited with status " + - int::to_str(rc)) - } - } - } -} - -pub fn check_compiling(filename: &Path) -> happiness { - let p = run::process_output( - "/Users/jruderman/code/rust/build/x86_64-apple-darwin/stage1/bin/rustc", - [filename.to_str()]); - - let out = str::from_bytes(p.output); - let err = str::from_bytes(p.error); - - //error!("Status: %d", p.status); - if p.status == 0 { - passed - } else if !err.is_empty() { - if err.contains("error:") { - cleanly_rejected(~"rejected with span_error") - } else { - error!("Stderr: %?", err); - failed(~"Unfamiliar error message") - } - } else if out.contains("Assertion") && out.contains("failed") { - error!("Stdout: %?", out); - failed(~"Looks like an llvm assertion failure") - } else if out.contains("internal compiler error unimplemented") { - known_bug(~"Something unimplemented") - } else if out.contains("internal compiler error") { - error!("Stdout: %?", out); - failed(~"internal compiler error") - - } else { - error!("%?", p.status); - error!("!Stdout: %?", out); - failed(~"What happened?") - } -} - - -pub fn parse_and_print(code: @str) -> @str { - let filename = Path("tmp.rs"); - let sess = parse::new_parse_sess(option::None); - write_file(&filename, code); - let crate = parse::parse_crate_from_source_str(filename.to_str().to_managed(), - code, - ~[], - sess); - do io::with_str_reader(code) |rdr| { - let filename = filename.to_str(); - do as_str |a| { - pprust::print_crate(sess.cm, - // Assuming there are no token_trees - token::mk_fake_ident_interner(), - copy sess.span_diagnostic, - crate, - filename.to_managed(), - rdr, - a, - pprust::no_ann(), - false) - }.to_managed() - } -} - -pub fn has_raw_pointers(c: @ast::crate) -> bool { - let has_rp = @mut false; - fn visit_ty(flag: @mut bool, t: @ast::Ty) { - match t.node { - ast::ty_ptr(_) => { *flag = true; } - _ => { } - } - } - let v = - visit::mk_simple_visitor(@visit::SimpleVisitor { - visit_ty: |a| visit_ty(has_rp, a), - .. *visit::default_simple_visitor()}); - visit::visit_crate(c, ((), v)); - return *has_rp; -} - -pub fn content_is_dangerous_to_run(code: &str) -> bool { - let dangerous_patterns = - ~[~"xfail-test", - ~"import", // espeically fs, run - ~"extern", - ~"unsafe", - ~"log"]; // python --> rust pipe deadlock? - - for dangerous_patterns.each |p| { if contains(code, *p) { return true; } } - return false; -} - -pub fn content_is_dangerous_to_compile(code: &str) -> bool { - let dangerous_patterns = - ~[~"xfail-test"]; - - for dangerous_patterns.each |p| { if contains(code, *p) { return true; } } - return false; -} - -pub fn content_might_not_converge(code: &str) -> bool { - let confusing_patterns = - ~[~"xfail-test", - ~"xfail-pretty", - ~"self", // crazy rules enforced by parser not typechecker? - ~"spawn", // precedence issues? - ~"bind", // precedence issues? - ~" be ", // don't want to replace its child with a non-call: - // "Non-call expression in tail call" - ~"\n\n\n\n\n" // https://github.com/mozilla/rust/issues/850 - ]; - - for confusing_patterns.each |p| { if contains(code, *p) { return true; } } - return false; -} - -pub fn file_might_not_converge(filename: &Path) -> bool { - let confusing_files = ~[ - ~"expr-alt.rs", // pretty-printing "(a = b) = c" - // vs "a = b = c" and wrapping - ~"block-arg-in-ternary.rs", // wrapping - ~"move-3-unique.rs", // 0 becomes (0), but both seem reasonable. wtf? - ~"move-3.rs" // 0 becomes (0), but both seem reasonable. wtf? - ]; - - - for confusing_files.each |f| { - if contains(filename.to_str(), *f) { - return true; - } - } - - return false; -} - -pub fn check_roundtrip_convergence(code: @str, maxIters: uint) { - let mut i = 0u; - let mut newv = code; - let mut oldv = code; - - while i < maxIters { - oldv = newv; - if content_might_not_converge(oldv) { return; } - newv = parse_and_print(oldv); - if oldv == newv { break; } - i += 1u; - } - - if oldv == newv { - error!("Converged after %u iterations", i); - } else { - error!("Did not converge after %u iterations!", i); - write_file(&Path("round-trip-a.rs"), oldv); - write_file(&Path("round-trip-b.rs"), newv); - run::process_status("diff", [~"-w", ~"-u", ~"round-trip-a.rs", ~"round-trip-b.rs"]); - fail!("Mismatch"); - } -} - -pub fn check_convergence(files: &[Path]) { - error!("pp convergence tests: %u files", files.len()); - for files.each |file| { - if !file_might_not_converge(file) { - let s = result::get(&io::read_whole_file_str(file)).to_managed(); - if !content_might_not_converge(s) { - error!("pp converge: %s", file.to_str()); - // Change from 7u to 2u once - // https://github.com/mozilla/rust/issues/850 is fixed - check_roundtrip_convergence(s, 7u); - } - } - } -} - -pub fn check_variants(files: &[Path], cx: Context) { - for files.each |file| { - if cx.mode == tm_converge && - file_might_not_converge(file) { - error!("Skipping convergence test based on\ - file_might_not_converge"); - loop; - } - - let s = result::get(&io::read_whole_file_str(file)).to_managed(); - if s.contains_char('#') { - loop; // Macros are confusing - } - if cx.mode == tm_converge && content_might_not_converge(s) { - loop; - } - if cx.mode == tm_run && content_is_dangerous_to_compile(s) { - loop; - } - - let file_str = file.to_str(); - - error!("check_variants: %?", file_str); - let sess = parse::new_parse_sess(None); - let crate = parse::parse_crate_from_source_str(file_str.to_managed(), - s, - ~[], - sess); - io::with_str_reader(s, |rdr| { - let file_str = file_str.to_str(); - error!("%s", - as_str(|a| { - pprust::print_crate( - sess.cm, - // Assuming no token_trees - token::mk_fake_ident_interner(), - copy sess.span_diagnostic, - crate, - file_str.to_managed(), - rdr, - a, - pprust::no_ann(), - false) - })) - }); - check_variants_of_ast(crate, sess.cm, file, cx); - } -} - -pub fn main() { - let args = os::args(); - if args.len() != 2u { - error!("usage: %s ", args[0]); - return; - } - let mut files = ~[]; - let root = Path(args[1]); - - find_rust_files(&mut files, &root); - error!("== check_convergence =="); - check_convergence(files); - error!("== check_variants: converge =="); - check_variants(files, Context { mode: tm_converge }); - error!("== check_variants: run =="); - check_variants(files, Context { mode: tm_run }); - - error!("Fuzzer done"); -} - -// For bootstrapping purposes... -pub mod core { - pub use std::cmp; - pub use std::sys; -} diff --git a/src/libfuzzer/ivec_fuzz.rs b/src/libfuzzer/ivec_fuzz.rs deleted file mode 100644 index 8f019a14eedb..000000000000 --- a/src/libfuzzer/ivec_fuzz.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* - -Idea: provide functions for 'exhaustive' and 'random' modification of vecs. - - two functions, "return all edits" and "return a random edit" = move- - leaning toward this model or two functions, "return the number of - possible edits" and "return edit #n" - -It would be nice if this could be data-driven, so the two functions -could share information: - type vec_modifier = rec(fn ( v, uint i) -> ~[T] fun, uint lo, uint di); - const ~[vec_modifier] vec_modifiers = ~[rec(fun=vec_omit, 0u, 1u), ...]/~; -But that gives me "error: internal compiler error unimplemented consts -that's not a plain literal". -https://github.com/graydon/rust/issues/570 - -vec_edits is not an iter because iters might go away. - -*/ - -use std::prelude::*; - -use vec::slice; -use vec::len; - -fn vec_omit(v: ~[T], i: uint) -> ~[T] { - slice(v, 0u, i) + slice(v, i + 1u, len(v)) -} -fn vec_dup(v: ~[T], i: uint) -> ~[T] { - slice(v, 0u, i) + [v[i]] + slice(v, i, len(v)) -} -fn vec_swadj(v: ~[T], i: uint) -> ~[T] { - slice(v, 0u, i) + [v[i + 1u], v[i]] + slice(v, i + 2u, len(v)) -} -fn vec_prefix(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) } -fn vec_suffix(v: ~[T], i: uint) -> ~[T] { slice(v, i, len(v)) } - -fn vec_poke(v: ~[T], i: uint, x: T) -> ~[T] { - slice(v, 0u, i) + ~[x] + slice(v, i + 1u, len(v)) -} -fn vec_insert(v: ~[T], i: uint, x: T) -> ~[T] { - slice(v, 0u, i) + ~[x] + slice(v, i, len(v)) -} - -// Iterates over 0...length, skipping the specified number on each side. -fn ix(skip_low: uint, skip_high: uint, length: uint, it: block(uint)) { - let i: uint = skip_low; - while i + skip_high <= length { it(i); i += 1u; } -} - -// Returns a bunch of modified versions of v, some of which introduce -// new elements (borrowed from xs). -fn vec_edits(v: ~[T], xs: ~[T]) -> ~[~[T]] { - let edits: ~[~[T]] = ~[]; - let Lv: uint = len(v); - - if Lv != 1u { - // When Lv == 1u, this is redundant with omit. - edits.push(~[]); - } - if Lv >= 3u { - // When Lv == 2u, this is redundant with swap. - edits.push(vec::reversed(v)); - } - ix(0u, 1u, Lv) {|i| edits += ~[vec_omit(v, i)]; } - ix(0u, 1u, Lv) {|i| edits += ~[vec_dup(v, i)]; } - ix(0u, 2u, Lv) {|i| edits += ~[vec_swadj(v, i)]; } - ix(1u, 2u, Lv) {|i| edits += ~[vec_prefix(v, i)]; } - ix(2u, 1u, Lv) {|i| edits += ~[vec_suffix(v, i)]; } - - ix(0u, 1u, len(xs)) {|j| - ix(0u, 1u, Lv) {|i| - edits.push(vec_poke(v, i, xs[j])); - } - ix(0u, 0u, Lv) {|i| - edits.push(vec_insert(v, i, xs[j])); - } - } - - edits -} - -// Would be nice if this were built in: -// https://github.com/graydon/rust/issues/424 -fn vec_to_str(v: ~[int]) -> str { - let i = 0u; - let s = "["; - while i < len(v) { - s += int::str(v[i]); - if i + 1u < len(v) { s += ", "; } - i += 1u; - } - return s + "]"; -} - -fn show_edits(a: ~[int], xs: ~[int]) { - log(error, "=== Edits of " + vec_to_str(a) + " ==="); - let b = vec_edits(a, xs); - ix(0u, 1u, len(b)) {|i| log(error, vec_to_str(b[i])); } -} - -fn demo_edits() { - let xs = ~[7, 8]; - show_edits(~[], xs); - show_edits(~[1], xs); - show_edits(~[1, 2], xs); - show_edits(~[1, 2, 3], xs); - show_edits(~[1, 2, 3, 4], xs); -} - -fn main() { demo_edits(); } diff --git a/src/libfuzzer/rand_util.rs b/src/libfuzzer/rand_util.rs deleted file mode 100644 index abc6b1cfc0af..000000000000 --- a/src/libfuzzer/rand_util.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::prelude::*; -use extra::rand; - -// random uint less than n -fn under(r : rand::rng, n : uint) -> uint { - assert!(n != 0u); r.next() as uint % n -} - -// random choice from a vec -fn choice(r : rand::rng, v : ~[T]) -> T { - assert!(v.len() != 0u); v[under(r, v.len())] -} - -// 1 in n chance of being true -fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u } - -// shuffle a vec in place -fn shuffle(r : rand::rng, &v : ~[T]) { - let i = v.len(); - while i >= 2u { - // Loop invariant: elements with index >= i have been locked in place. - i -= 1u; - vec::swap(v, i, under(r, i + 1u)); // Lock element i in place. - } -} - -// create a shuffled copy of a vec -fn shuffled(r : rand::rng, v : ~[T]) -> ~[T] { - let w = vec::to_mut(v); - shuffle(r, w); - vec::from_mut(w) // Shouldn't this happen automatically? -} - -// sample from a population without replacement -//fn sample(r : rand::rng, pop : ~[T], k : uint) -> ~[T] { fail!() } - -// Two ways to make a weighted choice. -// * weighted_choice is O(number of choices) time -// * weighted_vec is O(total weight) space -type weighted = { weight: uint, item: T }; -fn weighted_choice(r : rand::rng, v : ~[weighted]) -> T { - assert!(v.len() != 0u); - let total = 0u; - for {weight: weight, item: _} in v { - total += weight; - } - assert!(total >= 0u); - let chosen = under(r, total); - let so_far = 0u; - for {weight: weight, item: item} in v { - so_far += weight; - if so_far > chosen { - return item; - } - } - std::unreachable(); -} - -fn weighted_vec(v : ~[weighted]) -> ~[T] { - let r = ~[]; - for {weight: weight, item: item} in v { - let i = 0u; - while i < weight { - r.push(item); - i += 1u; - } - } - r -} - -fn main() -{ - let r = rand::mk_rng(); - - log(error, under(r, 5u)); - log(error, choice(r, ~[10, 20, 30])); - log(error, if unlikely(r, 5u) { "unlikely" } else { "likely" }); - - let mut a = ~[1, 2, 3]; - shuffle(r, a); - log(error, a); - - let i = 0u; - let v = ~[ - {weight:1u, item:"low"}, - {weight:8u, item:"middle"}, - {weight:1u, item:"high"} - ]; - let w = weighted_vec(v); - - while i < 1000u { - log(error, "Immed: " + weighted_choice(r, v)); - log(error, "Fast: " + choice(r, w)); - i += 1u; - } -} From 4b18fff2be74df9a2db5ee6ab418da322ad6ae18 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 14 Jun 2013 01:39:06 +1000 Subject: [PATCH 16/96] std: convert str::{map,levdistance,subslice_offset} to methods. The first two become map_chars and lev_distance. Also, remove a few allocations in rustdoc. --- src/librustc/middle/resolve.rs | 2 +- src/librustdoc/desc_to_brief_pass.rs | 8 +- src/librustdoc/markdown_pass.rs | 6 +- src/librustdoc/sectionalize_pass.rs | 24 ++- src/librustdoc/unindent_pass.rs | 31 ++-- src/libstd/str.rs | 218 ++++++++++++++------------- src/libsyntax/parse/comments.rs | 14 +- 7 files changed, 148 insertions(+), 155 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 2803608567d2..3e656b3e5940 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4845,7 +4845,7 @@ impl Resolver { let mut smallest = 0; for maybes.eachi |i, &other| { - values[i] = str::levdistance(name, other); + values[i] = name.lev_distance(other); if values[i] <= values[smallest] { smallest = i; diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 51fea9b46b3c..d6cae1f2fa3f 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -143,11 +143,9 @@ fn first_sentence_(s: &str) -> ~str { } pub fn paragraphs(s: &str) -> ~[~str] { - let mut lines = ~[]; - for str::each_line_any(s) |line| { lines.push(line.to_owned()); } let mut whitespace_lines = 0; let mut accum = ~""; - let paras = do lines.iter().fold(~[]) |paras, line| { + let paras = do s.any_line_iter().fold(~[]) |paras, line| { let mut res = paras; if line.is_whitespace() { @@ -163,9 +161,9 @@ pub fn paragraphs(s: &str) -> ~[~str] { whitespace_lines = 0; accum = if accum.is_empty() { - copy *line + line.to_owned() } else { - accum + "\n" + *line + fmt!("%s\n%s", accum, line) } } diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 17db7c24a7c8..2e020cd9e5ad 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -22,6 +22,7 @@ use markdown_writer::WriterFactory; use pass::Pass; use sort_pass; +use core::iterator::IteratorUtil; use core::cell::Cell; use core::str; use core::vec; @@ -466,10 +467,7 @@ fn write_variant(ctxt: &Ctxt, doc: doc::VariantDoc) { } fn list_item_indent(item: &str) -> ~str { - let mut indented = ~[]; - for str::each_line_any(item) |line| { - indented.push(line); - } + let indented = item.any_line_iter().collect::<~[&str]>(); // separate markdown elements within `*` lists must be indented by four // spaces, or they will escape the list context. indenting everything diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs index 8716f823848e..c44be7f597ed 100644 --- a/src/librustdoc/sectionalize_pass.rs +++ b/src/librustdoc/sectionalize_pass.rs @@ -19,7 +19,7 @@ use fold::Fold; use fold; use pass::Pass; -use core::str; +use core::iterator::IteratorUtil; pub fn mk_pass() -> Pass { Pass { @@ -104,21 +104,19 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) { if desc.is_none() { return (None, ~[]); } - let mut lines = ~[]; - for str::each_line_any(*desc.get_ref()) |line| { lines.push(line.to_owned()); } let mut new_desc = None::<~str>; let mut current_section = None; let mut sections = ~[]; - for lines.each |line| { - match parse_header(copy *line) { + for desc.get_ref().any_line_iter().advance |line| { + match parse_header(line) { Some(header) => { if current_section.is_some() { - sections += [copy *current_section.get_ref()]; + sections.push(copy *current_section.get_ref()); } current_section = Some(doc::Section { - header: header, + header: header.to_owned(), body: ~"" }); } @@ -126,17 +124,17 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) { match copy current_section { Some(section) => { current_section = Some(doc::Section { - body: section.body + "\n" + *line, + body: fmt!("%s\n%s", section.body, line), .. section }); } None => { new_desc = match copy new_desc { Some(desc) => { - Some(desc + "\n" + *line) + Some(fmt!("%s\n%s", desc, line)) } None => { - Some(copy *line) + Some(line.to_owned()) } }; } @@ -146,15 +144,15 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) { } if current_section.is_some() { - sections += [current_section.get()]; + sections.push(current_section.unwrap()); } (new_desc, sections) } -fn parse_header(line: ~str) -> Option<~str> { +fn parse_header<'a>(line: &'a str) -> Option<&'a str> { if line.starts_with("# ") { - Some(line.slice(2u, line.len()).to_owned()) + Some(line.slice_from(2)) } else { None } diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs index caf0e5376d12..2bcf04c0262e 100644 --- a/src/librustdoc/unindent_pass.rs +++ b/src/librustdoc/unindent_pass.rs @@ -21,7 +21,6 @@ middle of a line, and each of the following lines is indented. use core::prelude::*; -use core::str; use core::uint; use pass::Pass; use text_pass; @@ -31,8 +30,7 @@ pub fn mk_pass() -> Pass { } fn unindent(s: &str) -> ~str { - let mut lines = ~[]; - for str::each_line_any(s) |line| { lines.push(line.to_owned()); } + let lines = s.any_line_iter().collect::<~[&str]>(); let mut saw_first_line = false; let mut saw_second_line = false; let min_indent = do lines.iter().fold(uint::max_value) @@ -76,19 +74,20 @@ fn unindent(s: &str) -> ~str { } }; - if !lines.is_empty() { - let unindented = ~[lines.head().trim().to_owned()] - + do lines.tail().map |line| { - if line.is_whitespace() { - copy *line - } else { - assert!(line.len() >= min_indent); - line.slice(min_indent, line.len()).to_owned() - } - }; - unindented.connect("\n") - } else { - s.to_str() + match lines { + [head, .. tail] => { + let mut unindented = ~[ head.trim() ]; + unindented.push_all(do tail.map |&line| { + if line.is_whitespace() { + line + } else { + assert!(line.len() >= min_indent); + line.slice_from(min_indent) + } + }); + unindented.connect("\n") + } + [] => s.to_owned() } } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 1086fcaa75cf..fbdbb1b3f74b 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -26,7 +26,7 @@ use clone::Clone; use cmp::{TotalOrd, Ordering, Less, Equal, Greater}; use container::Container; use iter::Times; -use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator}; +use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIterator}; use libc; use option::{None, Option, Some}; use old_iter::{BaseIter, EqIter}; @@ -291,6 +291,10 @@ pub type WordIterator<'self> = FilterIterator<'self, &'self str, StrCharSplitIterator<'self, extern "Rust" fn(char) -> bool>>; +/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`). +pub type AnyLineIterator<'self> = + MapIterator<'self, &'self str, &'self str, StrCharSplitIterator<'self, char>>; + impl<'self, Sep: CharEq> Iterator<&'self str> for StrCharSplitIterator<'self, Sep> { #[inline] fn next(&mut self) -> Option<&'self str> { @@ -400,56 +404,6 @@ impl<'self> Iterator<&'self str> for StrStrSplitIterator<'self> { } } -/// Levenshtein Distance between two strings -pub fn levdistance(s: &str, t: &str) -> uint { - - let slen = s.len(); - let tlen = t.len(); - - if slen == 0 { return tlen; } - if tlen == 0 { return slen; } - - let mut dcol = vec::from_fn(tlen + 1, |x| x); - - for s.iter().enumerate().advance |(i, sc)| { - - let mut current = i; - dcol[0] = current + 1; - - for t.iter().enumerate().advance |(j, tc)| { - - let next = dcol[j + 1]; - - if sc == tc { - dcol[j + 1] = current; - } else { - dcol[j + 1] = ::cmp::min(current, next); - dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1; - } - - current = next; - } - } - - return dcol[tlen]; -} - -/** - * Splits a string into substrings separated by LF ('\n') - * and/or CR LF ("\r\n") - */ -pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { - for s.line_iter().advance |s| { - let l = s.len(); - if l > 0u && s[l - 1u] == '\r' as u8 { - if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return false; } - } else { - if !it( s ) { return false; } - } - } - return true; -} - /** Splits a string into substrings with possibly internal whitespace, * each of them at most `lim` bytes long. The substrings have leading and trailing * whitespace removed, and are only cut at whitespace boundaries. @@ -751,21 +705,6 @@ impl<'self, S: Str> Equiv for ~str { fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } } - -/* -Section: Iterating through strings -*/ - -/// Apply a function to each character -pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str { - let mut result = ~""; - result.reserve(ss.len()); - for ss.iter().advance |cc| { - result.push_char(ff(cc)); - } - result -} - /* Section: Searching */ @@ -989,40 +928,6 @@ pub fn as_buf(s: &str, f: &fn(*u8, uint) -> T) -> T { } } -/** - * Returns the byte offset of an inner slice relative to an enclosing outer slice - * - * # Example - * - * ~~~ {.rust} - * let string = "a\nb\nc"; - * let mut lines = ~[]; - * for string.line_iter().advance |line| { lines.push(line) } - * - * assert!(subslice_offset(string, lines[0]) == 0); // &"a" - * assert!(subslice_offset(string, lines[1]) == 2); // &"b" - * assert!(subslice_offset(string, lines[2]) == 4); // &"c" - * ~~~ - */ -#[inline(always)] -pub fn subslice_offset(outer: &str, inner: &str) -> uint { - do as_buf(outer) |a, a_len| { - do as_buf(inner) |b, b_len| { - let a_start: uint; - let a_end: uint; - let b_start: uint; - let b_end: uint; - unsafe { - a_start = cast::transmute(a); a_end = a_len + cast::transmute(a); - b_start = cast::transmute(b); b_end = b_len + cast::transmute(b); - } - assert!(a_start <= b_start); - assert!(b_end <= a_end); - b_start - a_start - } - } -} - /// Unsafe operations pub mod raw { use cast; @@ -1256,6 +1161,7 @@ pub trait StrSlice<'self> { fn matches_index_iter(&self, sep: &'self str) -> StrMatchesIndexIterator<'self>; fn split_str_iter(&self, &'self str) -> StrStrSplitIterator<'self>; fn line_iter(&self) -> StrCharSplitIterator<'self, char>; + fn any_line_iter(&self) -> AnyLineIterator<'self>; fn word_iter(&self) -> WordIterator<'self>; fn ends_with(&self, needle: &str) -> bool; fn is_empty(&self) -> bool; @@ -1296,6 +1202,12 @@ pub trait StrSlice<'self> { fn repeat(&self, nn: uint) -> ~str; fn slice_shift_char(&self) -> (char, &'self str); + + fn map_chars(&self, ff: &fn(char) -> char) -> ~str; + + fn lev_distance(&self, t: &str) -> uint; + + fn subslice_offset(&self, inner: &str) -> uint; } /// Extension methods for strings @@ -1437,6 +1349,17 @@ impl<'self> StrSlice<'self> for &'self str { fn line_iter(&self) -> StrCharSplitIterator<'self, char> { self.split_options_iter('\n', self.len(), false) } + + /// An iterator over the lines of a string, separated by either + /// `\n` or (`\r\n`). + fn any_line_iter(&self) -> AnyLineIterator<'self> { + do self.line_iter().transform |line| { + let l = line.len(); + if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) } + else { line } + } + } + /// An iterator over the words of a string (subsequences separated /// by any sequence of whitespace). #[inline] @@ -1921,6 +1844,85 @@ impl<'self> StrSlice<'self> for &'self str { } + /// Apply a function to each character. + fn map_chars(&self, ff: &fn(char) -> char) -> ~str { + let mut result = with_capacity(self.len()); + for self.iter().advance |cc| { + result.push_char(ff(cc)); + } + result + } + + /// Levenshtein Distance between two strings. + fn lev_distance(&self, t: &str) -> uint { + let slen = self.len(); + let tlen = t.len(); + + if slen == 0 { return tlen; } + if tlen == 0 { return slen; } + + let mut dcol = vec::from_fn(tlen + 1, |x| x); + + for self.iter().enumerate().advance |(i, sc)| { + + let mut current = i; + dcol[0] = current + 1; + + for t.iter().enumerate().advance |(j, tc)| { + + let next = dcol[j + 1]; + + if sc == tc { + dcol[j + 1] = current; + } else { + dcol[j + 1] = ::cmp::min(current, next); + dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1; + } + + current = next; + } + } + + return dcol[tlen]; + } + + + /** + * Returns the byte offset of an inner slice relative to an enclosing outer slice. + * + * Fails if `inner` is not a direct slice contained within self. + * + * # Example + * + * ~~~ {.rust} + * let string = "a\nb\nc"; + * let mut lines = ~[]; + * for string.line_iter().advance |line| { lines.push(line) } + * + * assert!(string.subslice_offset(lines[0]) == 0); // &"a" + * assert!(string.subslice_offset(lines[1]) == 2); // &"b" + * assert!(string.subslice_offset(lines[2]) == 4); // &"c" + * ~~~ + */ + #[inline(always)] + fn subslice_offset(&self, inner: &str) -> uint { + do as_buf(*self) |a, a_len| { + do as_buf(inner) |b, b_len| { + let a_start: uint; + let a_end: uint; + let b_start: uint; + let b_end: uint; + unsafe { + a_start = cast::transmute(a); a_end = a_len + cast::transmute(a); + b_start = cast::transmute(b); b_end = b_len + cast::transmute(b); + } + assert!(a_start <= b_start); + assert!(b_end <= a_end); + b_start - a_start + } + } + } + } #[allow(missing_doc)] @@ -3003,15 +3005,15 @@ mod tests { let a = "kernelsprite"; let b = a.slice(7, a.len()); let c = a.slice(0, a.len() - 6); - assert_eq!(subslice_offset(a, b), 7); - assert_eq!(subslice_offset(a, c), 0); + assert_eq!(a.subslice_offset(b), 7); + assert_eq!(a.subslice_offset(c), 0); let string = "a\nb\nc"; let mut lines = ~[]; for string.line_iter().advance |line| { lines.push(line) } - assert_eq!(subslice_offset(string, lines[0]), 0); - assert_eq!(subslice_offset(string, lines[1]), 2); - assert_eq!(subslice_offset(string, lines[2]), 4); + assert_eq!(string.subslice_offset(lines[0]), 0); + assert_eq!(string.subslice_offset(lines[1]), 2); + assert_eq!(string.subslice_offset(lines[2]), 4); } #[test] @@ -3019,7 +3021,7 @@ mod tests { fn test_subslice_offset_2() { let a = "alchemiter"; let b = "cruxtruder"; - subslice_offset(a, b); + a.subslice_offset(b); } #[test] @@ -3069,8 +3071,8 @@ mod tests { #[test] fn test_map() { - assert_eq!(~"", map("", |c| unsafe {libc::toupper(c as c_char)} as char)); - assert_eq!(~"YMCA", map("ymca", |c| unsafe {libc::toupper(c as c_char)} as char)); + assert_eq!(~"", "".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char)); + assert_eq!(~"YMCA", "ymca".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char)); } #[test] diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 68473f11537d..82a7b55eeeec 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -89,12 +89,11 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { } return do lines.map |line| { - let mut chars = ~[]; - for line.iter().advance |c| { chars.push(c) } + let chars = line.iter().collect::<~[char]>(); if i > chars.len() { ~"" } else { - str::from_chars(chars.slice(i, chars.len()).to_owned()) + str::from_chars(chars.slice(i, chars.len())) } }; } @@ -103,14 +102,13 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { // FIXME #5475: // return comment.slice(3u, comment.len()).trim().to_owned(); let r = comment.slice(3u, comment.len()); return r.trim().to_owned(); - } if comment.starts_with("/*") { - let mut lines = ~[]; - for str::each_line_any(comment.slice(3u, comment.len() - 2u)) |line| { - lines.push(line.to_owned()) - } + let lines = comment.slice(3u, comment.len() - 2u) + .any_line_iter() + .transform(|s| s.to_owned()) + .collect::<~[~str]>(); let lines = vertical_trim(lines); let lines = block_trim(lines, ~"\t ", None); let lines = block_trim(lines, ~"*", Some(1u)); From f1886680e00850843e2524fba609ddba6a13180b Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 14 Jun 2013 01:44:15 +1000 Subject: [PATCH 17/96] std: convert str::to_utf16 to a method. --- src/libstd/os.rs | 2 +- src/libstd/str.rs | 55 ++++++++++++++++++++++++----------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 044b305a0dd9..115729571986 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -144,7 +144,7 @@ pub mod win32 { } pub fn as_utf16_p(s: &str, f: &fn(*u16) -> T) -> T { - let mut t = str::to_utf16(s); + let mut t = s.to_utf16(); // Null terminate before passing on. t += [0u16]; vec::as_imm_buf(t, |buf, _len| f(buf)) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index fbdbb1b3f74b..d5beb755a27d 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -759,30 +759,6 @@ pub fn is_utf16(v: &[u16]) -> bool { return true; } -/// Converts to a vector of `u16` encoded as UTF-16 -pub fn to_utf16(s: &str) -> ~[u16] { - let mut u = ~[]; - for s.iter().advance |ch| { - // Arithmetic with u32 literals is easier on the eyes than chars. - let mut ch = ch as u32; - - if (ch & 0xFFFF_u32) == ch { - // The BMP falls through (assuming non-surrogate, as it - // should) - assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32); - u.push(ch as u16) - } else { - // Supplementary planes break into surrogates. - assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32); - ch -= 0x1_0000_u32; - let w1 = 0xD800_u16 | ((ch >> 10) as u16); - let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16); - u.push_all([w1, w2]) - } - } - u -} - /// Iterates over the utf-16 characters in the specified slice, yielding each /// decoded unicode character to the function provided. /// @@ -1188,6 +1164,7 @@ pub trait StrSlice<'self> { fn replace(&self, from: &str, to: &str) -> ~str; fn to_owned(&self) -> ~str; fn to_managed(&self) -> @str; + fn to_utf16(&self) -> ~[u16]; fn is_char_boundary(&self, index: uint) -> bool; fn char_range_at(&self, start: uint) -> CharRange; fn char_at(&self, i: uint) -> char; @@ -1602,6 +1579,30 @@ impl<'self> StrSlice<'self> for &'self str { unsafe { ::cast::transmute(v) } } + /// Converts to a vector of `u16` encoded as UTF-16. + fn to_utf16(&self) -> ~[u16] { + let mut u = ~[]; + for self.iter().advance |ch| { + // Arithmetic with u32 literals is easier on the eyes than chars. + let mut ch = ch as u32; + + if (ch & 0xFFFF_u32) == ch { + // The BMP falls through (assuming non-surrogate, as it + // should) + assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32); + u.push(ch as u16) + } else { + // Supplementary planes break into surrogates. + assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32); + ch -= 0x1_0000_u32; + let w1 = 0xD800_u16 | ((ch >> 10) as u16); + let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16); + u.push_all([w1, w2]) + } + } + u + } + /** * Returns false if the index points into the middle of a multi-byte * character sequence. @@ -3116,10 +3117,10 @@ mod tests { for pairs.each |p| { let (s, u) = copy *p; - assert!(to_utf16(s) == u); + assert!(s.to_utf16() == u); assert!(from_utf16(u) == s); - assert!(from_utf16(to_utf16(s)) == s); - assert!(to_utf16(from_utf16(u)) == u); + assert!(from_utf16(s.to_utf16()) == s); + assert!(from_utf16(u).to_utf16() == u); } } From 42974d3bc4ee091c6d6c586ff3c8568231290cd8 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 14 Jun 2013 01:54:40 +1000 Subject: [PATCH 18/96] std: simplify the string comparison implementations, using iterators. --- src/libstd/str.rs | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index d5beb755a27d..1f823a078c4f 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -530,54 +530,38 @@ pub fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } -#[inline] -fn cmp(a: &str, b: &str) -> Ordering { - let low = uint::min(a.len(), b.len()); - - for uint::range(0, low) |idx| { - match a[idx].cmp(&b[idx]) { - Greater => return Greater, - Less => return Less, - Equal => () - } - } - - a.len().cmp(&b.len()) -} - #[cfg(not(test))] impl<'self> TotalOrd for &'self str { #[inline] - fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: & &'self str) -> Ordering { + for self.bytes_iter().zip(other.bytes_iter()).advance |(s_b, o_b)| { + match s_b.cmp(&o_b) { + Greater => return Greater, + Less => return Less, + Equal => () + } + } + + self.len().cmp(&other.len()) + } } #[cfg(not(test))] impl TotalOrd for ~str { #[inline] - fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } } #[cfg(not(test))] impl TotalOrd for @str { #[inline] - fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) } + fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } } /// Bytewise slice less than #[inline] fn lt(a: &str, b: &str) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - let end = uint::min(a_len, b_len); - - let mut i = 0; - while i < end { - let (c_a, c_b) = (a[i], b[i]); - if c_a < c_b { return true; } - if c_a > c_b { return false; } - i += 1; - } - - return a_len < b_len; + a.cmp(& b) == Less } /// Bytewise less than or equal From 4686ed1a1d6e85d2c17fd67fdf4be597c701d141 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 14 Jun 2013 13:37:47 +1000 Subject: [PATCH 19/96] std: continue improving the comparison trait impls for str. This moves them all into the traits submodule, and delegates Ord to the TotalOrd instance. It also deletes the stand-alone lt, gt, ge and le functions. --- src/libextra/test.rs | 3 +- src/libstd/str.rs | 294 +++++++++++++++++++------------------------ 2 files changed, 129 insertions(+), 168 deletions(-) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 406dfb086eac..7050fe704633 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -26,7 +26,6 @@ use core::either; use core::io; use core::option; use core::result; -use core::str; use core::task; use core::to_str::ToStr; use core::uint; @@ -542,7 +541,7 @@ pub fn filter_tests( // Sort the tests alphabetically fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool { - str::le(t1.desc.name.to_str(), t2.desc.name.to_str()) + t1.desc.name.to_str() < t2.desc.name.to_str() } sort::quick_sort(filtered, lteq); diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 1f823a078c4f..89d497177dc4 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -23,7 +23,6 @@ use cast; use char; use char::Char; use clone::Clone; -use cmp::{TotalOrd, Ordering, Less, Equal, Greater}; use container::Container; use iter::Times; use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIterator}; @@ -37,8 +36,6 @@ use uint; use vec; use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector}; -#[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq}; - /* Section: Conditions */ @@ -530,165 +527,6 @@ pub fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } -#[cfg(not(test))] -impl<'self> TotalOrd for &'self str { - #[inline] - fn cmp(&self, other: & &'self str) -> Ordering { - for self.bytes_iter().zip(other.bytes_iter()).advance |(s_b, o_b)| { - match s_b.cmp(&o_b) { - Greater => return Greater, - Less => return Less, - Equal => () - } - } - - self.len().cmp(&other.len()) - } -} - -#[cfg(not(test))] -impl TotalOrd for ~str { - #[inline] - fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } -} - -#[cfg(not(test))] -impl TotalOrd for @str { - #[inline] - fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } -} - -/// Bytewise slice less than -#[inline] -fn lt(a: &str, b: &str) -> bool { - a.cmp(& b) == Less -} - -/// Bytewise less than or equal -#[inline] -pub fn le(a: &str, b: &str) -> bool { - !lt(b, a) -} - -/// Bytewise greater than or equal -#[inline] -fn ge(a: &str, b: &str) -> bool { - !lt(a, b) -} - -/// Bytewise greater than -#[inline] -fn gt(a: &str, b: &str) -> bool { - !le(a, b) -} - -#[cfg(not(test))] -impl<'self> Eq for &'self str { - #[inline(always)] - fn eq(&self, other: & &'self str) -> bool { - eq_slice((*self), (*other)) - } - #[inline(always)] - fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) } -} - -#[cfg(not(test))] -impl Eq for ~str { - #[inline(always)] - fn eq(&self, other: &~str) -> bool { - eq_slice((*self), (*other)) - } - #[inline(always)] - fn ne(&self, other: &~str) -> bool { !(*self).eq(other) } -} - -#[cfg(not(test))] -impl Eq for @str { - #[inline(always)] - fn eq(&self, other: &@str) -> bool { - eq_slice((*self), (*other)) - } - #[inline(always)] - fn ne(&self, other: &@str) -> bool { !(*self).eq(other) } -} - -#[cfg(not(test))] -impl<'self> TotalEq for &'self str { - #[inline(always)] - fn equals(&self, other: & &'self str) -> bool { - eq_slice((*self), (*other)) - } -} - -#[cfg(not(test))] -impl TotalEq for ~str { - #[inline(always)] - fn equals(&self, other: &~str) -> bool { - eq_slice((*self), (*other)) - } -} - -#[cfg(not(test))] -impl TotalEq for @str { - #[inline(always)] - fn equals(&self, other: &@str) -> bool { - eq_slice((*self), (*other)) - } -} - -#[cfg(not(test))] -impl Ord for ~str { - #[inline(always)] - fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) } - #[inline(always)] - fn le(&self, other: &~str) -> bool { le((*self), (*other)) } - #[inline(always)] - fn ge(&self, other: &~str) -> bool { ge((*self), (*other)) } - #[inline(always)] - fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl<'self> Ord for &'self str { - #[inline(always)] - fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) } - #[inline(always)] - fn le(&self, other: & &'self str) -> bool { le((*self), (*other)) } - #[inline(always)] - fn ge(&self, other: & &'self str) -> bool { ge((*self), (*other)) } - #[inline(always)] - fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl Ord for @str { - #[inline(always)] - fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) } - #[inline(always)] - fn le(&self, other: &@str) -> bool { le((*self), (*other)) } - #[inline(always)] - fn ge(&self, other: &@str) -> bool { ge((*self), (*other)) } - #[inline(always)] - fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) } -} - -#[cfg(not(test))] -impl<'self, S: Str> Equiv for &'self str { - #[inline(always)] - fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } -} -#[cfg(not(test))] -impl<'self, S: Str> Equiv for @str { - #[inline(always)] - fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } -} - -#[cfg(not(test))] -impl<'self, S: Str> Equiv for ~str { - #[inline(always)] - fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } -} - /* Section: Searching */ @@ -1072,12 +910,136 @@ pub mod raw { #[cfg(not(test))] pub mod traits { use ops::Add; + use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq}; + use super::{Str, eq_slice}; + impl<'self> Add<&'self str,~str> for ~str { #[inline(always)] fn add(&self, rhs: & &'self str) -> ~str { self.append((*rhs)) } } + + impl<'self> TotalOrd for &'self str { + #[inline] + fn cmp(&self, other: & &'self str) -> Ordering { + for self.bytes_iter().zip(other.bytes_iter()).advance |(s_b, o_b)| { + match s_b.cmp(&o_b) { + Greater => return Greater, + Less => return Less, + Equal => () + } + } + + self.len().cmp(&other.len()) + } + } + + impl TotalOrd for ~str { + #[inline] + fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } + + impl TotalOrd for @str { + #[inline] + fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } + + impl<'self> Eq for &'self str { + #[inline(always)] + fn eq(&self, other: & &'self str) -> bool { + eq_slice((*self), (*other)) + } + #[inline(always)] + fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) } + } + + impl Eq for ~str { + #[inline(always)] + fn eq(&self, other: &~str) -> bool { + eq_slice((*self), (*other)) + } + #[inline(always)] + fn ne(&self, other: &~str) -> bool { !(*self).eq(other) } + } + + impl Eq for @str { + #[inline(always)] + fn eq(&self, other: &@str) -> bool { + eq_slice((*self), (*other)) + } + #[inline(always)] + fn ne(&self, other: &@str) -> bool { !(*self).eq(other) } + } + + impl<'self> TotalEq for &'self str { + #[inline(always)] + fn equals(&self, other: & &'self str) -> bool { + eq_slice((*self), (*other)) + } + } + + impl TotalEq for ~str { + #[inline(always)] + fn equals(&self, other: &~str) -> bool { + eq_slice((*self), (*other)) + } + } + + impl TotalEq for @str { + #[inline(always)] + fn equals(&self, other: &@str) -> bool { + eq_slice((*self), (*other)) + } + } + + impl<'self> Ord for &'self str { + #[inline(always)] + fn lt(&self, other: & &'self str) -> bool { self.cmp(other) == Less } + #[inline(always)] + fn le(&self, other: & &'self str) -> bool { self.cmp(other) != Greater } + #[inline(always)] + fn ge(&self, other: & &'self str) -> bool { self.cmp(other) != Less } + #[inline(always)] + fn gt(&self, other: & &'self str) -> bool { self.cmp(other) == Greater } + } + + impl Ord for ~str { + #[inline(always)] + fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less } + #[inline(always)] + fn le(&self, other: &~str) -> bool { self.cmp(other) != Greater } + #[inline(always)] + fn ge(&self, other: &~str) -> bool { self.cmp(other) != Less } + #[inline(always)] + fn gt(&self, other: &~str) -> bool { self.cmp(other) == Greater } + } + + impl Ord for @str { + #[inline(always)] + fn lt(&self, other: &@str) -> bool { self.cmp(other) == Less } + #[inline(always)] + fn le(&self, other: &@str) -> bool { self.cmp(other) != Greater } + #[inline(always)] + fn ge(&self, other: &@str) -> bool { self.cmp(other) != Less } + #[inline(always)] + fn gt(&self, other: &@str) -> bool { self.cmp(other) == Greater } + } + + impl<'self, S: Str> Equiv for &'self str { + #[inline(always)] + fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } + } + + impl<'self, S: Str> Equiv for @str { + #[inline(always)] + fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } + } + + impl<'self, S: Str> Equiv for ~str { + #[inline(always)] + fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } + } } #[cfg(test)] @@ -2267,10 +2229,10 @@ mod tests { #[test] fn test_le() { - assert!((le(&"", &""))); - assert!((le(&"", &"foo"))); - assert!((le(&"foo", &"foo"))); - assert!((!eq(&~"foo", &~"bar"))); + assert!("" <= ""); + assert!("" <= "foo"); + assert!("foo" <= "foo"); + assert!("foo" != ~"bar"); } #[test] From ee25cf8d75671415e74ff3fe1a3c0ba42e35396a Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 14 Jun 2013 13:43:05 +1000 Subject: [PATCH 20/96] std: test-fixes, remove warnings, syntax highlighting for code examples. --- src/compiletest/runtest.rs | 1 - src/librustdoc/astsrv.rs | 2 -- src/librustdoc/desc_to_brief_pass.rs | 8 +++----- src/librustdoc/extract.rs | 2 -- src/librustdoc/markdown_pass.rs | 2 -- src/librustdoc/page_pass.rs | 1 - src/librustdoc/prune_hidden_pass.rs | 2 -- src/librustdoc/prune_private_pass.rs | 1 - src/librustdoc/sectionalize_pass.rs | 3 --- src/libstd/path.rs | 12 ++++++------ src/libstd/str.rs | 6 +++--- 11 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 891935dcadd0..e0ceb79a37df 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -24,7 +24,6 @@ use util::logv; use core::io; use core::os; -use core::str; use core::uint; use core::vec; diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index 9d8f750a3500..3775aafb5696 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -32,8 +32,6 @@ use syntax::ast; use syntax::ast_map; use syntax; -#[cfg(test)] use core::vec; - pub struct Ctxt { ast: @ast::crate, ast_map: ast_map::map diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index d6cae1f2fa3f..dc7621f98a09 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -129,14 +129,12 @@ fn first_sentence_(s: &str) -> ~str { } }); match idx { - Some(idx) if idx > 2u => { - str::to_owned(s.slice(0, idx - 1)) - } + Some(idx) if idx > 2u => s.slice(0, idx - 1).to_owned(), _ => { if s.ends_with(".") { - str::to_owned(s) + s.to_owned() } else { - str::to_owned(s) + s.to_owned() } } } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index f4b6ae8fb32a..f8c49f544bc2 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -285,8 +285,6 @@ mod test { use extract::{extract, from_srv}; use parse; - use core::vec; - fn mk_doc(source: @str) -> doc::Doc { let ast = parse::from_str(source); extract(ast, ~"") diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 2e020cd9e5ad..36df3a5267d4 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -537,8 +537,6 @@ mod test { use tystr_pass; use unindent_pass; - use core::str; - fn render(source: ~str) -> ~str { let (srv, doc) = create_doc_srv(source); let markdown = write_markdown_str_srv(srv, doc); diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index bb5d71e8db16..584e6ccc8873 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -157,7 +157,6 @@ mod test { use doc; use extract; use page_pass::run; - use core::vec; fn mk_doc_( output_style: config::OutputStyle, diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs index 8a90d3f74d39..484eb8c7980d 100644 --- a/src/librustdoc/prune_hidden_pass.rs +++ b/src/librustdoc/prune_hidden_pass.rs @@ -77,8 +77,6 @@ mod test { #[test] fn should_prune_hidden_items() { - use core::vec; - let doc = mk_doc(~"#[doc(hidden)] mod a { }"); assert!(doc.cratemod().mods().is_empty()) } diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index e861939c2dde..741da3e265ee 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -162,7 +162,6 @@ mod test { use extract; use tystr_pass; use prune_private_pass::run; - use core::vec; fn mk_doc(source: ~str) -> doc::Doc { do astsrv::from_str(copy source) |srv| { diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs index c44be7f597ed..ba433bf479d2 100644 --- a/src/librustdoc/sectionalize_pass.rs +++ b/src/librustdoc/sectionalize_pass.rs @@ -170,9 +170,6 @@ mod test { use extract; use sectionalize_pass::run; - use core::str; - use core::vec; - fn mk_doc(source: ~str) -> doc::Doc { do astsrv::from_str(copy source) |srv| { let doc = extract::from_srv(srv.clone(), ~""); diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 400657d0c255..99a7a461ab24 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -515,7 +515,7 @@ impl GenericPath for PosixPath { fn with_filestem(&self, s: &str) -> PosixPath { match self.filetype() { None => self.with_filename(s), - Some(ref t) => self.with_filename(str::to_owned(s) + *t), + Some(ref t) => self.with_filename(s.to_owned() + *t), } } @@ -657,7 +657,7 @@ impl GenericPath for WindowsPath { (None, None) => { host = None; device = None; - rest = str::to_owned(s); + rest = s.to_owned(); } } @@ -729,7 +729,7 @@ impl GenericPath for WindowsPath { fn with_filestem(&self, s: &str) -> WindowsPath { match self.filetype() { None => self.with_filename(s), - Some(ref t) => self.with_filename(str::to_owned(s) + *t), + Some(ref t) => self.with_filename(s.to_owned() + *t), } } @@ -984,7 +984,7 @@ mod tests { fn test_posix_paths() { fn t(wp: &PosixPath, s: &str) { let ss = wp.to_str(); - let sss = str::to_owned(s); + let sss = s.to_owned(); if (ss != sss) { debug!("got %s", ss); debug!("expected %s", sss); @@ -1042,7 +1042,7 @@ mod tests { fn test_normalize() { fn t(wp: &PosixPath, s: &str) { let ss = wp.to_str(); - let sss = str::to_owned(s); + let sss = s.to_owned(); if (ss != sss) { debug!("got %s", ss); debug!("expected %s", sss); @@ -1105,7 +1105,7 @@ mod tests { fn test_windows_paths() { fn t(wp: &WindowsPath, s: &str) { let ss = wp.to_str(); - let sss = str::to_owned(s); + let sss = s.to_owned(); if (ss != sss) { debug!("got %s", ss); debug!("expected %s", sss); diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 89d497177dc4..1ab07003b6ea 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -1432,7 +1432,7 @@ impl<'self> StrSlice<'self> for &'self str { * * # Example * - * ~~~ + * ~~~ {.rust} * assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar") * assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar") * assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar") @@ -1451,7 +1451,7 @@ impl<'self> StrSlice<'self> for &'self str { * * # Example * - * ~~~ + * ~~~ {.rust} * assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11") * assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12") * assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123") @@ -1473,7 +1473,7 @@ impl<'self> StrSlice<'self> for &'self str { * * # Example * - * ~~~ + * ~~~ {.rust} * assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar") * assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar") * assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar") From 30973ccb9041a5035cdb24b382a0d5634ccc9e2e Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 15 Jun 2013 23:17:53 +1000 Subject: [PATCH 21/96] std: allow any sort of string to be Added with +. --- src/librusti/rusti.rc | 2 +- src/libstd/str.rs | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 06ec6769385c..0af6ed724e1d 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -370,7 +370,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, if arg.ends_with(".rs") || arg.ends_with(".rc") { (arg.slice_to(arg.len() - 3).to_owned(), copy *arg) } else { - (copy *arg, arg + ".rs") + (copy *arg, *arg + ".rs") }; match compile_crate(filename, copy repl.binary) { Some(_) => loaded_crates.push(crate), diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 1ab07003b6ea..21f747317f4a 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -913,10 +913,12 @@ pub mod traits { use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq}; use super::{Str, eq_slice}; - impl<'self> Add<&'self str,~str> for ~str { + impl<'self> Add<&'self str,~str> for &'self str { #[inline(always)] fn add(&self, rhs: & &'self str) -> ~str { - self.append((*rhs)) + let mut ret = self.to_owned(); + ret.push_str(*rhs); + ret } } @@ -3137,6 +3139,24 @@ mod tests { assert_eq!("abc".char_range_at_reverse(0).next, 0); } + #[test] + fn test_add() { + macro_rules! t ( + ($s1:expr, $s2:expr, $e:expr) => { + assert_eq!($s1 + $s2, $e); + assert_eq!($s1.to_owned() + $s2, $e); + assert_eq!($s1.to_managed() + $s2, $e); + } + ); + + t!("foo", "bar", ~"foobar"); + t!("foo", @"bar", ~"foobar"); + t!("foo", ~"bar", ~"foobar"); + t!("ศไทย中", "华Việt Nam", ~"ศไทย中华Việt Nam"); + t!("ศไทย中", @"华Việt Nam", ~"ศไทย中华Việt Nam"); + t!("ศไทย中", ~"华Việt Nam", ~"ศไทย中华Việt Nam"); + } + #[test] fn test_iterator() { use iterator::*; From 6c547e42c859b1b0051293c48c691d8388bad332 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 02:20:06 -0400 Subject: [PATCH 22/96] rm vec::uniq_len --- src/libextra/flatpipes.rs | 8 +++----- src/libextra/net_tcp.rs | 5 ++--- src/libextra/priority_queue.rs | 4 ++-- src/libextra/sha1.rs | 2 +- src/libextra/smallintmap.rs | 10 +++++----- src/libextra/test.rs | 2 +- src/libstd/comm.rs | 2 +- src/libstd/container.rs | 4 ++-- src/libstd/io.rs | 2 +- src/libstd/repr.rs | 5 +++-- src/libstd/rt/io/extensions.rs | 3 ++- src/libstd/vec.rs | 28 ++++++++++++++++------------ 12 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index c0f619c1b858..4ff67fc3f42c 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -583,12 +583,12 @@ pub mod bytepipes { impl BytePort for PipeBytePort { fn try_recv(&self, count: uint) -> Option<~[u8]> { - if vec::uniq_len(&const *self.buf) >= count { + if self.buf.len() >= count { let mut bytes = ::core::util::replace(&mut *self.buf, ~[]); *self.buf = bytes.slice(count, bytes.len()).to_owned(); bytes.truncate(count); return Some(bytes); - } else if vec::uniq_len(&const *self.buf) > 0 { + } else if !self.buf.is_empty() { let mut bytes = ::core::util::replace(&mut *self.buf, ~[]); assert!(count > bytes.len()); match self.try_recv(count - bytes.len()) { @@ -598,7 +598,7 @@ pub mod bytepipes { } None => return None } - } else if vec::uniq_len(&const *self.buf) == 0 { + } else /* empty */ { match self.port.try_recv() { Some(buf) => { assert!(!buf.is_empty()); @@ -607,8 +607,6 @@ pub mod bytepipes { } None => return None } - } else { - ::core::util::unreachable() } } } diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index d95807f2b91c..28b3700399a6 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -879,8 +879,7 @@ impl io::Reader for TcpSocketBuf { // If possible, copy up to `len` bytes from the internal // `data.buf` into `buf` - let nbuffered = vec::uniq_len(&const self.data.buf) - - self.data.buf_off; + let nbuffered = self.data.buf.len() - self.data.buf_off; let needed = len - count; if nbuffered > 0 { unsafe { @@ -934,7 +933,7 @@ impl io::Reader for TcpSocketBuf { } fn read_byte(&self) -> int { loop { - if vec::uniq_len(&const self.data.buf) > self.data.buf_off { + if self.data.buf.len() > self.data.buf_off { let c = self.data.buf[self.data.buf_off]; self.data.buf_off += 1; return c as int diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 601b7685f3ca..efbf23f11b15 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -35,10 +35,10 @@ impl BaseIter for PriorityQueue { impl Container for PriorityQueue { /// Returns the length of the queue - fn len(&const self) -> uint { vec::uniq_len(&const self.data) } + fn len(&self) -> uint { self.data.len() } /// Returns true if a queue contains no elements - fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&self) -> bool { self.len() == 0 } } impl Mutable for PriorityQueue { diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs index 908e497b9591..0c35630345b4 100644 --- a/src/libextra/sha1.rs +++ b/src/libextra/sha1.rs @@ -93,7 +93,7 @@ pub fn sha1() -> @Sha1 { } fn process_msg_block(st: &mut Sha1State) { assert_eq!(st.h.len(), digest_buf_len); - assert_eq!(vec::uniq_len(st.work_buf), work_buf_len); + assert_eq!(st.work_buf.len(), work_buf_len); let mut t: int; // Loop counter let w = st.work_buf; diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 7f566bc16e73..dae9113b3a9d 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -32,9 +32,9 @@ pub struct SmallIntMap { impl Container for SmallIntMap { /// Return the number of elements in the map - fn len(&const self) -> uint { + fn len(&self) -> uint { let mut sz = 0; - for uint::range(0, vec::uniq_len(&const self.v)) |i| { + for uint::range(0, self.v.len()) |i| { match self.v[i] { Some(_) => sz += 1, None => {} @@ -44,7 +44,7 @@ impl Container for SmallIntMap { } /// Return true if the map contains no elements - fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&self) -> bool { self.len() == 0 } } impl Mutable for SmallIntMap { @@ -199,12 +199,12 @@ pub struct SmallIntSet { impl Container for SmallIntSet { /// Return the number of elements in the map - fn len(&const self) -> uint { + fn len(&self) -> uint { self.map.len() } /// Return true if the map contains no elements - fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&self) -> bool { self.len() == 0 } } impl Mutable for SmallIntSet { diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 406dfb086eac..a465cef09e6b 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -365,7 +365,7 @@ pub fn run_tests_console(opts: &TestOpts, fn print_failures(st: &ConsoleTestState) { st.out.write_line("\nfailures:"); let mut failures = ~[]; - for uint::range(0, vec::uniq_len(&const st.failures)) |i| { + for uint::range(0, st.failures.len()) |i| { let name = copy st.failures[i].name; failures.push(name.to_str()); } diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index f0c353c8d62b..bcdd6cd0bfa6 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -209,7 +209,7 @@ impl Peekable for PortSet { fn peek(&self) -> bool { // It'd be nice to use self.port.each, but that version isn't // pure. - for uint::range(0, vec::uniq_len(&const self.ports)) |i| { + for uint::range(0, self.ports.len()) |i| { let port: &pipesy::Port = &self.ports[i]; if port.peek() { return true; diff --git a/src/libstd/container.rs b/src/libstd/container.rs index 065582e2e0d2..c1b656f1cd9e 100644 --- a/src/libstd/container.rs +++ b/src/libstd/container.rs @@ -16,10 +16,10 @@ use option::Option; /// knowledge known is the number of elements contained within. pub trait Container { /// Return the number of elements in the container - fn len(&const self) -> uint; + fn len(&self) -> uint; /// Return true if the container contains no elements - fn is_empty(&const self) -> bool; + fn is_empty(&self) -> bool; } /// A trait to represent mutable containers diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 6f065d74fa2e..d3faa75e3b04 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1667,7 +1667,7 @@ impl Writer for BytesWriter { fn seek(&self, offset: int, whence: SeekStyle) { let pos = *self.pos; - let len = vec::uniq_len(&const *self.bytes); + let len = self.bytes.len(); *self.pos = seek_in_buf(offset, pos, len, whence); } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index 46f69d020d1e..b7ff1acea139 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -18,6 +18,7 @@ More runtime type reflection use cast::transmute; use char; +use container::Container; use intrinsic; use intrinsic::{TyDesc, TyVisitor, visit_tydesc}; use intrinsic::Opaque; @@ -502,7 +503,7 @@ impl TyVisitor for ReprVisitor { _offset: uint, inner: *TyDesc) -> bool { - match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] { + match self.var_stk[self.var_stk.len() - 1] { Matched => { if i != 0 { self.writer.write_str(", "); @@ -520,7 +521,7 @@ impl TyVisitor for ReprVisitor { _disr_val: int, n_fields: uint, _name: &str) -> bool { - match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] { + match self.var_stk[self.var_stk.len() - 1] { Matched => { if n_fields > 0 { self.writer.write_char(')'); diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index 727ab13a4f6f..a5e68bcdac4c 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -297,7 +297,8 @@ impl ReaderUtil for T { do (|| { while total_read < len { - let slice = vec::mut_slice(*buf, start_len + total_read, buf.len()); + let len = buf.len(); + let slice = vec::mut_slice(*buf, start_len + total_read, len); match self.read(slice) { Some(nread) => { total_read += nread; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 211ee12c2910..44f3fc4c3212 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -118,15 +118,6 @@ pub fn capacity(v: &const ~[T]) -> uint { } } -// A botch to tide us over until core and std are fully demuted. -#[allow(missing_doc)] -pub fn uniq_len(v: &const ~[T]) -> uint { - unsafe { - let v: &~[T] = transmute(v); - as_const_buf(*v, |_p, len| len) - } -} - /** * Creates and initializes an owned vector. * @@ -1767,19 +1758,32 @@ pub mod traits { } } -impl<'self,T> Container for &'self const [T] { +impl<'self, T> Container for &'self const [T] { /// Returns true if a vector contains no elements #[inline] - fn is_empty(&const self) -> bool { + fn is_empty(&self) -> bool { as_const_buf(*self, |_p, len| len == 0u) } /// Returns the length of a vector #[inline] - fn len(&const self) -> uint { + fn len(&self) -> uint { as_const_buf(*self, |_p, len| len) } +} +impl Container for ~[T] { + /// Returns true if a vector contains no elements + #[inline] + fn is_empty(&self) -> bool { + as_const_buf(*self, |_p, len| len == 0u) + } + + /// Returns the length of a vector + #[inline] + fn len(&self) -> uint { + as_const_buf(*self, |_p, len| len) + } } #[allow(missing_doc)] From e097d5eaba1459fa22b7679712e8e9d0fd27a242 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 03:16:10 -0400 Subject: [PATCH 23/96] rm CopyableOrderedIter replaced with OrdIterator --- src/librustc/middle/trans/adt.rs | 4 ++-- src/libstd/old_iter.rs | 5 ----- src/libstd/prelude.rs | 4 ++-- src/libstd/vec.rs | 17 ----------------- src/libsyntax/opt_vec.rs | 7 ------- 5 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index ad07f41f8c30..9ae241c7030f 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -165,7 +165,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { if cases.all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs = cases.map(|c| c.discr); - return CEnum(discrs.min(), discrs.max()); + return CEnum(*discrs.iter().min().unwrap(), *discrs.iter().max().unwrap()); } if cases.len() == 1 { @@ -509,7 +509,7 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int, } General(ref cases) => { let case = &cases[discr as uint]; - let max_sz = cases.map(|s| s.size).max(); + let max_sz = cases.iter().transform(|x| x.size).max().unwrap(); let discr_ty = C_int(ccx, discr); let contents = build_const_struct(ccx, case, ~[discr_ty] + vals); diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index 9fea43768161..39f3a81ad218 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -54,11 +54,6 @@ pub trait CopyableIter { fn find(&self, p: &fn(&A) -> bool) -> Option; } -pub trait CopyableOrderedIter { - fn min(&self) -> A; - fn max(&self) -> A; -} - // A trait for sequences that can be built by imperatively pushing elements // onto them. pub trait Buildable { diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 61b8d36266e2..60165ed5daeb 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -47,9 +47,9 @@ pub use char::Char; pub use container::{Container, Mutable, Map, Set}; pub use hash::Hash; pub use old_iter::{BaseIter, ReverseIter, ExtendedIter, EqIter}; -pub use old_iter::{CopyableIter, CopyableOrderedIter}; +pub use old_iter::CopyableIter; pub use iter::{Times, FromIter}; -pub use iterator::{Iterator, IteratorUtil}; +pub use iterator::{Iterator, IteratorUtil, OrdIterator}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 44f3fc4c3212..7b4764164b54 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2619,23 +2619,6 @@ impl old_iter::CopyableIter for @[A] { } } -impl<'self,A:Copy + Ord> old_iter::CopyableOrderedIter for &'self [A] { - fn min(&self) -> A { old_iter::min(self) } - fn max(&self) -> A { old_iter::max(self) } -} - -// FIXME(#4148): This should be redundant -impl old_iter::CopyableOrderedIter for ~[A] { - fn min(&self) -> A { old_iter::min(self) } - fn max(&self) -> A { old_iter::max(self) } -} - -// FIXME(#4148): This should be redundant -impl old_iter::CopyableOrderedIter for @[A] { - fn min(&self) -> A { old_iter::min(self) } - fn max(&self) -> A { old_iter::max(self) } -} - impl Clone for ~[A] { #[inline] fn clone(&self) -> ~[A] { diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 791f7444b622..67e712f0596c 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -196,10 +196,3 @@ impl old_iter::CopyableIter for OptVec { old_iter::find(self, f) } } - -impl old_iter::CopyableOrderedIter for OptVec { - #[inline(always)] - fn min(&self) -> A { old_iter::min(self) } - #[inline(always)] - fn max(&self) -> A { old_iter::max(self) } -} From 52a38b80976be2025b466c144030bb7e7165d32b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 18:20:43 -0400 Subject: [PATCH 24/96] fix test --- src/libstd/os.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 044b305a0dd9..fffcb34dc09c 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1685,10 +1685,11 @@ mod tests { assert!((ostream as uint != 0u)); let s = ~"hello"; let mut buf = s.as_bytes_with_null().to_owned(); + let len = buf.len(); do vec::as_mut_buf(buf) |b, _len| { - assert!((libc::fwrite(b as *c_void, 1u as size_t, - (s.len() + 1u) as size_t, ostream) - == buf.len() as size_t)) + assert_eq!(libc::fwrite(b as *c_void, 1u as size_t, + (s.len() + 1u) as size_t, ostream), + len as size_t) } assert_eq!(libc::fclose(ostream), (0u as c_int)); let in_mode = in.get_mode(); From 845465ee246bee760b8ef0da725f8a711bfc23c9 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 19:24:20 -0400 Subject: [PATCH 25/96] old_iter: rm the min/max free functions --- src/libstd/old_iter.rs | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index 39f3a81ad218..347b47744228 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -187,40 +187,6 @@ pub fn position>(this: &IA, f: &fn(&A) -> bool) return None; } -// note: 'rposition' would only make sense to provide with a bidirectional -// iter interface, such as would provide "reach" in addition to "each". As is, -// it would have to be implemented with foldr, which is too inefficient. - -#[inline(always)] -pub fn min>(this: &IA) -> A { - match do foldl::,IA>(this, None) |a, b| { - match a { - &Some(ref a_) if *a_ < *b => { - *(a) - } - _ => Some(*b) - } - } { - Some(val) => val, - None => fail!("min called on empty iterator") - } -} - -#[inline(always)] -pub fn max>(this: &IA) -> A { - match do foldl::,IA>(this, None) |a, b| { - match a { - &Some(ref a_) if *a_ > *b => { - *(a) - } - _ => Some(*b) - } - } { - Some(val) => val, - None => fail!("max called on empty iterator") - } -} - #[inline(always)] pub fn find>(this: &IA, f: &fn(&A) -> bool) -> Option { From bbcff95ac51f5533866d307a85eedb062a1a05da Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 16 Jun 2013 12:20:12 +1000 Subject: [PATCH 26/96] remove unused imports --- src/libextra/base64.rs | 2 -- src/libextra/rope.rs | 1 - src/libextra/sha1.rs | 3 --- src/libextra/smallintmap.rs | 5 ----- src/libextra/sort.rs | 3 --- src/libextra/stats.rs | 1 - src/libextra/std.rc | 1 + src/libextra/tempfile.rs | 1 - src/libextra/terminfo/parser/compiled.rs | 1 - src/libextra/treemap.rs | 1 - src/librustc/back/rpath.rs | 3 --- src/librustc/middle/astencode.rs | 1 - src/librustc/middle/trans/adt.rs | 1 - src/librustc/middle/trans/base.rs | 2 -- src/librustdoc/desc_to_brief_pass.rs | 1 - src/librustdoc/markdown_pass.rs | 1 - src/librustdoc/text_pass.rs | 2 -- src/libstd/path.rs | 1 - src/libsyntax/ext/quote.rs | 2 -- src/libsyntax/fold.rs | 2 +- 20 files changed, 2 insertions(+), 33 deletions(-) diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index f4754b3e4cbe..5bf4dd517a5b 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -229,8 +229,6 @@ impl<'self> FromBase64 for &'self str { #[cfg(test)] mod tests { - use core::str; - #[test] fn test_to_base64() { assert_eq!("".to_base64(), ~""); diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs index 12539cd4759d..fed73256c002 100644 --- a/src/libextra/rope.rs +++ b/src/libextra/rope.rs @@ -1271,7 +1271,6 @@ mod tests { use rope::*; - use core::str; use core::uint; use core::vec; diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs index 908e497b9591..38cb14711547 100644 --- a/src/libextra/sha1.rs +++ b/src/libextra/sha1.rs @@ -24,7 +24,6 @@ use core::prelude::*; -use core::str; use core::uint; use core::vec; @@ -279,8 +278,6 @@ pub fn sha1() -> @Sha1 { mod tests { use sha1; - use core::vec; - #[test] fn test() { struct Test { diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 7f566bc16e73..d63e1c4516ff 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -294,11 +294,6 @@ mod tests { use super::SmallIntMap; - use core::local_data; - use core::rand; - use core::uint; - use core::vec; - #[test] fn test_find_mut() { let mut m = SmallIntMap::new(); diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 0189e0db6d4e..b88fd374da25 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -751,7 +751,6 @@ fn shift_vec(dest: &mut [T], mod test_qsort3 { use sort::*; - use core::vec; fn check_sort(v1: &mut [int], v2: &mut [int]) { let len = v1.len(); @@ -861,8 +860,6 @@ mod tests { use sort::*; - use core::vec; - fn check_sort(v1: &[int], v2: &[int]) { let len = v1.len(); pub fn le(a: &int, b: &int) -> bool { *a <= *b } diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 4af47fa806f8..3a1de5de01d6 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -12,7 +12,6 @@ use core::prelude::*; -use core::vec; use core::f64; use core::cmp; use core::num; diff --git a/src/libextra/std.rc b/src/libextra/std.rc index 83c0bb516b43..93759bea35f7 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -37,6 +37,7 @@ not required in or otherwise suitable for the core library. extern mod core(name = "std", vers = "0.7-pre"); +#[cfg(stage0)] use core::{str, unstable}; use core::str::{StrSlice, OwnedStr}; diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs index c239e65e2d9a..39dcee5eff31 100644 --- a/src/libextra/tempfile.rs +++ b/src/libextra/tempfile.rs @@ -36,7 +36,6 @@ mod tests { use tempfile::mkdtemp; use core::os; - use core::str; #[test] fn test_mkdtemp() { diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 81b6083db014..66649c62fcaf 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -313,7 +313,6 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> { #[cfg(test)] mod test { use super::*; - use p = core::path::Path; #[test] fn test_veclens() { diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index f98758f64afe..e37ce7c71ef7 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -710,7 +710,6 @@ mod test_treemap { use core::rand::RngUtil; use core::rand; - use core::str; use core::vec; #[test] diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 85fc0575170b..33f578d335b0 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -199,9 +199,6 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { mod test { use core::prelude::*; - use core::os; - use core::str; - // FIXME(#2119): the outer attribute should be #[cfg(unix, test)], then // these redundant #[cfg(test)] blocks can be removed #[cfg(test)] diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index e11367a7a7da..925b1f506d75 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -15,7 +15,6 @@ use cstore = metadata::cstore; use driver::session::Session; use e = metadata::encoder; use metadata::decoder; -use metadata::encoder; use metadata::tydecode; use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter}; use metadata::tyencode; diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index ad07f41f8c30..09db79037b38 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -47,7 +47,6 @@ use core::container::Map; use core::libc::c_ulonglong; use core::option::{Option, Some, None}; -use core::str; use core::vec; use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE}; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e2073d21fe39..ffc54bbed355 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -71,7 +71,6 @@ use core::libc::c_uint; use core::str; use core::uint; use core::vec; -use core::local_data; use extra::time; use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_name}; @@ -3120,4 +3119,3 @@ pub fn trans_crate(sess: session::Session, return (llcx, llmod, link_meta); } - diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index dc7621f98a09..dbaa5e8532cb 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -24,7 +24,6 @@ use fold::Fold; use fold; use pass::Pass; -use core::str; use core::util; pub fn mk_pass() -> Pass { diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 36df3a5267d4..075b64a674cb 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -22,7 +22,6 @@ use markdown_writer::WriterFactory; use pass::Pass; use sort_pass; -use core::iterator::IteratorUtil; use core::cell::Cell; use core::str; use core::vec; diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index 1f7a71e0fd89..6db582a60e98 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -149,8 +149,6 @@ mod test { use sectionalize_pass; use text_pass::mk_pass; - use core::str; - fn mk_doc(source: ~str) -> doc::Doc { do astsrv::from_str(copy source) |srv| { let doc = extract::from_srv(srv.clone(), ~""); diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 99a7a461ab24..9c4e8f083584 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -947,7 +947,6 @@ pub mod windows { mod tests { use option::{None, Some}; use path::{PosixPath, WindowsPath, windows}; - use str; #[test] fn test_double_slash_collapsing() { diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 25166eca7bb0..44e480dc7df2 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -39,8 +39,6 @@ pub mod rt { use parse; use print::pprust; - use core::str; - pub use ast::*; pub use parse::token::*; pub use parse::new_parser_from_tts; diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 035675e523e7..c1bf979cd319 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -969,7 +969,7 @@ mod test { // change every identifier to "zz" pub fn to_zz() -> @fn(ast::ident)->ast::ident { let zz_id = token::str_to_ident("zz"); - |id| {zz_id} + |_id| {zz_id} } // maybe add to expand.rs... From 1026fe84a457f7badbf1a7e79a51cdc5bd2d1e37 Mon Sep 17 00:00:00 2001 From: Ben Striegel Date: Sun, 16 Jun 2013 00:37:53 -0400 Subject: [PATCH 27/96] Delete some binary files from the test suite --- src/test/run-pass/sized-borrowed-pointer | Bin 12750 -> 0 bytes src/test/run-pass/sized-owned-pointer | Bin 12746 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 src/test/run-pass/sized-borrowed-pointer delete mode 100755 src/test/run-pass/sized-owned-pointer diff --git a/src/test/run-pass/sized-borrowed-pointer b/src/test/run-pass/sized-borrowed-pointer deleted file mode 100755 index 275622161d34f1ed28f2811d7f921fe1dea5fd66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12750 zcmb<-^>JfjWMqH=CI&kOFptXtECeAL7;Y$nxnRP9!GeK{!GS@JL7IV$fq{XQfq?<0 z&H>7T(FROlEetT41HxrsW?*1oVPIe=fXWvzK}>+rGEj9e8tf(p2C&;e_CcjlYzB#~ z;RBHj3^1C3K>;iP(hqWLfh?HIP#~KCX256(kb@W)7!05^OdrU3AblNBeH~DJFggLG zfPsMlM#KCE@*4>EK;?U&{)5pFSHWz7gayb!0Z&U(K>8GTK|BTq1zt$Fz-S+cFawMR zsRaoIJ}pTBxf8@D2E*JL1ho%WxJ-b$A4Y@15oCUYC`&4X28cx*hS{f|lbK{@qMwtZ zo0FMWTA^EEVWw+lqF0=+X9P|U0?;^i_X`CZ46+{NFOWD$K#+lfL70Jofs=uOfd?c2 zO@B}(m=a=OU;wED=>h5Gho&`duq-4EL4y}6f}pq%OgIbV1`r442X+Pq252$^34_xz zDA|DYg2D%6XU7KxMg|oZPLLSLE|7cNs_!!GdOWGd+4brhr^8mwJ8YViZxlwz?Ckx> z_v-R{KJ&?ZmS6+15Go9aw1O;cj6-}TBLf2{9FWz5*zP#gC*u&$#bM4DXc&XcM8+E! zu-jXQ!4Sz#z%604ff%V>MV@f}sOV{4v-){0tJ%`~r)s zTBv(2a6Dy$V>IkAVehKFpkbOd$XAG8k|}%y)rF8z(24rkIv#$1}uxmBk08 zre_wHq!u~nBo-H^7Bj?qhWN&(q!vMiLwucc^7B$d5|eULA#&JdqWsL0b5axYN(&4P z67%vhGct1$OHvKZ;YfVUUsx*HTnkToRv{lo?-^T2!2wpT`gn7D+BjEJ=;e zO)Q8nE=h?u&@+!Wa)~b}N{vSk3WoT!%)Cs7_{_Y_5{8`2B#`c+5>UW^I3R|eAxONS zB%>%bF$Gjc7=ZXGIUuGHh?xswnK6_WBq!$N#HXa@fC4i)8zzvKS`HP+$xKRysEv;Y zu|dK`CGok5nRyKHsVRvii45`aNyWtwafbNRyc7l%{~%9yPd|M)gBD=vd8PWrC5h>&hM=NNALNN-eVi(DGLx+IGxBp&^^=lvN^`-=ajPcL+|uGA z{ha*d#2g}Bf)QaQ`2{(tWvMw(32^AR`*=Dz#~bMx>6yZkHmp2^@EI8(5LB+hSP*tU zIFCV8l}crDGB7YPoP=tAArHy#pt2HFWX7L0VLsA!ATf{}Ok4p;98_k*#5It_L2iPH8z6}zm-!Y*;;^y?q{jhC98^bv#6Z}i`3;9h zH*2Yw0)t2EffCji$_xw)9?eHM4ufP7_`hk9m;%Fp)e$qw|o*!B_Sk zj2ApQk9l1DSIQK7co#^mN9&~$nEppl{SCGcMHLtrN(DnbI-kC%`~Uxc>@n7Jq6!R* zpAUoFi@vv4= zEnr|^D3|iw1!^FGEcV1Y0|o|$!yvl?UbBIsC-(5`9}|!Oihc=@76t|eB>f9u z`aPQ82zYeXegGRI5PR68yY>Uv{jc9688-pNJXqz2WL^N0c?uq2KY}dv=;pN&QDE@s z7S#q(owYwaI*)sFmVWT)Jm=Bv`op6$^aUuKyL~_Sbi2NI@%8Wj{~pap6k-qa%QJwy z=h6Je!lTnh#iO%Cg~OvWL`A@((?>g-7!N37^he9-YU0IFKfq@($Wg->@Vhv)x89-T)V|6lUxd=u~@`tSe$5g=<@ zK<;Mn=*&^M;nA!6M?itWr!z(6flsgM3lLlLsZVE)$_vNNzdoHMDjz%!{$=*;{N~eH zqw>SE^SVc8jLHR&n_q1H^Z&m`>)R3;!`q1C^zXBrzL%{$4{~Z_^7#{rp|Gxl~V;LA2L?Fg8FjfUIFjfdKO7pODOkiXe0EvV8 zIv_i=plU!ANE}3?s%KyTwFg1!FZ}-hAC#OK_ypYeB)s^!%Q+et?4_)=j8&9C`ao(x zZ4!>Z|NonS1k(5f+L)YqVPzahK81mSLF4cL{~&b?SmZ%57xDN1|3V!4moP9etoi%@ ze+fw5kx!zH8DYK-0|Ubm1_lO>fB*k?g5-VL*nE0ey?a@F`j|cXnLPO%n%S8=_(0(c zk_Pz~)V9p{_y0d6CP1R2cr*k?Ltr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1cp`! z9DvTNE`ZW7*F%Q~K*I-MAsF8P%79V~wonF?V(@@6pcF#{lmVp}lA#PJ#Q++U1z7-^ z69dtQp%T#PO$HbrHn#?w2La7tfz-q1KO{jM(EKfQK2#dYhxOy7p!^D`JZPK&Bm|QO z4M>9c8=&)|U;q8j2k||aA@eAp0ZI@*f)&DtjaN*7%EQKnuR;e2U~_x0AvsZyW+V(6 z5CwA;Amh$ZZ448@f{1Y$(0DOONE}2kFfiQUfY=WcuYmGl{(zVUnU4f%f!Y7>Kg2%~ zQ1$^KTQN z;SZCC(eBR9Rtg&Ksd**&`3fd_W_rd71%`TthB^ubnW?%4dZv0tnhQjFchos8c8D<4YEsPDKLDL(cJOk4Y zTlWB44*^^M08$IWu<`)J24T=-6Q~S;>4%jQ8=wN9aafQ#kQxvT%a1T~3>g?0zWx87 z4^_?pD_14%j&6QKG}Ks^j9mq1LIepvo@W?%rX z3xMf|m17Z52gAxOn0+8KU~CZW&A`9_Dl=gEVdaD#)FL&IA|&_2)WPTo1_lOD83gA; z%b5tMepvXUyB}&SLppTL1WZ4y+^c} z{h+!ADh$_O4P6HUav#V|uzDy1I;jS$UqEso46+ME!*Cgz{t3`>Y64V0c+4E87&L|t zWy7X~8qxGK!0Kyg#lr$k2T*McFnut7JDPr2y~zTtNTJSvDF?58fpZub7d`FI@T` zqUjHS>JNbGw}5Gc(lB>JxeU)ib2iX23?v4c#)Z%z61V#yvJ4Dwp!OTU1fX;W)PBh7 zE~p?>Er}0!cG7@H4>5M-U%|nHdD&>nCAiAexy$kO5Ynf%q`Y z%pe3`7YY*t(aa3O46yPC#D`&K1`!5WxdIad(aa2@46yP7#D`&K1~CR$IRFy_(aa3u z4DkF75`bc61_=gOzJ&^bDP{)Db!#9AW(M?H5i*a>!tn7wNFEu3+ILJ0ybK?p^%{6? zn1O-82Amfq8DQ;ntn4b(0Gt(b$=2QW8*=9n3=gd3U(X5Z--G-GOV6-+*$0REH1HZL%yd!=TCd2&%kTxdE)nLSdXP8+ z=6c00kUN<$*HumftB2`E(95CfBcSyPOlAvMJugE652W7=p7RH-0RX9oDMF&ZfYmcF z!1{+UDRm~u`cGKB0~0p}ueXHp5Of+;J^FglY#i!q!0Ivm+YDCE%K%#U1Tr0xUKtoV zz~WfSvEt0C)D+#M{Gy`#^3)XFf_!ktQm-f(w4~Amw1m#kJl@PK(J;v}DK$0OGC9%2 z%+NUAz`zx@$}T?zv|5rO-rdLF$JfjWMqH=CI&kOFptXtECeAL7;Y$nxnRP9!GeK{!GS@JL7IV$fq{XQfq?<0 z&H>7T(FROlEetT41HxrsW?*1oVPIe=fXWvzK}>+rGEj9e8tf(p2C&;e_CcjlYzB#~ z;RBHj3^1C3K>;iP(hqWLfh?HIP#~KCX256(kb@W)7!05^OdrU3AblNBeH~DJFggLG zfPsMlM#KCE@*4>EK;?U&{)5pFSHWz7gayb!0Z&U(K>8GTK|BTq1zt$Fz-S+cFawMR zsRaoIJ}pTBxf8@D2E*JL1ho%WxJ-b$A4Y@15oCUYC`&4X28cx*hS{f|lbK{@qMwtZ zo0FMWTA^EEVWw+lqF0=+X9P|U0?;^i_X`CZ46+{NFOWD$K#+lfL70Jofs=uOfd?c2 zO@B}(m=a=OU;wED=>h5Gho&`duq-4EL4y}6f}pq%OgIbV1`r442X+Pq252$^34_xz zDA|DYg2D%6XU7KxMg|oZPLLSLE|7cNs_!!GdOWGd+4brhr^8mwJ8YViZxlwz?Ckx> z_v-R{KJ&?ZmS6+15Go9aw1O;cj6-}TBLf2{9FWz5*zP#gC*u&$#bM4DXc&XcM8+E! zu-jXQ!4Sz#z%604ff%V>MV@f}sOV{4v-){0tJ%`~r)s zTBv(2a6Dy$V>IkAVehKFpkbOd$XAG8k|}%y)rF8z(24rkIv#$1}uxmBk08 zre_wHq!u~nBo-H^7Bj?qhWN&(q!vMiLwucc^7B$d5|eULA#&JdqWsL0b5axYN(&4P z67%vhGct1$OHvKZ;YfVUUsx*HTnkToRv{lo?-^T2!2wpT`gn7D+BjEJ=;e zO)Q8nE=h?u&@+!Wa)~b}N{vSk3WoT!%)Cs7_{_Y_5{8`2B#`c+5>UW^I3R|eAxONS zB%>%bF$Gjc7=ZXGIUuGHh?xswnK6_WBq!$N#HXa@fC4i)8zzvKS`HP+$xKRysEv;Y zu|dK`CGok5nRyKHsVRvii45`aNyWtwafbNRyc7l%{~%9yPd|M)gBD=vd8PWrC5h>&hM=NNALNN-eVi(DGLx+IGxBp&^^=lvN^`-=ajPcL+|uGA z{ha*d#2g}Bf)QaQ`2{(tWvMw(32^AR`*=Dz#~bMx>6yZkHmp2^@EI8(5LB+hSP*tU zIFCV8l}crDGB7YPoP=tAArHy#pt2HFWX7L0VLsA!ATf{}Ok4p;98_k*#5It_L2iPH8z6}zm-!Y*;;^y?q{jhC98^bv#6Z}i`3;9h zH*2Yw0)t2EffCji$_xw)9?eHM4ufP7_`hk9m;%Fp)e$qw|o*!B_Sk zj2ApQk9l1DSIQK7co#^mN9&~$nEppl{SCGcMHLtrN(DnbI-kC%`~Uxc>@n7Jq6!R* zpAUoFi@vv4= zEnr|^D3|iw1!^FGEcV1Y0|o|$!yvl?UbBIsC-(5`9}|!Oihc=@76t|eB>f9u z`aPQ82zYeXegGRI5PR68yY>Uv{jc9688-pNJXqz2WL^N0c?uq2KY}dv=;pN&QDE@s z7S#q(owYwaI*)sFmVWT)Jm=Bv`op6$^aUuKyL~_Sbi2NI@%8Wj{~pap6k-qa%QJwy z=h6Je!lTnh#iO%Cg~OvWL`A@((?>g-7!N37^he9-YU0IFKfq@($Wg->@Vhv)x89-T)V|6lUxd=u~@`tSe$5g=<@ zK<;Mn=*&^M;nA!6M?itWr!z(6flsgM3lLlLsZVE)$_vNNzdoHMDjz%!{$=*;{N~eH zqw>SE^SVc8jLHR&n_q1H^Z&m`>)R3;!`q1C^zXBrzL%{$4{~Z_^7#{rp|Gxl~V;LA2L?Fg8FjfUIFjfdKO7pODOkiXe0EvV8 zIv_i=plU!ANE}3?s%KyTwFg1!FZ}-hAC#OK_ypYeB)s^!%Q+et?4_)=j8&9C`ao(x zZ4!>Z|NonS1k(5f+L)YqVPzahK81mSLF4cL{~&b?SmZ%57xDN1|3V!4moP9etoi%@ ze+fw5kx!zH8DYK-0|Ubm1_lO>fB*k?g5-VL*nE0ey?a@F`j|cXnLPO%n%S8=_(0(c zk_Pz~)V9p{_y0d6CP1R2cr*k?Ltr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1cp`! z9DvTNE`ZW7*F%Q~K*I-MAsF8P%79V~wonF?V(@@6pcF#{lmVp}lA#PJ#Q++U1z7-^ z69dtQp%T#PO$HbrHn#?w2La7tfz-q1KO{jM(EKfQK2#dYhxOy7p!^D`JZPK&Bm|QO z4M>9c8=&)|U;q8j2k||aA@eAp0ZI@*f)&DtjaN*7%EQKnuR;e2U~_x0AvsZyW+V(6 z5CwA;Amh$ZZ448@f{1Y$(0DOONE}2kFfiQUfY=WcuYmGl{(zVUnU4f%f!Y7>Kg2%~ zQ1$^KTQN z;SZCC(eBR9Rtg&Ksd**&`3fd_W_rd71%`TthB^ubnW?%4dZv0tnhQjFchos8c8D<4YEsPDKLDL(cJOk4Y zTlWB44*^^M08$IWu<`)J24T=-6Q~S;>4%jQ8=wN9aafQ#kQxvT%a1T~3>g?0zWx87 z4^_?pD_14%j&6QKG}Ks^j9mq1LIepvo@W?%rX z3xMf|m17Z52gAxOn0+8KU~CZW&A`9_Dl=gEVdaD#)FL&IA|&_2)WPTo1_lOD83gA; z%b5tMepvXUyB}&SLppTL1WZ4y+^c} z{h+!ADh$_O4P6HUav#V|uzDy1I;jS$UqEso46+ME!*Cgz{t3`>Y64V0c+4E87&L|t zWy7X~8qxGK!0Kyg#lr$k2T*McFnut7JDPr2y~zTtNTJSvDF?58fpZub7d`FI@T` zqUjHS>JNbGw}5Gc(lB>JxeU)ib2iX23?v4c#)Z%z61V#yvJ4Dwp!OTU1fX;W)PBh7 zE~p?>Er}0!cG7@H4>5M-U%|nHdD&>nCAiAexy$kO5Ynf%q`Y z%pe3`7YY*t(aa3O46yPC#D`&K1`!5WxdIad(aa2@46yP7#D`&K1~CR$IRFy_(aa3u z4DkF75`bc61_=gOzJ&^bDP{)Db!#9AW(M?H5i*a>!tn7wNFEu3(m4|YFT)3Dy#}5e zW?*0dl?#jvk_@nRI&!&y%^Wvy-o;0C3*Zc7@fL5`9%!XyttuS$@e?f8}ya&g+$J02(?}N?3Oovaw;vf@IF$*L1 z^^LNO*w=Gfg4H9^Gpt?)_4A=cABqJ@;5Am5=_DVtUXh8H;R|$KB1}^?NSpz4yx0)@!gvTe3924_y=XcP^%Y?CnEtH?tLJ3^t$PBQ4r<4O=oYXzmU65( zvnn-3H@`eDHAS}|AKa_dD@q2fr!)brpEERzH%>7#HaD|0Gf6TuO*J(#jyEuHg{`p5 zPXVozWQce7@pp3ciT8JN3w8~O4{>zzagAq)2QQ6;bOXUF5>W)e>oXbRT_XJ)eLbBS zKs`a|>P65R#CVj2nUFP)$;GA6C6`dWM65prcU>{oOgcCqFAGFp_la0Whe|&LC zN@iYsX>n=_zQwHZNM4JN&&@ANEiOq+&V~gccnN2Gh_7?JtDj4JJZ$YJVlilZd`fYC zd`4nk3TV+RA}GK;bab~D6I!!M#?o5kg{7n~vjxXIbcHKoK`V68DkzCTSI`0g`cf1` From 7f00ab3df10b8b648872edf25fb1700168b306de Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 20:53:30 -0400 Subject: [PATCH 28/96] fix benchmark and the tutorials --- doc/tutorial-tasks.md | 2 +- doc/tutorial.md | 9 ++------- src/test/bench/shootout-fasta-redux.rs | 3 ++- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index b00cd665271f..2e3ce40c9f7d 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -359,7 +359,7 @@ fn pnorm(nums: &~[float], p: uint) -> float { fn main() { let numbers = vec::from_fn(1000000, |_| rand::random::()); - println(fmt!("Inf-norm = %?", numbers.max())); + println(fmt!("Inf-norm = %?", *numbers.iter().max().unwrap())); let numbers_arc = ARC(numbers); diff --git a/doc/tutorial.md b/doc/tutorial.md index a45803611666..c0b939ddac50 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2039,17 +2039,12 @@ themselves contain type parameters. A trait for generalized sequence types might look like the following: ~~~~ -# use std::vec; trait Seq { - fn len(&self) -> uint; - fn iter(&self, b: &fn(v: &T)); + fn length(&self) -> uint; } impl Seq for ~[T] { - fn len(&self) -> uint { self.len() } - fn iter(&self, b: &fn(v: &T)) { - for vec::each(*self) |elt| { b(elt); } - } + fn length(&self) -> uint { self.len() } } ~~~~ diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index 8b587f02ad6d..8c8b26afa08b 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -95,7 +95,8 @@ impl RepeatFasta { let alu: &[u8] = self.alu.as_bytes(); copy_memory(buf, alu, alu_len); - copy_memory(vec::mut_slice(buf, alu_len, buf.len()), + let buf_len = buf.len(); + copy_memory(vec::mut_slice(buf, alu_len, buf_len), alu, LINE_LEN); From 53f6a4e9fbc3e8bb1fcf47ec3676c791892ea1b1 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 16 Jun 2013 13:01:08 +1000 Subject: [PATCH 29/96] std: fix UnfoldrIterator cross-crate. --- src/libstd/iterator.rs | 4 +-- src/test/run-pass/unfoldr-cross-crate.rs | 34 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/unfoldr-cross-crate.rs diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index e65904a68992..a7450101fc09 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -788,8 +788,8 @@ impl<'self, A, St> UnfoldrIterator<'self, A, St> { /// Creates a new iterator with the specified closure as the "iterator /// function" and an initial state to eventually pass to the iterator #[inline] - pub fn new(f: &'self fn(&mut St) -> Option, initial_state: St) - -> UnfoldrIterator<'self, A, St> { + pub fn new<'a>(f: &'a fn(&mut St) -> Option, initial_state: St) + -> UnfoldrIterator<'a, A, St> { UnfoldrIterator { f: f, state: initial_state diff --git a/src/test/run-pass/unfoldr-cross-crate.rs b/src/test/run-pass/unfoldr-cross-crate.rs new file mode 100644 index 000000000000..4e98543ae826 --- /dev/null +++ b/src/test/run-pass/unfoldr-cross-crate.rs @@ -0,0 +1,34 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::iterator::*; + +// UnfoldrIterator had a bug with 'self that mean it didn't work +// cross-crate + +fn main() { + fn count(st: &mut uint) -> Option { + if *st < 10 { + let ret = Some(*st); + *st += 1; + ret + } else { + None + } + } + + let mut it = UnfoldrIterator::new(count, 0); + let mut i = 0; + for it.advance |counted| { + assert_eq!(counted, i); + i += 1; + } + assert_eq!(i, 10); +} From 64ccc60eee27180e0393ba87a40bbb0bbb73fad5 Mon Sep 17 00:00:00 2001 From: Sander Mathijs van Veen Date: Sun, 16 Jun 2013 17:39:13 +0200 Subject: [PATCH 30/96] Remove h[123] border and increase their padding to better readability --- doc/rust.css | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/doc/rust.css b/doc/rust.css index 35581a8d4edf..ed9ea446aa87 100644 --- a/doc/rust.css +++ b/doc/rust.css @@ -12,41 +12,38 @@ body { } h1 { - font-size: 20pt; - margin-top: 2em; + font-size: 24pt; + margin-top: 1.6em; padding-left: 0.4em; line-height: 1.6em; background-color:#FFF2CE; border-radius: 0.2em; - border: 1px solid rgba(0, 0, 0, 0.15); } h2 { - font-size: 15pt; - margin-top: 2em; - padding-left: 0.4em; + font-size: 16pt; + margin-top: 1.6em; + padding: 0.2em 0.5em; background-color:#FFF2CE; border-radius: 0.4em; - border: 1px solid rgba(0, 0, 0, 0.15); } h2 code { color: #097334; - font-size: 15pt; + font-size: 16pt; } h3 { - font-size: 13pt; + font-size: 14pt; color: black; background-color:#D9E7FF; border-radius: 0.4em; - border: 1px solid rgba(0, 0, 0, 0.15); - padding: 0 0.4em 0 0.4em; + padding: 0.2em 0.5em; } h3 code { color: #541800; - font-size: 13pt; + font-size: 14pt; font-style: italic; } From 642cd467c6b49f50b42d833480b875ca5eb64e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sun, 16 Jun 2013 14:51:50 +0200 Subject: [PATCH 31/96] Avoid quadratic growth of cleanup blocks Currently, cleanup blocks are only reused when there are nested scopes, the child scope's cleanup block will terminate with a jump to the parent scope's cleanup block. But within a single scope, adding or revoking any cleanup will force a fresh cleanup block. This means quadratic growth with the number of allocations in a scope, because each allocation needs a landing pad. Instead of forcing a fresh cleanup block, we can keep a list chained cleanup blocks that form a prefix of the currently required cleanups. That way, the next cleanup block only has to handle newly added cleanups. And by keeping the whole list instead of just the latest block, we can also handle revocations more efficiently, by only dropping those blocks that are no longer required, instead of all of them. Reduces the size of librustc by about 5% and the time required to build it by about 10%. --- src/librustc/middle/trans/base.rs | 22 +++++++++++++++++----- src/librustc/middle/trans/common.rs | 22 ++++++++++++++-------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index ffc54bbed355..53f2729c38e9 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1317,26 +1317,38 @@ pub fn cleanup_and_leave(bcx: block, match cur.kind { block_scope(inf) if !inf.empty_cleanups() => { - let (sub_cx, inf_cleanups) = { + let (sub_cx, dest, inf_cleanups) = { let inf = &mut *inf; // FIXME(#5074) workaround stage0 + let mut skip = 0; + let mut dest = None; { - let r = vec::find((*inf).cleanup_paths, |cp| cp.target == leave); + let r = vec::rfind((*inf).cleanup_paths, |cp| cp.target == leave); for r.iter().advance |cp| { - Br(bcx, cp.dest); - return; + if cp.size == inf.cleanups.len() { + Br(bcx, cp.dest); + return; + } + + skip = cp.size; + dest = Some(cp.dest); } } let sub_cx = sub_block(bcx, "cleanup"); Br(bcx, sub_cx.llbb); inf.cleanup_paths.push(cleanup_path { target: leave, + size: inf.cleanups.len(), dest: sub_cx.llbb }); - (sub_cx, copy inf.cleanups) + (sub_cx, dest, inf.cleanups.tailn(skip).to_owned()) }; bcx = trans_block_cleanups_(sub_cx, inf_cleanups, is_lpad); + for dest.iter().advance |&dest| { + Br(bcx, dest); + return; + } } _ => () } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index f5919ca2586f..ff98e5a177f2 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -325,11 +325,17 @@ pub enum cleanup { // target: none means the path ends in an resume instruction pub struct cleanup_path { target: Option, + size: uint, dest: BasicBlockRef } -pub fn scope_clean_changed(scope_info: &mut scope_info) { - if scope_info.cleanup_paths.len() > 0u { scope_info.cleanup_paths = ~[]; } +pub fn shrink_scope_clean(scope_info: &mut scope_info, size: uint) { + scope_info.landing_pad = None; + scope_info.cleanup_paths = scope_info.cleanup_paths.iter() + .take_while(|&cu| cu.size <= size).transform(|&x|x).collect(); +} + +pub fn grow_scope_clean(scope_info: &mut scope_info) { scope_info.landing_pad = None; } @@ -374,7 +380,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { scope_info.cleanups.push( clean(|a| glue::drop_ty_root(a, root, rooted, t), cleanup_type)); - scope_clean_changed(scope_info); + grow_scope_clean(scope_info); } } @@ -388,7 +394,7 @@ pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { scope_info.cleanups.push( clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty), cleanup_type)); - scope_clean_changed(scope_info); + grow_scope_clean(scope_info); } } pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { @@ -402,7 +408,7 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { scope_info.cleanups.push( clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t), cleanup_type)); - scope_clean_changed(scope_info); + grow_scope_clean(scope_info); } } pub fn add_clean_return_to_mut(bcx: block, @@ -434,7 +440,7 @@ pub fn add_clean_return_to_mut(bcx: block, filename_val, line_val), normal_exit_only)); - scope_clean_changed(scope_info); + grow_scope_clean(scope_info); } } pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { @@ -451,7 +457,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { do in_scope_cx(cx) |scope_info| { scope_info.cleanups.push(clean_temp(ptr, free_fn, normal_exit_and_unwind)); - scope_clean_changed(scope_info); + grow_scope_clean(scope_info); } } @@ -474,7 +480,7 @@ pub fn revoke_clean(cx: block, val: ValueRef) { vec::slice(scope_info.cleanups, *i + 1u, scope_info.cleanups.len())); - scope_clean_changed(scope_info); + shrink_scope_clean(scope_info, *i); } } } From 461a79a24702f262fa9116ed769315b25f064cbf Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Jun 2013 16:18:39 -0400 Subject: [PATCH 32/96] Partial fix for #7158: Save EDX in morestack on x86-32 --- src/rt/arch/i386/morestack.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S index 1b2768208056..a95e183a1d12 100644 --- a/src/rt/arch/i386/morestack.S +++ b/src/rt/arch/i386/morestack.S @@ -207,12 +207,14 @@ MORESTACK: subl $12, %esp // Save the return value of the function we allocated space for + movl %edx, 4(%esp) movl %eax, (%esp) call UPCALL_DEL_STACK // And restore it movl (%esp), %eax + movl 4(%esp), %edx addl $12,%esp From 682bb4144ca3fddffee8ed2927e7552049fcf25c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Jun 2013 20:15:38 -0400 Subject: [PATCH 33/96] correct ASM_COMMENTS Makefile option --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index fa4c327f0614..baae56c4f409 100644 --- a/Makefile.in +++ b/Makefile.in @@ -111,7 +111,7 @@ ifdef SAVE_TEMPS CFG_RUSTC_FLAGS += --save-temps endif ifdef ASM_COMMENTS - CFG_RUSTC_FLAGS += -z asm-comments + CFG_RUSTC_FLAGS += -Z asm-comments endif ifdef TIME_PASSES CFG_RUSTC_FLAGS += -Z time-passes From eb48c296817be7529a1757ac8d4798112717eaa9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Jun 2013 20:26:59 -0400 Subject: [PATCH 34/96] Add copies to type params with Copy bound --- src/libextra/deque.rs | 36 +-- src/libextra/dlist.rs | 17 +- src/libextra/future.rs | 2 +- src/libextra/list.rs | 4 +- src/libextra/smallintmap.rs | 2 +- src/libextra/sort.rs | 18 +- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 4 +- src/librustc/middle/ty.rs | 6 +- src/librustc/middle/typeck/infer/lattice.rs | 65 +++--- src/librustc/middle/typeck/infer/mod.rs | 4 +- src/librustc/middle/typeck/infer/unify.rs | 42 ++-- src/libstd/at_vec.rs | 6 +- src/libstd/either.rs | 4 +- src/libstd/io.rs | 2 +- src/libstd/num/num.rs | 6 +- src/libstd/num/strconv.rs | 28 +-- src/libstd/old_iter.rs | 12 +- src/libstd/option.rs | 12 +- src/libstd/rand.rs | 6 +- src/libstd/tuple.rs | 6 +- src/libstd/vec.rs | 34 +-- src/libsyntax/ast_util.rs | 52 ++--- src/libsyntax/diagnostic.rs | 2 +- src/libsyntax/print/pprust.rs | 12 +- src/libsyntax/util/interner.rs | 6 +- src/libsyntax/visit.rs | 212 ++++++++++-------- src/test/auxiliary/cci_capture_clause.rs | 2 +- src/test/auxiliary/cci_nested_lib.rs | 2 +- src/test/bench/msgsend-pipes-shared.rs | 6 +- src/test/bench/msgsend-pipes.rs | 6 +- src/test/bench/msgsend-ring-pipes.rs | 6 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 8 +- .../compile-fail/infinite-instantiation.rs | 2 +- src/test/compile-fail/kindck-owned.rs | 5 +- src/test/run-pass/alignment-gep-tup-like-1.rs | 2 +- src/test/run-pass/alignment-gep-tup-like-2.rs | 2 +- src/test/run-pass/auto-encode.rs | 61 ++--- .../borrowck-move-from-unsafe-ptr-ok.rs | 21 -- src/test/run-pass/borrowed-ptr-pattern.rs | 2 +- src/test/run-pass/box-unbox.rs | 2 +- .../close-over-big-then-small-data.rs | 2 +- src/test/run-pass/expr-block-generic-box2.rs | 2 +- .../run-pass/expr-block-generic-unique2.rs | 2 +- src/test/run-pass/expr-block-generic.rs | 2 +- src/test/run-pass/expr-if-generic-box2.rs | 2 +- src/test/run-pass/expr-if-generic.rs | 2 +- src/test/run-pass/expr-match-generic-box2.rs | 2 +- src/test/run-pass/expr-match-generic.rs | 2 +- src/test/run-pass/generic-derived-type.rs | 3 +- src/test/run-pass/issue-2718.rs | 8 +- src/test/run-pass/ivec-add.rs | 4 +- .../run-pass/kindck-owned-trait-contains-1.rs | 2 +- src/test/run-pass/reflect-visit-data.rs | 4 +- src/test/run-pass/resource-generic.rs | 2 +- src/test/run-pass/static-method-test.rs | 2 +- 56 files changed, 380 insertions(+), 390 deletions(-) delete mode 100644 src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 89e23a3a77ff..c8bb984736a1 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -264,31 +264,31 @@ mod tests { fn test_parameterized(a: T, b: T, c: T, d: T) { let mut deq = Deque::new(); assert_eq!(deq.len(), 0); - deq.add_front(a); - deq.add_front(b); - deq.add_back(c); + deq.add_front(copy a); + deq.add_front(copy b); + deq.add_back(copy c); assert_eq!(deq.len(), 3); - deq.add_back(d); + deq.add_back(copy d); assert_eq!(deq.len(), 4); - assert_eq!(*deq.peek_front(), b); - assert_eq!(*deq.peek_back(), d); - assert_eq!(deq.pop_front(), b); - assert_eq!(deq.pop_back(), d); - assert_eq!(deq.pop_back(), c); - assert_eq!(deq.pop_back(), a); + assert_eq!(copy *deq.peek_front(), copy b); + assert_eq!(copy *deq.peek_back(), copy d); + assert_eq!(deq.pop_front(), copy b); + assert_eq!(deq.pop_back(), copy d); + assert_eq!(deq.pop_back(), copy c); + assert_eq!(deq.pop_back(), copy a); assert_eq!(deq.len(), 0); - deq.add_back(c); + deq.add_back(copy c); assert_eq!(deq.len(), 1); - deq.add_front(b); + deq.add_front(copy b); assert_eq!(deq.len(), 2); - deq.add_back(d); + deq.add_back(copy d); assert_eq!(deq.len(), 3); - deq.add_front(a); + deq.add_front(copy a); assert_eq!(deq.len(), 4); - assert_eq!(*deq.get(0), a); - assert_eq!(*deq.get(1), b); - assert_eq!(*deq.get(2), c); - assert_eq!(*deq.get(3), d); + assert_eq!(copy *deq.get(0), copy a); + assert_eq!(copy *deq.get(1), copy b); + assert_eq!(copy *deq.get(2), copy c); + assert_eq!(copy *deq.get(3), copy d); } #[deriving(Eq)] diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index c3e2beb122f0..a67b17388198 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -111,7 +111,8 @@ pub fn from_elem(data: T) -> @mut DList { /// Creates a new dlist from a vector of elements, maintaining the same order pub fn from_vec(vec: &[T]) -> @mut DList { do vec.iter().fold(DList()) |list,data| { - list.push(*data); // Iterating left-to-right -- add newly to the tail. + // Iterating left-to-right -- add newly to the tail. + list.push(copy *data); list } } @@ -460,35 +461,35 @@ impl DList { impl DList { /// Remove data from the head of the list. O(1). pub fn pop(@mut self) -> Option { - self.pop_n().map(|nobe| nobe.data) + self.pop_n().map(|nobe| copy nobe.data) } /// Remove data from the tail of the list. O(1). pub fn pop_tail(@mut self) -> Option { - self.pop_tail_n().map(|nobe| nobe.data) + self.pop_tail_n().map(|nobe| copy nobe.data) } /// Get data at the list's head. O(1). pub fn peek(@mut self) -> Option { - self.peek_n().map(|nobe| nobe.data) + self.peek_n().map(|nobe| copy nobe.data) } /// Get data at the list's tail. O(1). pub fn peek_tail(@mut self) -> Option { - self.peek_tail_n().map (|nobe| nobe.data) + self.peek_tail_n().map (|nobe| copy nobe.data) } /// Get data at the list's head, failing if empty. O(1). - pub fn head(@mut self) -> T { self.head_n().data } + pub fn head(@mut self) -> T { copy self.head_n().data } /// Get data at the list's tail, failing if empty. O(1). - pub fn tail(@mut self) -> T { self.tail_n().data } + pub fn tail(@mut self) -> T { copy self.tail_n().data } /// Get the elements of the list as a vector. O(n). pub fn to_vec(@mut self) -> ~[T] { let mut v = vec::with_capacity(self.size); for old_iter::eachi(&self) |index,data| { - v[index] = *data; + v[index] = copy *data; } v } diff --git a/src/libextra/future.rs b/src/libextra/future.rs index 40cfeebd5dcd..4652e1d64770 100644 --- a/src/libextra/future.rs +++ b/src/libextra/future.rs @@ -57,7 +57,7 @@ priv enum FutureState { impl Future { pub fn get(&mut self) -> A { //! Get the value of the future. - *(self.get_ref()) + copy *(self.get_ref()) } } diff --git a/src/libextra/list.rs b/src/libextra/list.rs index 68d9bb4e1ae3..34c35e0d7fde 100644 --- a/src/libextra/list.rs +++ b/src/libextra/list.rs @@ -27,7 +27,7 @@ pub enum MutList { /// Create a list from a vector pub fn from_vec(v: &[T]) -> @List { - v.rev_iter().fold(@Nil::, |t, h| @Cons(*h, t)) + v.rev_iter().fold(@Nil::, |t, h| @Cons(copy *h, t)) } /** @@ -61,7 +61,7 @@ pub fn find(ls: @List, f: &fn(&T) -> bool) -> Option { loop { ls = match *ls { Cons(ref hd, tl) => { - if f(hd) { return Some(*hd); } + if f(hd) { return Some(copy *hd); } tl } Nil => return None diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 972bccde18a2..aee087d3764d 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -179,7 +179,7 @@ impl SmallIntMap { ff: &fn(uint, V, V) -> V) -> bool { let new_val = match self.find(&key) { None => val, - Some(orig) => ff(key, *orig, val) + Some(orig) => ff(key, copy *orig, val) }; self.insert(key, new_val) } diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index b88fd374da25..b5645d9c5017 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -37,7 +37,7 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { let v_len = end - begin; if v_len == 0 { return ~[]; } - if v_len == 1 { return ~[v[begin]]; } + if v_len == 1 { return ~[copy v[begin]]; } let mid = v_len / 2 + begin; let a = (begin, mid); @@ -53,9 +53,9 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { let mut b_ix = 0; while a_ix < a_len && b_ix < b_len { if le(&a[a_ix], &b[b_ix]) { - rs.push(a[a_ix]); + rs.push(copy a[a_ix]); a_ix += 1; - } else { rs.push(b[b_ix]); b_ix += 1; } + } else { rs.push(copy b[b_ix]); b_ix += 1; } } rs.push_all(vec::slice(a, a_ix, a_len)); rs.push_all(vec::slice(b, b_ix, b_len)); @@ -106,7 +106,7 @@ pub fn quick_sort(arr: &mut [T], compare_func: Le) { fn qsort3(arr: &mut [T], left: int, right: int) { if right <= left { return; } - let v: T = arr[right]; + let v: T = copy arr[right]; let mut i: int = left - 1; let mut j: int = right; let mut p: int = i; @@ -233,7 +233,7 @@ fn binarysort(array: &mut [T], start: uint) { if start == 0 { start += 1; } while start < size { - let pivot = array[start]; + let pivot = copy array[start]; let mut left = 0; let mut right = start; assert!(left <= right); @@ -470,7 +470,7 @@ impl MergeState { let mut tmp = ~[]; for uint::range(base1, base1+len1) |i| { - tmp.push(array[i]); + tmp.push(copy array[i]); } let mut c1 = 0; @@ -580,7 +580,7 @@ impl MergeState { let mut tmp = ~[]; for uint::range(base2, base2+len2) |i| { - tmp.push(array[i]); + tmp.push(copy array[i]); } let mut c1 = base1 + len1 - 1; @@ -732,7 +732,7 @@ fn copy_vec(dest: &mut [T], assert!(s1+from.len() <= dest.len()); for from.eachi |i, v| { - dest[s1+i] = *v; + dest[s1+i] = copy *v; } } @@ -1045,7 +1045,7 @@ mod big_tests { fn multiplyVec(arr: &[T], num: uint) -> ~[T] { let size = arr.len(); let res = do vec::from_fn(num) |i| { - arr[i % size] + copy arr[i % size] }; res } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 110f686e5a66..5d5d7582b5f3 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1184,7 +1184,7 @@ fn create_index(index: ~[entry]) -> for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); }; for index.each |elt| { let h = elt.val.hash() as uint; - buckets[h % 256].push(*elt); + buckets[h % 256].push(copy *elt); } let mut buckets_frozen = ~[]; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 7a8ebb4abfdd..87c33ce64f54 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -200,8 +200,8 @@ fn cached_metadata(cache: metadata_cache, let items = cache.get(&mdtag); for items.each |item| { let md: T = md_from_metadata::(*item); - if eq_fn(md) { - return option::Some(md); + if eq_fn(copy md) { + return option::Some(copy md); } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b54f362c7d2d..e161f35af09d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3694,7 +3694,7 @@ fn lookup_locally_or_in_crate_store( */ match map.find(&def_id) { - Some(&v) => { return v; } + Some(&ref v) => { return copy *v; } None => { } } @@ -3702,8 +3702,8 @@ fn lookup_locally_or_in_crate_store( fail!("No def'n found for %? in tcx.%s", def_id, descr); } let v = load_external(); - map.insert(def_id, v); - return v; + map.insert(def_id, copy v); + return copy v; } pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method { diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 820bb2f86b04..7a3230079ee3 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -89,10 +89,10 @@ impl CombineFields { // Need to make sub_id a subtype of sup_id. let node_a = self.infcx.get(a_id); let node_b = self.infcx.get(b_id); - let a_id = node_a.root; - let b_id = node_b.root; - let a_bounds = node_a.possible_types; - let b_bounds = node_b.possible_types; + let a_id = copy node_a.root; + let b_id = copy node_b.root; + let a_bounds = copy node_a.possible_types; + let b_bounds = copy node_b.possible_types; debug!("vars(%s=%s <: %s=%s)", a_id.to_str(), a_bounds.inf_str(self.infcx), @@ -102,8 +102,8 @@ impl CombineFields { // If both A's UB and B's LB have already been bound to types, // see if we can make those types subtypes. - match (a_bounds.ub, b_bounds.lb) { - (Some(ref a_ub), Some(ref b_lb)) => { + match (&a_bounds.ub, &b_bounds.lb) { + (&Some(ref a_ub), &Some(ref b_lb)) => { let r = self.infcx.try( || LatticeValue::sub(self, a_ub, b_lb)); match r { @@ -138,9 +138,9 @@ impl CombineFields { * Make a variable (`a_id`) a subtype of the concrete type `b` */ let node_a = self.infcx.get(a_id); - let a_id = node_a.root; + let a_id = copy node_a.root; let a_bounds = &node_a.possible_types; - let b_bounds = &Bounds { lb: None, ub: Some(b) }; + let b_bounds = &Bounds { lb: None, ub: Some(copy b) }; debug!("var_sub_t(%s=%s <: %s)", a_id.to_str(), @@ -161,9 +161,9 @@ impl CombineFields { * * Make a concrete type (`a`) a subtype of the variable `b_id` */ - let a_bounds = &Bounds { lb: Some(a), ub: None }; + let a_bounds = &Bounds { lb: Some(copy a), ub: None }; let node_b = self.infcx.get(b_id); - let b_id = node_b.root; + let b_id = copy node_b.root; let b_bounds = &node_b.possible_types; debug!("t_sub_var(%s <: %s=%s)", @@ -190,11 +190,11 @@ impl CombineFields { b.inf_str(self.infcx)); let _r = indenter(); - match (*a, *b) { - (None, None) => Ok(None), - (Some(_), None) => Ok(*a), - (None, Some(_)) => Ok(*b), - (Some(ref v_a), Some(ref v_b)) => { + match (a, b) { + (&None, &None) => Ok(None), + (&Some(_), &None) => Ok(copy *a), + (&None, &Some(_)) => Ok(copy *b), + (&Some(ref v_a), &Some(ref v_b)) => { do lattice_op(self, v_a, v_b).chain |v| { Ok(Some(v)) } @@ -272,13 +272,13 @@ impl CombineFields { b.inf_str(self.infcx)); let _r = indenter(); - match (*a, *b) { - (None, None) | - (Some(_), None) | - (None, Some(_)) => { + match (a, b) { + (&None, &None) | + (&Some(_), &None) | + (&None, &Some(_)) => { uok() } - (Some(ref t_a), Some(ref t_b)) => { + (&Some(ref t_a), &Some(ref t_b)) => { LatticeValue::sub(self, t_a, t_b) } } @@ -303,9 +303,9 @@ pub trait TyLatticeDir { impl LatticeDir for Lub { fn combine_fields(&self) -> CombineFields { **self } - fn bnd(&self, b: &Bounds) -> Option { b.ub } + fn bnd(&self, b: &Bounds) -> Option { copy b.ub } fn with_bnd(&self, b: &Bounds, t: T) -> Bounds { - Bounds { ub: Some(t), ..*b } + Bounds { ub: Some(t), ..copy *b } } } @@ -317,9 +317,9 @@ impl TyLatticeDir for Lub { impl LatticeDir for Glb { fn combine_fields(&self) -> CombineFields { **self } - fn bnd(&self, b: &Bounds) -> Option { b.lb } + fn bnd(&self, b: &Bounds) -> Option { copy b.lb } fn with_bnd(&self, b: &Bounds, t: T) -> Bounds { - Bounds { lb: Some(t), ..*b } + Bounds { lb: Some(t), ..copy *b } } } @@ -405,8 +405,8 @@ pub fn lattice_vars cres> { let nde_a = this.infcx().get(a_vid); let nde_b = this.infcx().get(b_vid); - let a_vid = nde_a.root; - let b_vid = nde_b.root; + let a_vid = copy nde_a.root; + let b_vid = copy nde_b.root; let a_bounds = &nde_a.possible_types; let b_bounds = &nde_b.possible_types; @@ -436,8 +436,8 @@ pub fn lattice_vars) -> cres { let nde_a = this.infcx().get(a_id); - let a_id = nde_a.root; + let a_id = copy nde_a.root; let a_bounds = &nde_a.possible_types; // The comments in this function are written for LUB, but they @@ -472,10 +472,11 @@ pub fn lattice_var_and_t { impl CresCompare for cres { fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres { - do self.chain |s| { + do (copy *self).chain |s| { if s == t { - *self + copy *self } else { Err(f()) } diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index c6e4b485d29b..371d389f712c 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -61,7 +61,7 @@ impl InferCtxt { { let vid_u = vid.to_uint(); let var_val = match vb.vals.find(&vid_u) { - Some(&var_val) => var_val, + Some(&ref var_val) => copy *var_val, None => { tcx.sess.bug(fmt!( "failed lookup of vid `%u`", vid_u)); @@ -69,11 +69,11 @@ impl InferCtxt { }; match var_val { Redirect(vid) => { - let node: Node = helper(tcx, vb, vid); + let node: Node = helper(tcx, vb, copy vid); if node.root != vid { // Path compression vb.vals.insert(vid.to_uint(), - Redirect(node.root)); + Redirect(copy node.root)); } node } @@ -96,12 +96,10 @@ impl InferCtxt { debug!("Updating variable %s to %s", vid.to_str(), new_v.inf_str(self)); - { // FIXME(#4903)---borrow checker is not flow sensitive - let vb = UnifyVid::appropriate_vals_and_bindings(self); - let old_v = { *vb.vals.get(&vid.to_uint()) }; // FIXME(#4903) - vb.bindings.push((vid, old_v)); - vb.vals.insert(vid.to_uint(), new_v); - } + let vb = UnifyVid::appropriate_vals_and_bindings(self); + let old_v = copy *vb.vals.get(&vid.to_uint()); + vb.bindings.push((copy vid, old_v)); + vb.vals.insert(vid.to_uint(), new_v); } pub fn unify node_b.rank { // a has greater rank, so a should become b's parent, // i.e., b should redirect to a. - self.set(node_b.root, Redirect(node_a.root)); - (node_a.root, node_a.rank) + self.set(copy node_b.root, Redirect(copy node_a.root)); + (copy node_a.root, node_a.rank) } else if node_a.rank < node_b.rank { // b has greater rank, so a should redirect to b. - self.set(node_a.root, Redirect(node_b.root)); - (node_b.root, node_b.rank) + self.set(copy node_a.root, Redirect(copy node_b.root)); + (copy node_b.root, node_b.rank) } else { // If equal, redirect one to the other and increment the // other's rank. assert_eq!(node_a.rank, node_b.rank); - self.set(node_b.root, Redirect(node_a.root)); - (node_a.root, node_a.rank + 1) + self.set(copy node_b.root, Redirect(copy node_a.root)); + (copy node_a.root, node_a.rank + 1) } } @@ -174,20 +172,20 @@ impl InferCtxt { let node_a = self.get(a_id); let node_b = self.get(b_id); - let a_id = node_a.root; - let b_id = node_b.root; + let a_id = copy node_a.root; + let b_id = copy node_b.root; if a_id == b_id { return uok(); } let combined = match (&node_a.possible_types, &node_b.possible_types) { (&None, &None) => None, - (&Some(ref v), &None) | (&None, &Some(ref v)) => Some(*v), + (&Some(ref v), &None) | (&None, &Some(ref v)) => Some(copy *v), (&Some(ref v1), &Some(ref v2)) => { if *v1 != *v2 { - return mk_err(a_is_expected, *v1, *v2); + return mk_err(a_is_expected, copy *v1, copy *v2); } - Some(*v1) + Some(copy *v1) } }; @@ -211,7 +209,7 @@ impl InferCtxt { * `b`. */ let node_a = self.get(a_id); - let a_id = node_a.root; + let a_id = copy node_a.root; match node_a.possible_types { None => { @@ -223,7 +221,7 @@ impl InferCtxt { if *a_t == b { return uok(); } else { - return mk_err(a_is_expected, *a_t, b); + return mk_err(a_is_expected, copy *a_t, b); } } } diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index a118e445fe20..56646eb4bfbd 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -107,8 +107,8 @@ pub fn build_sized_opt(size: Option, #[inline(always)] pub fn append(lhs: @[T], rhs: &const [T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { - for lhs.each |x| { push(*x); } - for uint::range(0, rhs.len()) |i| { push(rhs[i]); } + for lhs.each |x| { push(copy *x); } + for uint::range(0, rhs.len()) |i| { push(copy rhs[i]); } } } @@ -168,7 +168,7 @@ pub fn to_managed_consume(v: ~[T]) -> @[T] { * elements of a slice. */ pub fn to_managed(v: &[T]) -> @[T] { - from_fn(v.len(), |i| v[i]) + from_fn(v.len(), |i| copy v[i]) } #[cfg(not(test))] diff --git a/src/libstd/either.rs b/src/libstd/either.rs index fac0866f17e7..e0451b2c65d4 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -47,7 +47,7 @@ pub fn lefts(eithers: &[Either]) -> ~[T] { do vec::build_sized(eithers.len()) |push| { for eithers.each |elt| { match *elt { - Left(ref l) => { push(*l); } + Left(ref l) => { push(copy *l); } _ => { /* fallthrough */ } } } @@ -59,7 +59,7 @@ pub fn rights(eithers: &[Either]) -> ~[U] { do vec::build_sized(eithers.len()) |push| { for eithers.each |elt| { match *elt { - Right(ref r) => { push(*r); } + Right(ref r) => { push(copy *r); } _ => { /* fallthrough */ } } } diff --git a/src/libstd/io.rs b/src/libstd/io.rs index d3faa75e3b04..3e771c4dddeb 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1779,7 +1779,7 @@ pub mod fsync { None => (), Some(level) => { // fail hard if not succesful - assert!(((self.arg.fsync_fn)(self.arg.val, level) + assert!(((self.arg.fsync_fn)(copy self.arg.val, level) != -1)); } } diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index 4681e4f4f53f..e73156243689 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -410,10 +410,10 @@ pub fn pow_with_uint+Mul>(radix: uint, pow let mut multiplier = cast(radix); while (my_pow > 0u) { if my_pow % 2u == 1u { - total *= multiplier; + total = total * multiplier; } - my_pow /= 2u; - multiplier *= multiplier; + my_pow = my_pow / 2u; + multiplier = multiplier * multiplier; } total } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 3905d82cd0f5..75c4fa98a2b5 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -229,7 +229,7 @@ pub fn to_str_bytes_common+ // Initialize accumulator with signed zero for floating point parsing to // work - let mut accum = if accum_positive { _0 } else { -_1 * _0}; - let mut last_accum = accum; // Necessary to detect overflow + let mut accum = if accum_positive { copy _0 } else { -_1 * _0}; + let mut last_accum = copy accum; // Necessary to detect overflow let mut i = start; let mut exp_found = false; @@ -511,13 +511,13 @@ pub fn from_str_bytes_common+ match char::to_digit(c, radix) { Some(digit) => { // shift accum one digit left - accum *= radix_gen; + accum = accum * copy radix_gen; // add/subtract current digit depending on sign if accum_positive { - accum += cast(digit as int); + accum = accum + cast(digit as int); } else { - accum -= cast(digit as int); + accum = accum - cast(digit as int); } // Detect overflow by comparing to last value, except @@ -526,7 +526,7 @@ pub fn from_str_bytes_common+ if accum_positive && accum <= last_accum { return None; } if !accum_positive && accum >= last_accum { return None; } } - last_accum = accum; + last_accum = copy accum; } None => match c { '_' if ignore_underscores => {} @@ -548,7 +548,7 @@ pub fn from_str_bytes_common+ // Parse fractional part of number // Skip if already reached start of exponent if !exp_found { - let mut power = _1; + let mut power = copy _1; while i < len { let c = buf[i] as char; @@ -556,21 +556,21 @@ pub fn from_str_bytes_common+ match char::to_digit(c, radix) { Some(digit) => { // Decrease power one order of magnitude - power /= radix_gen; + power = power / radix_gen; let digit_t: T = cast(digit); // add/subtract current digit depending on sign if accum_positive { - accum += digit_t * power; + accum = accum + digit_t * power; } else { - accum -= digit_t * power; + accum = accum - digit_t * power; } // Detect overflow by comparing to last value if accum_positive && accum < last_accum { return None; } if !accum_positive && accum > last_accum { return None; } - last_accum = accum; + last_accum = copy accum; } None => match c { '_' if ignore_underscores => {} @@ -596,7 +596,7 @@ pub fn from_str_bytes_common+ } } - let mut multiplier = _1; + let mut multiplier = copy _1; if exp_found { let c = buf[i] as char; diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index 347b47744228..96bcf4e91074 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -115,7 +115,7 @@ pub fn filter_to_vec>(this: &IA, -> ~[A] { do vec::build_sized_opt(this.size_hint()) |push| { for this.each |a| { - if prd(a) { push(*a); } + if prd(a) { push(copy *a); } } } } @@ -191,7 +191,7 @@ pub fn position>(this: &IA, f: &fn(&A) -> bool) pub fn find>(this: &IA, f: &fn(&A) -> bool) -> Option { for this.each |i| { - if f(i) { return Some(*i) } + if f(i) { return Some(copy *i) } } return None; } @@ -270,7 +270,7 @@ pub fn from_fn>(n_elts: uint, op: InitOp) -> BT { pub fn from_elem>(n_elts: uint, t: T) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0; - while i < n_elts { push(t); i += 1; } + while i < n_elts { push(copy t); i += 1; } } } @@ -281,8 +281,8 @@ pub fn append,BT:Buildable>(lhs: &IT, rhs: &IT) let size_opt = lhs.size_hint().chain_ref( |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); do build_sized_opt(size_opt) |push| { - for lhs.each |x| { push(*x); } - for rhs.each |x| { push(*x); } + for lhs.each |x| { push(copy *x); } + for rhs.each |x| { push(copy *x); } } } @@ -291,6 +291,6 @@ pub fn append,BT:Buildable>(lhs: &IT, rhs: &IT) #[inline(always)] pub fn copy_seq,BT:Buildable>(v: &IT) -> BT { do build_sized_opt(v.size_hint()) |push| { - for v.each |x| { push(*x); } + for v.each |x| { push(copy *x); } } } diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 762727064459..30394cb21afd 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -88,14 +88,14 @@ impl Ord for Option { } } -impl> Add, Option> for Option { +impl> Add, Option> for Option { #[inline(always)] fn add(&self, other: &Option) -> Option { - match (*self, *other) { - (None, None) => None, - (_, None) => *self, - (None, _) => *other, - (Some(ref lhs), Some(ref rhs)) => Some(*lhs + *rhs) + match (&*self, &*other) { + (&None, &None) => None, + (_, &None) => copy *self, + (&None, _) => copy *other, + (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs) } } } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 7946f7e4f13f..2d73ed0c6a1c 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -526,7 +526,7 @@ impl RngUtil for R { if values.is_empty() { None } else { - Some(values[self.gen_uint_range(0u, values.len())]) + Some(copy values[self.gen_uint_range(0u, values.len())]) } } /** @@ -555,7 +555,7 @@ impl RngUtil for R { for v.each |item| { so_far += item.weight; if so_far > chosen { - return Some(item.item); + return Some(copy item.item); } } util::unreachable(); @@ -569,7 +569,7 @@ impl RngUtil for R { let mut r = ~[]; for v.each |item| { for uint::range(0u, item.weight) |_i| { - r.push(item.item); + r.push(copy item.item); } } r diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index b80f152a5b1d..c120883be5a0 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -32,7 +32,7 @@ impl CopyableTuple for (T, U) { #[inline(always)] fn first(&self) -> T { match *self { - (t, _) => t, + (ref t, _) => copy *t, } } @@ -40,14 +40,14 @@ impl CopyableTuple for (T, U) { #[inline(always)] fn second(&self) -> U { match *self { - (_, u) => u, + (_, ref u) => copy *u, } } /// Return the results of swapping the two elements of self #[inline(always)] fn swap(&self) -> (U, T) { - match *self { + match copy *self { (t, u) => (u, t), } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1a236a49a322..3f7bf897be2e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -167,7 +167,7 @@ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { /// Creates a new unique vector with the same contents as the slice pub fn to_owned(t: &[T]) -> ~[T] { - from_fn(t.len(), |i| t[i]) + from_fn(t.len(), |i| copy t[i]) } /// Creates a new vector with a capacity of `capacity` @@ -441,9 +441,9 @@ pub fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { for each(v) |elt| { if f(elt) { - lefts.push(*elt); + lefts.push(copy *elt); } else { - rights.push(*elt); + rights.push(copy *elt); } } @@ -798,7 +798,7 @@ pub fn grow(v: &mut ~[T], n: uint, initval: &T) { let mut i: uint = 0u; while i < n { - v.push(*initval); + v.push(copy *initval); i += 1u; } } @@ -970,7 +970,7 @@ pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { - if f(elem) { result.push(*elem); } + if f(elem) { result.push(copy *elem); } } result } @@ -1026,7 +1026,7 @@ impl<'self, T:Copy> VectorVector for &'self [~[T]] { let mut r = ~[]; let mut first = true; for self.each |&inner| { - if first { first = false; } else { r.push(*sep); } + if first { first = false; } else { r.push(copy *sep); } r.push_all(inner); } r @@ -1044,7 +1044,7 @@ impl<'self, T:Copy> VectorVector for &'self [&'self [T]] { let mut r = ~[]; let mut first = true; for self.each |&inner| { - if first { first = false; } else { r.push(*sep); } + if first { first = false; } else { r.push(copy *sep); } r.push_all(inner); } r @@ -1077,7 +1077,7 @@ pub fn find(v: &[T], f: &fn(t: &T) -> bool) -> Option { */ pub fn find_between(v: &[T], start: uint, end: uint, f: &fn(t: &T) -> bool) -> Option { - position_between(v, start, end, f).map(|i| v[*i]) + position_between(v, start, end, f).map(|i| copy v[*i]) } /** @@ -1103,7 +1103,7 @@ pub fn rfind_between(v: &[T], end: uint, f: &fn(t: &T) -> bool) -> Option { - rposition_between(v, start, end, f).map(|i| v[*i]) + rposition_between(v, start, end, f).map(|i| copy v[*i]) } /// Find the first index containing a matching value @@ -1227,7 +1227,7 @@ pub fn bsearch_elem(v: &[T], x: &T) -> Option { pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { let mut (ts, us) = (~[], ~[]); for each(v) |p| { - let (t, u) = *p; + let (t, u) = copy *p; ts.push(t); us.push(u); } @@ -1262,7 +1262,7 @@ pub fn zip_slice(v: &const [T], u: &const [U]) let mut i = 0u; assert_eq!(sz, u.len()); while i < sz { - zipped.push((v[i], u[i])); + zipped.push((copy v[i], copy u[i])); i += 1u; } zipped @@ -1359,8 +1359,8 @@ pub fn reversed(v: &const [T]) -> ~[T] { let mut rs: ~[T] = ~[]; let mut i = v.len(); if i == 0 { return (rs); } else { i -= 1; } - while i != 0 { rs.push(v[i]); i -= 1; } - rs.push(v[0]); + while i != 0 { rs.push(copy v[i]); i -= 1; } + rs.push(copy v[0]); rs } @@ -1479,7 +1479,7 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { */ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> bool { let length = values.len(); - let mut permutation = vec::from_fn(length, |i| values[i]); + let mut permutation = vec::from_fn(length, |i| copy values[i]); if length <= 1 { fun(permutation); return true; @@ -1506,7 +1506,7 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> reverse_part(indices, k+1, length); // fixup permutation based on indices for uint::range(k, length) |i| { - permutation[i] = values[indices[i]]; + permutation[i] = copy values[indices[i]]; } } } @@ -2031,7 +2031,7 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { /// Returns the element at the given index, without doing bounds checking. #[inline(always)] unsafe fn unsafe_get(&self, index: uint) -> T { - *self.unsafe_ref(index) + copy *self.unsafe_ref(index) } } @@ -2350,7 +2350,7 @@ pub mod raw { */ #[inline(always)] pub unsafe fn get(v: &const [T], i: uint) -> T { - as_const_buf(v, |p, _len| *ptr::const_offset(p, i)) + as_const_buf(v, |p, _len| copy *ptr::const_offset(p, i)) } /** diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index cc89db6e1893..07913946578f 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -395,30 +395,30 @@ impl id_range { pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { let visit_generics: @fn(&Generics, T) = |generics, t| { for generics.ty_params.each |p| { - vfn(p.id, t); + vfn(p.id, copy t); } for generics.lifetimes.each |p| { - vfn(p.id, t); + vfn(p.id, copy t); } }; visit::mk_vt(@visit::Visitor { visit_mod: |m, sp, id, (t, vt)| { - vfn(id, t); + vfn(id, copy t); visit::visit_mod(m, sp, id, (t, vt)); }, visit_view_item: |vi, (t, vt)| { match vi.node { - view_item_extern_mod(_, _, id) => vfn(id, t), + view_item_extern_mod(_, _, id) => vfn(id, copy t), view_item_use(ref vps) => { for vps.each |vp| { match vp.node { - view_path_simple(_, _, id) => vfn(id, t), - view_path_glob(_, id) => vfn(id, t), + view_path_simple(_, _, id) => vfn(id, copy t), + view_path_glob(_, id) => vfn(id, copy t), view_path_list(_, ref paths, id) => { - vfn(id, t); + vfn(id, copy t); for paths.each |p| { - vfn(p.node.id, t); + vfn(p.node.id, copy t); } } } @@ -429,34 +429,34 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { }, visit_foreign_item: |ni, (t, vt)| { - vfn(ni.id, t); + vfn(ni.id, copy t); visit::visit_foreign_item(ni, (t, vt)); }, visit_item: |i, (t, vt)| { - vfn(i.id, t); + vfn(i.id, copy t); match i.node { item_enum(ref enum_definition, _) => - for (*enum_definition).variants.each |v| { vfn(v.node.id, t); }, + for (*enum_definition).variants.each |v| { vfn(v.node.id, copy t); }, _ => () } visit::visit_item(i, (t, vt)); }, visit_local: |l, (t, vt)| { - vfn(l.node.id, t); + vfn(l.node.id, copy t); visit::visit_local(l, (t, vt)); }, visit_block: |b, (t, vt)| { - vfn(b.node.id, t); + vfn(b.node.id, copy t); visit::visit_block(b, (t, vt)); }, visit_stmt: |s, (t, vt)| { - vfn(ast_util::stmt_id(s), t); + vfn(ast_util::stmt_id(s), copy t); visit::visit_stmt(s, (t, vt)); }, visit_pat: |p, (t, vt)| { - vfn(p.id, t); + vfn(p.id, copy t); visit::visit_pat(p, (t, vt)); }, @@ -464,36 +464,36 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { { let r = e.get_callee_id(); for r.iter().advance |callee_id| { - vfn(*callee_id, t); + vfn(*callee_id, copy t); } } - vfn(e.id, t); + vfn(e.id, copy t); visit::visit_expr(e, (t, vt)); }, visit_ty: |ty, (t, vt)| { match ty.node { - ty_path(_, id) => vfn(id, t), + ty_path(_, id) => vfn(id, copy t), _ => { /* fall through */ } } visit::visit_ty(ty, (t, vt)); }, visit_generics: |generics, (t, vt)| { - visit_generics(generics, t); + visit_generics(generics, copy t); visit::visit_generics(generics, (t, vt)); }, visit_fn: |fk, d, a, b, id, (t, vt)| { - vfn(id, t); + vfn(id, copy t); match *fk { visit::fk_item_fn(_, generics, _, _) => { - visit_generics(generics, t); + visit_generics(generics, copy t); } visit::fk_method(_, generics, m) => { - vfn(m.self_id, t); - visit_generics(generics, t); + vfn(m.self_id, copy t); + visit_generics(generics, copy t); } visit::fk_anon(_) | visit::fk_fn_block => { @@ -501,13 +501,13 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { } for d.inputs.each |arg| { - vfn(arg.id, t) + vfn(arg.id, copy t) } - visit::visit_fn(fk, d, a, b, id, (t, vt)); + visit::visit_fn(fk, d, a, b, id, (copy t, vt)); }, visit_struct_field: |f, (t, vt)| { - vfn(f.node.id, t); + vfn(f.node.id, copy t); visit::visit_struct_field(f, (t, vt)); }, diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 1704b4ef6c5b..e67ca5260b8f 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -318,7 +318,7 @@ pub fn expect(diag: @span_handler, opt: Option, msg: &fn() -> ~str) -> T { match opt { - Some(ref t) => (*t), + Some(ref t) => copy *t, None => diag.handler().bug(msg()) } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7eec9e2ee896..e72d9b502dcd 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -322,7 +322,7 @@ pub fn commasep(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN)) { let mut first = true; for elts.each |elt| { if first { first = false; } else { word_space(s, ","); } - op(s, *elt); + op(s, copy *elt); } end(s); } @@ -334,13 +334,13 @@ pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN), let len = elts.len(); let mut i = 0u; for elts.each |elt| { - maybe_print_comment(s, get_span(*elt).hi); - op(s, *elt); + maybe_print_comment(s, get_span(copy *elt).hi); + op(s, copy *elt); i += 1u; if i < len { word(s.s, ","); - maybe_print_trailing_comment(s, get_span(*elt), - Some(get_span(elts[i]).hi)); + maybe_print_trailing_comment(s, get_span(copy *elt), + Some(get_span(copy elts[i]).hi)); space_if_not_bol(s); } } @@ -2118,7 +2118,7 @@ pub fn print_string(s: @ps, st: &str) { pub fn to_str(t: T, f: @fn(@ps, T), intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); - f(s, t); + f(s, copy t); eof(s.s); } } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index d4f183ada7b6..bd5c178e7fe7 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -36,7 +36,7 @@ impl Interner { pub fn prefill(init: &[T]) -> Interner { let rv = Interner::new(); - for init.each() |v| { rv.intern(*v); } + for init.each() |v| { rv.intern(copy *v); } rv } @@ -48,7 +48,7 @@ impl Interner { let vect = &mut *self.vect; let new_idx = vect.len(); - self.map.insert(val, new_idx); + self.map.insert(copy val, new_idx); vect.push(val); new_idx } @@ -63,7 +63,7 @@ impl Interner { new_idx } - pub fn get(&self, idx: uint) -> T { self.vect[idx] } + pub fn get(&self, idx: uint) -> T { copy self.vect[idx] } pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 6e753a8cc58e..f24c393d7b48 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -127,15 +127,15 @@ pub fn visit_crate(c: &crate, (e, v): (E, vt)) { } pub fn visit_mod(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt)) { - for m.view_items.each |vi| { (v.visit_view_item)(*vi, (e, v)); } - for m.items.each |i| { (v.visit_item)(*i, (e, v)); } + for m.view_items.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); } + for m.items.each |i| { (v.visit_item)(*i, (copy e, v)); } } pub fn visit_view_item(_vi: @view_item, (_e, _v): (E, vt)) { } pub fn visit_local(loc: @local, (e, v): (E, vt)) { - (v.visit_pat)(loc.node.pat, (e, v)); - (v.visit_ty)(loc.node.ty, (e, v)); + (v.visit_pat)(loc.node.pat, (copy e, v)); + (v.visit_ty)(loc.node.ty, (copy e, v)); match loc.node.init { None => (), Some(ex) => (v.visit_expr)(ex, (e, v)) @@ -149,8 +149,8 @@ fn visit_trait_ref(tref: @ast::trait_ref, (e, v): (E, vt)) { pub fn visit_item(i: @item, (e, v): (E, vt)) { match i.node { item_const(t, ex) => { - (v.visit_ty)(t, (e, v)); - (v.visit_expr)(ex, (e, v)); + (v.visit_ty)(t, (copy e, v)); + (v.visit_expr)(ex, (copy e, v)); } item_fn(ref decl, purity, abi, ref generics, ref body) => { (v.visit_fn)( @@ -170,15 +170,15 @@ pub fn visit_item(i: @item, (e, v): (E, vt)) { } item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)), item_foreign_mod(ref nm) => { - for nm.view_items.each |vi| { (v.visit_view_item)(*vi, (e, v)); } - for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (e, v)); } + for nm.view_items.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); } + for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); } } item_ty(t, ref tps) => { - (v.visit_ty)(t, (e, v)); + (v.visit_ty)(t, (copy e, v)); (v.visit_generics)(tps, (e, v)); } item_enum(ref enum_definition, ref tps) => { - (v.visit_generics)(tps, (e, v)); + (v.visit_generics)(tps, (copy e, v)); visit_enum_def( enum_definition, tps, @@ -186,24 +186,24 @@ pub fn visit_item(i: @item, (e, v): (E, vt)) { ); } item_impl(ref tps, ref traits, ty, ref methods) => { - (v.visit_generics)(tps, (e, v)); + (v.visit_generics)(tps, (copy e, v)); for traits.iter().advance |&p| { - visit_trait_ref(p, (e, v)); + visit_trait_ref(p, (copy e, v)); } - (v.visit_ty)(ty, (e, v)); + (v.visit_ty)(ty, (copy e, v)); for methods.each |m| { - visit_method_helper(*m, (e, v)) + visit_method_helper(*m, (copy e, v)) } } item_struct(struct_def, ref generics) => { - (v.visit_generics)(generics, (e, v)); + (v.visit_generics)(generics, (copy e, v)); (v.visit_struct_def)(struct_def, i.ident, generics, i.id, (e, v)); } item_trait(ref generics, ref traits, ref methods) => { - (v.visit_generics)(generics, (e, v)); - for traits.each |p| { visit_path(p.path, (e, v)); } + (v.visit_generics)(generics, (copy e, v)); + for traits.each |p| { visit_path(p.path, (copy e, v)); } for methods.each |m| { - (v.visit_trait_method)(m, (e, v)); + (v.visit_trait_method)(m, (copy e, v)); } } item_mac(ref m) => visit_mac(m, (e, v)) @@ -216,15 +216,19 @@ pub fn visit_enum_def(enum_definition: &ast::enum_def, for enum_definition.variants.each |vr| { match vr.node.kind { tuple_variant_kind(ref variant_args) => { - for variant_args.each |va| { (v.visit_ty)(va.ty, (e, v)); } + for variant_args.each |va| { + (v.visit_ty)(va.ty, (copy e, v)); + } } struct_variant_kind(struct_def) => { (v.visit_struct_def)(struct_def, vr.node.name, tps, - vr.node.id, (e, v)); + vr.node.id, (copy e, v)); } } // Visit the disr expr if it exists - for vr.node.disr_expr.iter().advance |ex| { (v.visit_expr)(*ex, (e, v)) } + for vr.node.disr_expr.iter().advance |ex| { + (v.visit_expr)(*ex, (copy e, v)) + } } } @@ -238,71 +242,75 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { }, ty_tup(ref ts) => { for ts.each |tt| { - (v.visit_ty)(*tt, (e, v)); + (v.visit_ty)(*tt, (copy e, v)); } }, ty_closure(ref f) => { - for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); } + for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); } (v.visit_ty)(f.decl.output, (e, v)); }, ty_bare_fn(ref f) => { - for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); } + for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); } (v.visit_ty)(f.decl.output, (e, v)); }, ty_path(p, _) => visit_path(p, (e, v)), ty_fixed_length_vec(ref mt, ex) => { - (v.visit_ty)(mt.ty, (e, v)); - (v.visit_expr)(ex, (e, v)); + (v.visit_ty)(mt.ty, (copy e, v)); + (v.visit_expr)(ex, (copy e, v)); }, ty_nil | ty_bot | ty_mac(_) | ty_infer => () } } pub fn visit_path(p: @Path, (e, v): (E, vt)) { - for p.types.each |tp| { (v.visit_ty)(*tp, (e, v)); } + for p.types.each |tp| { (v.visit_ty)(*tp, (copy e, v)); } } pub fn visit_pat(p: @pat, (e, v): (E, vt)) { match p.node { pat_enum(path, ref children) => { - visit_path(path, (e, v)); + visit_path(path, (copy e, v)); for children.iter().advance |children| { - for children.iter().advance |child| { (v.visit_pat)(*child, (e, v)); } + for children.iter().advance |child| { + (v.visit_pat)(*child, (copy e, v)); + } } } pat_struct(path, ref fields, _) => { - visit_path(path, (e, v)); + visit_path(path, (copy e, v)); for fields.each |f| { - (v.visit_pat)(f.pat, (e, v)); + (v.visit_pat)(f.pat, (copy e, v)); } } pat_tup(ref elts) => { for elts.each |elt| { - (v.visit_pat)(*elt, (e, v)) + (v.visit_pat)(*elt, (copy e, v)) } }, pat_box(inner) | pat_uniq(inner) | pat_region(inner) => { (v.visit_pat)(inner, (e, v)) }, pat_ident(_, path, ref inner) => { - visit_path(path, (e, v)); - for inner.iter().advance |subpat| { (v.visit_pat)(*subpat, (e, v)) } + visit_path(path, (copy e, v)); + for inner.iter().advance |subpat| { + (v.visit_pat)(*subpat, (copy e, v)) + } } pat_lit(ex) => (v.visit_expr)(ex, (e, v)), pat_range(e1, e2) => { - (v.visit_expr)(e1, (e, v)); + (v.visit_expr)(e1, (copy e, v)); (v.visit_expr)(e2, (e, v)); } pat_wild => (), pat_vec(ref before, ref slice, ref after) => { for before.each |elt| { - (v.visit_pat)(*elt, (e, v)); + (v.visit_pat)(*elt, (copy e, v)); } for slice.iter().advance |elt| { - (v.visit_pat)(*elt, (e, v)); + (v.visit_pat)(*elt, (copy e, v)); } for after.each |tail| { - (v.visit_pat)(*tail, (e, v)); + (v.visit_pat)(*tail, (copy e, v)); } } } @@ -311,7 +319,7 @@ pub fn visit_pat(p: @pat, (e, v): (E, vt)) { pub fn visit_foreign_item(ni: @foreign_item, (e, v): (E, vt)) { match ni.node { foreign_item_fn(ref fd, _, ref generics) => { - visit_fn_decl(fd, (e, v)); + visit_fn_decl(fd, (copy e, v)); (v.visit_generics)(generics, (e, v)); } foreign_item_const(t) => { @@ -324,7 +332,7 @@ pub fn visit_ty_param_bounds(bounds: @OptVec, (e, v): (E, vt)) { for bounds.each |bound| { match *bound { - TraitTyParamBound(ty) => visit_trait_ref(ty, (e, v)), + TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)), RegionTyParamBound => {} } } @@ -332,14 +340,14 @@ pub fn visit_ty_param_bounds(bounds: @OptVec, pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { for generics.ty_params.each |tp| { - visit_ty_param_bounds(tp.bounds, (e, v)); + visit_ty_param_bounds(tp.bounds, (copy e, v)); } } pub fn visit_fn_decl(fd: &fn_decl, (e, v): (E, vt)) { for fd.inputs.each |a| { - (v.visit_pat)(a.pat, (e, v)); - (v.visit_ty)(a.ty, (e, v)); + (v.visit_pat)(a.pat, (copy e, v)); + (v.visit_ty)(a.ty, (copy e, v)); } (v.visit_ty)(fd.output, (e, v)); } @@ -365,15 +373,15 @@ pub fn visit_method_helper(m: &method, (e, v): (E, vt)) { pub fn visit_fn(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span, _id: node_id, (e, v): (E, vt)) { - visit_fn_decl(decl, (e, v)); + visit_fn_decl(decl, (copy e, v)); let generics = generics_of_fn(fk); - (v.visit_generics)(&generics, (e, v)); + (v.visit_generics)(&generics, (copy e, v)); (v.visit_block)(body, (e, v)); } pub fn visit_ty_method(m: &ty_method, (e, v): (E, vt)) { - for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); } - (v.visit_generics)(&m.generics, (e, v)); + for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); } + (v.visit_generics)(&m.generics, (copy e, v)); (v.visit_ty)(m.decl.output, (e, v)); } @@ -392,7 +400,7 @@ pub fn visit_struct_def( (e, v): (E, vt) ) { for sd.fields.each |f| { - (v.visit_struct_field)(*f, (e, v)); + (v.visit_struct_field)(*f, (copy e, v)); } } @@ -406,10 +414,10 @@ pub fn visit_struct_method(m: @method, (e, v): (E, vt)) { pub fn visit_block(b: &blk, (e, v): (E, vt)) { for b.node.view_items.each |vi| { - (v.visit_view_item)(*vi, (e, v)); + (v.visit_view_item)(*vi, (copy e, v)); } for b.node.stmts.each |s| { - (v.visit_stmt)(*s, (e, v)); + (v.visit_stmt)(*s, (copy e, v)); } visit_expr_opt(b.node.expr, (e, v)); } @@ -435,7 +443,7 @@ pub fn visit_expr_opt(eo: Option<@expr>, (e, v): (E, vt)) { } pub fn visit_exprs(exprs: &[@expr], (e, v): (E, vt)) { - for exprs.each |ex| { (v.visit_expr)(*ex, (e, v)); } + for exprs.each |ex| { (v.visit_expr)(*ex, (copy e, v)); } } pub fn visit_mac(_m: &mac, (_e, _v): (E, vt)) { @@ -444,53 +452,57 @@ pub fn visit_mac(_m: &mac, (_e, _v): (E, vt)) { pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { match ex.node { - expr_vstore(x, _) => (v.visit_expr)(x, (e, v)), - expr_vec(ref es, _) => visit_exprs(*es, (e, v)), + expr_vstore(x, _) => (v.visit_expr)(x, (copy e, v)), + expr_vec(ref es, _) => visit_exprs(*es, (copy e, v)), expr_repeat(element, count, _) => { - (v.visit_expr)(element, (e, v)); - (v.visit_expr)(count, (e, v)); + (v.visit_expr)(element, (copy e, v)); + (v.visit_expr)(count, (copy e, v)); } expr_struct(p, ref flds, base) => { - visit_path(p, (e, v)); - for flds.each |f| { (v.visit_expr)(f.node.expr, (e, v)); } - visit_expr_opt(base, (e, v)); + visit_path(p, (copy e, v)); + for flds.each |f| { + (v.visit_expr)(f.node.expr, (copy e, v)); + } + visit_expr_opt(base, (copy e, v)); } expr_tup(ref elts) => { - for elts.each |el| { (v.visit_expr)(*el, (e, v)) } + for elts.each |el| { (v.visit_expr)(*el, (copy e, v)) } } expr_call(callee, ref args, _) => { - visit_exprs(*args, (e, v)); - (v.visit_expr)(callee, (e, v)); + visit_exprs(*args, (copy e, v)); + (v.visit_expr)(callee, (copy e, v)); } expr_method_call(_, callee, _, ref tys, ref args, _) => { - visit_exprs(*args, (e, v)); - for tys.each |tp| { (v.visit_ty)(*tp, (e, v)); } - (v.visit_expr)(callee, (e, v)); + visit_exprs(*args, (copy e, v)); + for tys.each |tp| { + (v.visit_ty)(*tp, (copy e, v)); + } + (v.visit_expr)(callee, (copy e, v)); } expr_binary(_, _, a, b) => { - (v.visit_expr)(a, (e, v)); - (v.visit_expr)(b, (e, v)); + (v.visit_expr)(a, (copy e, v)); + (v.visit_expr)(b, (copy e, v)); } expr_addr_of(_, x) | expr_unary(_, _, x) | - expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e, v)), + expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (copy e, v)), expr_lit(_) => (), expr_cast(x, t) => { - (v.visit_expr)(x, (e, v)); - (v.visit_ty)(t, (e, v)); + (v.visit_expr)(x, (copy e, v)); + (v.visit_ty)(t, (copy e, v)); } expr_if(x, ref b, eo) => { - (v.visit_expr)(x, (e, v)); - (v.visit_block)(b, (e, v)); - visit_expr_opt(eo, (e, v)); + (v.visit_expr)(x, (copy e, v)); + (v.visit_block)(b, (copy e, v)); + visit_expr_opt(eo, (copy e, v)); } expr_while(x, ref b) => { - (v.visit_expr)(x, (e, v)); - (v.visit_block)(b, (e, v)); + (v.visit_expr)(x, (copy e, v)); + (v.visit_block)(b, (copy e, v)); } - expr_loop(ref b, _) => (v.visit_block)(b, (e, v)), + expr_loop(ref b, _) => (v.visit_block)(b, (copy e, v)), expr_match(x, ref arms) => { - (v.visit_expr)(x, (e, v)); - for arms.each |a| { (v.visit_arm)(a, (e, v)); } + (v.visit_expr)(x, (copy e, v)); + for arms.each |a| { (v.visit_arm)(a, (copy e, v)); } } expr_fn_block(ref decl, ref body) => { (v.visit_fn)( @@ -499,44 +511,46 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { body, ex.span, ex.id, - (e, v) + (copy e, v) ); } - expr_block(ref b) => (v.visit_block)(b, (e, v)), + expr_block(ref b) => (v.visit_block)(b, (copy e, v)), expr_assign(a, b) => { - (v.visit_expr)(b, (e, v)); - (v.visit_expr)(a, (e, v)); + (v.visit_expr)(b, (copy e, v)); + (v.visit_expr)(a, (copy e, v)); } - expr_copy(a) => (v.visit_expr)(a, (e, v)), + expr_copy(a) => (v.visit_expr)(a, (copy e, v)), expr_assign_op(_, _, a, b) => { - (v.visit_expr)(b, (e, v)); - (v.visit_expr)(a, (e, v)); + (v.visit_expr)(b, (copy e, v)); + (v.visit_expr)(a, (copy e, v)); } expr_field(x, _, ref tys) => { - (v.visit_expr)(x, (e, v)); - for tys.each |tp| { (v.visit_ty)(*tp, (e, v)); } + (v.visit_expr)(x, (copy e, v)); + for tys.each |tp| { + (v.visit_ty)(*tp, (copy e, v)); + } } expr_index(_, a, b) => { - (v.visit_expr)(a, (e, v)); - (v.visit_expr)(b, (e, v)); + (v.visit_expr)(a, (copy e, v)); + (v.visit_expr)(b, (copy e, v)); } - expr_path(p) => visit_path(p, (e, v)), + expr_path(p) => visit_path(p, (copy e, v)), expr_self => (), expr_break(_) => (), expr_again(_) => (), - expr_ret(eo) => visit_expr_opt(eo, (e, v)), + expr_ret(eo) => visit_expr_opt(eo, (copy e, v)), expr_log(lv, x) => { - (v.visit_expr)(lv, (e, v)); - (v.visit_expr)(x, (e, v)); + (v.visit_expr)(lv, (copy e, v)); + (v.visit_expr)(x, (copy e, v)); } - expr_mac(ref mac) => visit_mac(mac, (e, v)), - expr_paren(x) => (v.visit_expr)(x, (e, v)), + expr_mac(ref mac) => visit_mac(mac, (copy e, v)), + expr_paren(x) => (v.visit_expr)(x, (copy e, v)), expr_inline_asm(ref a) => { for a.inputs.each |&(_, in)| { - (v.visit_expr)(in, (e, v)); + (v.visit_expr)(in, (copy e, v)); } for a.outputs.each |&(_, out)| { - (v.visit_expr)(out, (e, v)); + (v.visit_expr)(out, (copy e, v)); } } } @@ -544,9 +558,9 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { } pub fn visit_arm(a: &arm, (e, v): (E, vt)) { - for a.pats.iter().advance |p| { (v.visit_pat)(*p, (e, v)); } - visit_expr_opt(a.guard, (e, v)); - (v.visit_block)(&a.body, (e, v)); + for a.pats.iter().advance |p| { (v.visit_pat)(*p, (copy e, v)); } + visit_expr_opt(a.guard, (copy e, v)); + (v.visit_block)(&a.body, (copy e, v)); } // Simpler, non-context passing interface. Always walks the whole tree, simply diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index e58b28aa3ded..e45bfc8ea5dc 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -14,7 +14,7 @@ use std::task; pub fn foo(x: T) -> Port { let (p, c) = stream(); do task::spawn() { - c.send(x); + c.send(copy x); } p } diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs index 5701912b5f6f..c0b98f2af07c 100644 --- a/src/test/auxiliary/cci_nested_lib.rs +++ b/src/test/auxiliary/cci_nested_lib.rs @@ -25,7 +25,7 @@ pub fn alist_add(lst: &alist, k: A, v: B) { pub fn alist_get(lst: &alist, k: A) -> B { let eq_fn = lst.eq_fn; for lst.data.each |entry| { - if eq_fn(entry.key, k) { return entry.value; } + if eq_fn(copy entry.key, copy k) { return copy entry.value; } } fail!(); } diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 9fbc1d4590de..7a9be7548849 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -30,9 +30,7 @@ use std::ptr; use std::uint; use std::vec; -macro_rules! move_out ( - { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } } -) +fn move_out(x: T) {} enum request { get_count, @@ -91,7 +89,7 @@ fn run(args: &[~str]) { //error!("sending stop message"); to_child.send(stop); - move_out!(to_child); + move_out(to_child); let result = from_child.recv(); let end = extra::time::precise_time_s(); let elapsed = end - start; diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 2663bb266706..796072c84858 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -25,9 +25,7 @@ use std::task; use std::uint; use std::vec; -macro_rules! move_out ( - { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } } -) +fn move_out(x: T) {} enum request { get_count, @@ -87,7 +85,7 @@ fn run(args: &[~str]) { //error!("sending stop message"); to_child.send(stop); - move_out!(to_child); + move_out(to_child); let result = from_child.recv(); let end = extra::time::precise_time_s(); let elapsed = end - start; diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs index f2bb77b26ef5..0f6ca37a3fbb 100644 --- a/src/test/bench/msgsend-ring-pipes.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -34,10 +34,6 @@ proto! ring ( } ) -macro_rules! move_out ( - ($x:expr) => { unsafe { let y = *ptr::to_unsafe_ptr(&$x); y } } -) - fn thread_ring(i: uint, count: uint, num_chan: ring::client::num, @@ -54,7 +50,7 @@ fn thread_ring(i: uint, match recv(port) { ring::num(_n, p) => { //log(error, _n); - num_port = Some(move_out!(p)); + num_port = Some(p); } } }; diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index b7969fb0552e..e12df5811eee 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -36,15 +36,15 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { fn le_by_val(kv0: &(TT,UU), kv1: &(TT,UU)) -> bool { - let (_, v0) = *kv0; - let (_, v1) = *kv1; + let (_, v0) = copy *kv0; + let (_, v1) = copy *kv1; return v0 >= v1; } fn le_by_key(kv0: &(TT,UU), kv1: &(TT,UU)) -> bool { - let (k0, _) = *kv0; - let (k1, _) = *kv1; + let (k0, _) = copy *kv0; + let (k1, _) = copy *kv1; return k0 <= k1; } diff --git a/src/test/compile-fail/infinite-instantiation.rs b/src/test/compile-fail/infinite-instantiation.rs index 605453d1bca2..377b2016bcbe 100644 --- a/src/test/compile-fail/infinite-instantiation.rs +++ b/src/test/compile-fail/infinite-instantiation.rs @@ -23,7 +23,7 @@ impl to_opt for uint { impl to_opt for Option { fn to_option(&self) -> Option> { - Some(*self) + Some(copy *self) } } diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index 27cc07ed123b..ec84551f7b0a 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -9,12 +9,13 @@ // except according to those terms. fn copy1(t: T) -> @fn() -> T { - let result: @fn() -> T = || t; //~ ERROR value may contain borrowed pointers + let result: @fn() -> T = || copy t; + //~^ ERROR value may contain borrowed pointers result } fn copy2(t: T) -> @fn() -> T { - let result: @fn() -> T = || t; + let result: @fn() -> T = || copy t; result } diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs index bf96d6cfab52..6f1b4b815213 100644 --- a/src/test/run-pass/alignment-gep-tup-like-1.rs +++ b/src/test/run-pass/alignment-gep-tup-like-1.rs @@ -13,7 +13,7 @@ struct pair { } fn f(a: A, b: u16) -> @fn() -> (A, u16) { - let result: @fn() -> (A, u16) = || (a, b); + let result: @fn() -> (A, u16) = || (copy a, b); result } diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index 6bf4e96bc053..753e5339de9d 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -24,7 +24,7 @@ fn make_cycle(a: A) { } fn f(a: A, b: B) -> @fn() -> (A, B) { - let result: @fn() -> (A, B) = || (a, b); + let result: @fn() -> (A, B) = || (copy a, copy b); result } diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index 7b03a699e783..6e5b837e0aaf 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -41,6 +41,10 @@ fn test_ebml or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// just make sure this compiles: - -fn bar(x: *~int) -> ~int { - unsafe { - let y = *x; - return y; - } -} - -pub fn main() { -} diff --git a/src/test/run-pass/borrowed-ptr-pattern.rs b/src/test/run-pass/borrowed-ptr-pattern.rs index e0af2e80508c..86e8f600cd53 100644 --- a/src/test/run-pass/borrowed-ptr-pattern.rs +++ b/src/test/run-pass/borrowed-ptr-pattern.rs @@ -10,7 +10,7 @@ fn foo(x: &T) -> T{ match x { - &a => a + &ref a => copy *a } } diff --git a/src/test/run-pass/box-unbox.rs b/src/test/run-pass/box-unbox.rs index e7dc43656798..f4fb10fea724 100644 --- a/src/test/run-pass/box-unbox.rs +++ b/src/test/run-pass/box-unbox.rs @@ -12,7 +12,7 @@ struct Box {c: @T} -fn unbox(b: Box) -> T { return *b.c; } +fn unbox(b: Box) -> T { return copy *b.c; } pub fn main() { let foo: int = 17; diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs index 736c0f919417..69da3c8d9862 100644 --- a/src/test/run-pass/close-over-big-then-small-data.rs +++ b/src/test/run-pass/close-over-big-then-small-data.rs @@ -17,7 +17,7 @@ struct Pair { } fn f(a: A, b: u16) -> @fn() -> (A, u16) { - let result: @fn() -> (A, u16) = || (a, b); + let result: @fn() -> (A, u16) = || (copy a, b); result } diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs index 5d26fbdd7893..9cf047d425c3 100644 --- a/src/test/run-pass/expr-block-generic-box2.rs +++ b/src/test/run-pass/expr-block-generic-box2.rs @@ -14,7 +14,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = { expected }; + let actual: T = { copy expected }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs index 0d70bff36497..25bf553ff35c 100644 --- a/src/test/run-pass/expr-block-generic-unique2.rs +++ b/src/test/run-pass/expr-block-generic-unique2.rs @@ -14,7 +14,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = { expected }; + let actual: T = { copy expected }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs index e507700e6b28..afb1a4c76bbb 100644 --- a/src/test/run-pass/expr-block-generic.rs +++ b/src/test/run-pass/expr-block-generic.rs @@ -16,7 +16,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = { expected }; + let actual: T = { copy expected }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs index 12193037e119..186d15c3490a 100644 --- a/src/test/run-pass/expr-if-generic-box2.rs +++ b/src/test/run-pass/expr-if-generic-box2.rs @@ -14,7 +14,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, not_expected: T, eq: compare) { - let actual: T = if true { expected } else { not_expected }; + let actual: T = if true { copy expected } else { not_expected }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs index 8d2ce83c8794..2e6db3bba07f 100644 --- a/src/test/run-pass/expr-if-generic.rs +++ b/src/test/run-pass/expr-if-generic.rs @@ -15,7 +15,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, not_expected: T, eq: compare) { - let actual: T = if true { expected } else { not_expected }; + let actual: T = if true { copy expected } else { not_expected }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/expr-match-generic-box2.rs b/src/test/run-pass/expr-match-generic-box2.rs index c5c89b428255..64aa4ce3609a 100644 --- a/src/test/run-pass/expr-match-generic-box2.rs +++ b/src/test/run-pass/expr-match-generic-box2.rs @@ -14,7 +14,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = match true { true => { expected }, _ => fail!("wat") }; + let actual: T = match true { true => { copy expected }, _ => fail!("wat") }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/expr-match-generic.rs b/src/test/run-pass/expr-match-generic.rs index 04a229f22800..bd87e7207d14 100644 --- a/src/test/run-pass/expr-match-generic.rs +++ b/src/test/run-pass/expr-match-generic.rs @@ -14,7 +14,7 @@ type compare = @fn(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = match true { true => { expected }, _ => fail!("wat") }; + let actual: T = match true { true => { copy expected }, _ => fail!("wat") }; assert!((eq(expected, actual))); } diff --git a/src/test/run-pass/generic-derived-type.rs b/src/test/run-pass/generic-derived-type.rs index 9e266a3f2080..649fe3433b46 100644 --- a/src/test/run-pass/generic-derived-type.rs +++ b/src/test/run-pass/generic-derived-type.rs @@ -15,8 +15,7 @@ fn g(x: X) -> X { return x; } struct Pair {a: T, b: T} fn f(t: T) -> Pair { - - let x: Pair = Pair {a: t, b: t}; + let x: Pair = Pair {a: copy t, b: t}; return g::>(x); } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 4ef83e405be4..014aebeff9da 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -233,9 +233,7 @@ pub mod pingpong { let addr : *::pipes::send_packet = match &p { &ping(ref x) => { cast::transmute(x) } }; - let liberated_value = *addr; - cast::forget(p); - liberated_value + fail!() } } @@ -244,9 +242,7 @@ pub mod pingpong { let addr : *::pipes::send_packet = match &p { &pong(ref x) => { cast::transmute(x) } }; - let liberated_value = *addr; - cast::forget(p); - liberated_value + fail!() } } diff --git a/src/test/run-pass/ivec-add.rs b/src/test/run-pass/ivec-add.rs index 80168daf62d0..7cee6b4e8de6 100644 --- a/src/test/run-pass/ivec-add.rs +++ b/src/test/run-pass/ivec-add.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn double(a: T) -> ~[T] { return ~[a] + ~[a]; } +fn double(a: T) -> ~[T] { return ~[copy a] + ~[a]; } -fn double_int(a: int) -> ~[int] { return ~[a] + ~[a]; } +fn double_int(a: int) -> ~[int] { return ~[copy a] + ~[a]; } pub fn main() { let mut d = double(1); diff --git a/src/test/run-pass/kindck-owned-trait-contains-1.rs b/src/test/run-pass/kindck-owned-trait-contains-1.rs index 35b5e077e7af..c51094d26c88 100644 --- a/src/test/run-pass/kindck-owned-trait-contains-1.rs +++ b/src/test/run-pass/kindck-owned-trait-contains-1.rs @@ -11,7 +11,7 @@ trait repeat { fn get(&self) -> A; } impl repeat for @A { - fn get(&self) -> A { **self } + fn get(&self) -> A { copy **self } } fn repeater(v: @A) -> @repeat { diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index f4ccd038afee..e091554a3572 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -486,9 +486,9 @@ struct Stuff { } impl my_visitor { - pub fn get(&self, f: &fn(T)) { + pub fn get(&self, f: &fn(T)) { unsafe { - f(*(self.ptr1 as *T)); + f(copy *(self.ptr1 as *T)); } } diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs index 41eafb0293af..7a18cd02c2de 100644 --- a/src/test/run-pass/resource-generic.rs +++ b/src/test/run-pass/resource-generic.rs @@ -20,7 +20,7 @@ struct finish { impl Drop for finish { fn finalize(&self) { unsafe { - (self.arg.fin)(self.arg.val); + (self.arg.fin)(copy self.arg.val); } } } diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs index 4dde143f686b..2d6b2141c5c7 100644 --- a/src/test/run-pass/static-method-test.rs +++ b/src/test/run-pass/static-method-test.rs @@ -21,7 +21,7 @@ trait bool_like { } fn andand(x1: T, x2: T) -> T { - bool_like::select(x1, x2, x1) + bool_like::select(copy x1, x2, x1) } impl bool_like for bool { From e7b0b71197bb246c3213914919bdb959f39a8f74 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Jun 2013 20:15:52 -0400 Subject: [PATCH 35/96] Remove moves from *T and implement in another way --- src/libextra/c_vec.rs | 2 +- src/libstd/pipes.rs | 13 ++++++------- src/libstd/task/spawn.rs | 17 +++-------------- src/test/run-pass/pipe-bank-proto.rs | 10 ++-------- 4 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index 7cc7b659ed9d..fd48e7d5958d 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: @fn()) */ pub fn get(t: CVec, ofs: uint) -> T { assert!(ofs < len(t)); - return unsafe { *ptr::mut_offset(t.base, ofs) }; + return unsafe { copy *ptr::mut_offset(t.base, ofs) }; } /** diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index 012ad0ed80d2..3448401e0b18 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -85,7 +85,8 @@ bounded and unbounded protocols allows for less code duplication. #[allow(missing_doc)]; use container::Container; -use cast::{forget, transmute, transmute_copy}; +use cast::{forget, transmute, transmute_copy, transmute_mut}; +use cast; use either::{Either, Left, Right}; use iterator::IteratorUtil; use kinds::Owned; @@ -102,10 +103,6 @@ use util::replace; static SPIN_COUNT: uint = 0; -macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) -) - #[deriving(Eq)] enum State { Empty, @@ -316,9 +313,11 @@ impl Drop for BufferResource { fn finalize(&self) { unsafe { // FIXME(#4330) Need self by value to get mutability. - let this: &mut BufferResource = transmute(self); + let this: &mut BufferResource = transmute_mut(self); + + let null_buffer: ~Buffer = transmute(ptr::null::>()); + let mut b = replace(&mut this.buffer, null_buffer); - let mut b = move_it!(this.buffer); //let p = ptr::to_unsafe_ptr(*b); //error!("drop %?", p); let old_count = intrinsics::atomic_xsub_rel( diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 30ad4ee2a894..fa1790d79cb7 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -98,10 +98,6 @@ use iterator::{IteratorUtil}; #[cfg(test)] use comm; #[cfg(test)] use task; -macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) -) - type TaskSet = HashSet<*rust_task>; fn new_taskset() -> TaskSet { @@ -638,23 +634,16 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { notify_chan: Option>, f: ~fn()) -> ~fn() { - let child_data = Cell::new((child_arc, ancestors)); + let child_data = Cell::new((notify_chan, child_arc, ancestors)); let result: ~fn() = || { // Agh. Get move-mode items into the closure. FIXME (#2829) - let mut (child_arc, ancestors) = child_data.take(); + let mut (notify_chan, child_arc, ancestors) = child_data.take(); // Child task runs this code. // Even if the below code fails to kick the child off, we must // send Something on the notify channel. - //let mut notifier = None;//notify_chan.map(|c| AutoNotify(c)); - let notifier = match notify_chan { - Some(ref notify_chan_value) => { - let moved_ncv = move_it!(*notify_chan_value); - Some(AutoNotify(moved_ncv)) - } - _ => None - }; + let notifier = notify_chan.map_consume(|c| AutoNotify(c)); if enlist_many(child, &child_arc, &mut ancestors) { let group = @@mut TCB(child, diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index d723fa322094..7ac38966faa3 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -45,24 +45,18 @@ proto! bank ( } ) -macro_rules! move_it ( - { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } } -) - fn switch(endp: pipes::RecvPacket, f: &fn(v: Option) -> U) -> U { f(pipes::try_recv(endp)) } -fn move_it(x: T) -> T { x } - macro_rules! follow ( { $($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+ } => ( |m| match m { $(Some($message($($($x,)+)* next)) => { - let $next = move_it!(next); + let $next = next; $e })+ _ => { fail!() } } @@ -96,7 +90,7 @@ fn bank_client(bank: bank::client::login) { let bank = client::login(bank, ~"theincredibleholk", ~"1234"); let bank = match try_recv(bank) { Some(ok(connected)) => { - move_it!(connected) + connected } Some(invalid(_)) => { fail!("login unsuccessful") } None => { fail!("bank closed the connection") } From a9012a2ad183ad96238ccf2473b731be85eb12e1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 13 Jun 2013 17:42:01 -0400 Subject: [PATCH 36/96] Make type parameters not implicitly copyable, even if they have the Copy bound. Consider: T:Copy could be bound to ~T, which is not implicitly copyable. --- src/librustc/middle/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e161f35af09d..77bf790131c4 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2273,7 +2273,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { for type_param_def.bounds.builtin_bounds.each |bound| { debug!("tc = %s, bound = %?", tc.to_str(), bound); tc = tc - match bound { - BoundCopy => TypeContents::nonimplicitly_copyable(cx), + BoundCopy => TypeContents::noncopyable(cx), BoundStatic => TypeContents::nonstatic(cx), BoundOwned => TypeContents::nonowned(cx), BoundConst => TypeContents::nonconst(cx), From e014ab9023017ec1c1533a1fbe27288e0b53152f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Jun 2013 20:17:59 -0400 Subject: [PATCH 37/96] Make it illegal to move from *T. This interacts poorly with moves-based-on-type, since it creates moves that were not apparent. It also turns out to be not widely used. --- src/librustc/middle/borrowck/gather_loans/gather_moves.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index ef911c9a808e..5431a0a29980 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -105,7 +105,8 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt, mc::cat_implicit_self(*) | mc::cat_copied_upvar(*) | mc::cat_deref(_, _, mc::region_ptr(*)) | - mc::cat_deref(_, _, mc::gc_ptr(*)) => { + mc::cat_deref(_, _, mc::gc_ptr(*)) | + mc::cat_deref(_, _, mc::unsafe_ptr(*)) => { bccx.span_err( cmt0.span, fmt!("cannot move out of %s", @@ -129,8 +130,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt, mc::cat_rvalue(*) | mc::cat_local(*) | mc::cat_arg(*) | - mc::cat_self(*) | - mc::cat_deref(_, _, mc::unsafe_ptr(*)) => { + mc::cat_self(*) => { true } From 5fdb0cbb8ce98bdddc947fc1eeabd2efd509aadc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Jun 2013 21:36:55 -0400 Subject: [PATCH 38/96] Correct tutorial tests --- doc/tutorial.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index c0b939ddac50..f69f569faee4 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1941,12 +1941,14 @@ fn head_bad(v: &[T]) -> T { ~~~~ However, we can tell the compiler that the `head` function is only for -copyable types: that is, those that have the `Copy` trait. +copyable types: that is, those that have the `Copy` trait. In that +case, we can explicitly create a second copy of the value we are +returning using the `copy` keyword: ~~~~ // This does fn head(v: &[T]) -> T { - v[0] + copy v[0] } ~~~~ @@ -2137,7 +2139,7 @@ as in this version of `print_all` that copies elements. fn print_all(printable_things: ~[T]) { let mut i = 0; while i < printable_things.len() { - let copy_of_thing = printable_things[i]; + let copy_of_thing = copy printable_things[i]; copy_of_thing.print(); i += 1; } From bada191309d43d481d265bb1ff9c3a14e827babf Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 16 Jun 2013 12:48:08 -0400 Subject: [PATCH 39/96] Correct docs --- doc/rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rust.md b/doc/rust.md index 3c0828def154..9edbc44d6c21 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2826,7 +2826,7 @@ Within the body of an item that has type parameter declarations, the names of it ~~~~~~~ fn map(f: &fn(A) -> B, xs: &[A]) -> ~[B] { if xs.len() == 0 { return ~[]; } - let first: B = f(xs[0]); + let first: B = f(copy xs[0]); let rest: ~[B] = map(f, xs.slice(1, xs.len())); return ~[first] + rest; } From 6a6ffb4c76427a5c3ff4870aa8fb5ad3aeb7d70d Mon Sep 17 00:00:00 2001 From: SiegeLord Date: Fri, 14 Jun 2013 18:37:29 -0400 Subject: [PATCH 40/96] Do not strip leading whitespace when parsing doc comments. This change prevents the indentation in code blocks inside the /// doc comments from being eaten. The indentation that is the same across the consecutive doc comments is removed by the uindent_pass in librustdoc. --- src/librustdoc/attr_parser.rs | 4 +- src/libsyntax/parse/comments.rs | 88 ++++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index a86a7f38a8cd..1abdae113c59 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -152,6 +152,6 @@ mod test { fn should_concatenate_multiple_doc_comments() { let source = @"/// foo\n/// bar"; let desc = parse_desc(parse_attributes(source)); - assert!(desc == Some(~"foo\nbar")); + assert!(desc == Some(~" foo\n bar")); } } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 40352f890f4f..472f807cd8b6 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -69,39 +69,48 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { return lines.slice(i, j).to_owned(); } - // drop leftmost columns that contain only values in chars - fn block_trim(lines: ~[~str], chars: ~str, max: Option) -> ~[~str] { - - let mut i = max.get_or_default(uint::max_value); - for lines.each |line| { - if line.trim().is_empty() { - loop; - } + /// remove a "[ \t]*\*" block from each line, if possible + fn horizontal_trim(lines: ~[~str]) -> ~[~str] { + let mut i = uint::max_value; + let mut can_trim = true; + let mut first = true; + for lines.iter().advance |line| { for line.iter().enumerate().advance |(j, c)| { - if j >= i { + if j > i || !"* \t".contains_char(c) { + can_trim = false; break; } - if !chars.contains_char(c) { - i = j; + if c == '*' { + if first { + i = j; + first = false; + } else if i != j { + can_trim = false; + } break; } } + if i > line.len() { + can_trim = false; + } + if !can_trim { + break; + } } - return do lines.map |line| { - let chars = line.iter().collect::<~[char]>(); - if i > chars.len() { - ~"" - } else { - str::from_chars(chars.slice(i, chars.len())) + if can_trim { + do lines.map |line| { + line.slice(i + 1, line.len()).to_owned() } - }; + } else { + lines + } } if comment.starts_with("//") { // FIXME #5475: - // return comment.slice(3u, comment.len()).trim().to_owned(); - let r = comment.slice(3u, comment.len()); return r.trim().to_owned(); + // return comment.slice(3u, comment.len()).to_owned(); + let r = comment.slice(3u, comment.len()); return r.to_owned(); } if comment.starts_with("/*") { @@ -109,10 +118,10 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { .any_line_iter() .transform(|s| s.to_owned()) .collect::<~[~str]>(); + let lines = vertical_trim(lines); - let lines = block_trim(lines, ~"\t ", None); - let lines = block_trim(lines, ~"*", Some(1u)); - let lines = block_trim(lines, ~"\t ", None); + let lines = horizontal_trim(lines); + return lines.connect("\n"); } @@ -370,3 +379,36 @@ pub fn gather_comments_and_literals(span_diagnostic: (comments, literals) } + +#[cfg(test)] +mod test { + use super::*; + + #[test] fn test_block_doc_comment_1() { + let comment = "/**\n * Test \n ** Test\n * Test\n*/"; + let correct_stripped = " Test \n* Test\n Test"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped.slice(0, stripped.len()), correct_stripped); + } + + #[test] fn test_block_doc_comment_2() { + let comment = "/**\n * Test\n * Test\n*/"; + let correct_stripped = " Test\n Test"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped.slice(0, stripped.len()), correct_stripped); + } + + #[test] fn test_block_doc_comment_3() { + let comment = "/**\n let a: *int;\n *a = 5;\n*/"; + let correct_stripped = " let a: *int;\n *a = 5;"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped.slice(0, stripped.len()), correct_stripped); + } + + #[test] fn test_line_doc_comment() { + let comment = "/// Test"; + let correct_stripped = " Test"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped.slice(0, stripped.len()), correct_stripped); + } +} From a6bc5dd6efd9b43640c5067c51563262c9ea7986 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 15 Jun 2013 16:57:37 -0700 Subject: [PATCH 41/96] More 0.7 release notes --- RELEASES.txt | 70 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/RELEASES.txt b/RELEASES.txt index 5bf160d62487..d099b1336dfd 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -4,36 +4,90 @@ Version 0.7 (July 2013) * ??? changes, numerous bugfixes * Syntax changes - * `#[deriving(Encodable)]`, `#[deriving(Decodable)]` + * `use mod` is no longer valid. + * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style + argument list. + * `Encodable`, `Decodable`, `TotalOrd`, `TotalEq`, `DeepClone` can all + be automatically derived with `#[deriving(...)]`. + * The `Durable` trait is replaced with the `'static` bounds. + * At long last, 'argument modes' no longer exist. + * The `bytes!` macro returns a vector of bytes for string, u8, char, + and unsuffixed integer literals. * Semantic changes + * The borrow checker has been rewritten with flow-sensitivity, fixing + many bugs and inconveniences. * The `self` parameter no longer implicitly means `&'self self`, and can be explicitly marked with a lifetime. * Structs with the `#[packed]` attribute have byte alignment and no padding between fields. + * The `for` loop protocol now requires `for`-iterators to return `bool` + so they compose better. + * `Option<~T>` is now represented as a nullable pointer. + * `@mut` does dynamic borrow checks correctly. + * Macros TODO + * The `main` function is only detected at the topmost level of the crate. + The `#[main]` attribute is still valid anywhere. + * Struct fields may no longer be mutable. Use inherited mutability. + * The `#[non_owned]` attribute makes a type that would otherwise be + `Owned`, not. TODO this may change to non_send before 0.7 + * The `#[mutable]` attribute makes a type that would otherwise be + `Const`, note. TODO this may change to non_freeze before 0.7 + * Unbounded recursion will abort the process after reaching the limit + specified by the `RUST_MAX_STACK` environment variable. + * The `vecs_implicitly_copyable` lint mode has been removed. Vectors + are never implicitly copyable. * Libraries - - **Note: in 0.7 `core` was renamed `std` and `std` to `extra. - These notes use the new crate names.** - * The `core` crate was renamed to `std`. * The `std` crate was renamed to `extra`. * `std::mut` removed. + * std: The prelude no longer reexports any modules, only types and traits. + * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, + `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. * std: `iterator` module for external iterator objects. + * std: new numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, + `Algebraic`, `Trigonometric`, `Exponential`, `Primitive`. + * std: Tuple traits and accessors defined for up to 12-tuples, e.g. + `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`. * std: many types implement `Clone` - tuples, @, @mut. TODO * std: `path` type renamed to `Path`. * std: Many standalone functions removed in favor of methods in - `vec`, `str`, TODO. In the future methods will also work as functions. + `vec`, `str`. In the future methods will also work as functions. + * std: `reinterpret_cast` removed. Used `transmute`. + * std: ascii string handling in `std::ascii`. + * std: `Rand` is implemented for ~/@. + * std: `run` module for spawning processes overhauled. + * std: Various atomic types added to `unstable::atomic`. + * std: `LinearMap` and `LinearSet` renamed to `HashMap` and `HashSet`. + * std: Added `os::mkdir_recursive`. + * std: Added `os::glob` function performs filesystems globs. + * std: `FuzzyEq` renamed to `ApproxEq`. + * std: `Map` now defines `pop` and `swap` methods. + * extra: `flate` module moved from `std` to `extra`. * extra: `FileInput` implements `std::io::Reader`. * extra: `Complex` number type and `complex` module. * extra: `Rational` number type and `rational` module. * extra: `BigInt`, `BigUint` implement numeric and comparison traits. + * extra: `term` uses terminfo now, is more correct. + + * Tooling + * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks. + * `unused_mut` lint mode for identifying unused `mut` qualifiers. + * The `rusti` command has been rewritten and a number of bugs addressed. + * rustc outputs in color on more terminals. + * rustc accepts a `--link-args` flag to pass arguments to the linker. + * rustc accepts a `-Z print-link-args` flag for debugging linkage. + * Compiling with `-g` will make the binary record information about + dynamic borrowcheck failures for debugging. + * rustdoc has a nicer stylesheet. + * Various improvements to rustdoc. * Other - * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks. * More and improved library documentation. - * The `rusti` command has been rewritten and a number of bugs addressed. + * Various improvements on ARM and Android. + * Various improvements to MIPS backend. + * jemalloc is the Rust allocator. Version 0.6 (April 2013) ------------------------ From 93156ab7e1e04f2805e6a43c1ea60b8ca168dfe5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 16 Jun 2013 19:24:51 -0700 Subject: [PATCH 42/96] std::rt: Reduce the delay on a timer test. Slow --- src/libstd/rt/uv/timer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index 5557a5809875..cd6fc5c0a250 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -143,7 +143,7 @@ mod test { let count_ptr: *mut int = &mut count; let mut loop_ = Loop::new(); let mut timer = TimerWatcher::new(&mut loop_); - do timer.start(10, 20) |timer, status| { + do timer.start(1, 2) |timer, status| { assert!(status.is_none()); unsafe { *count_ptr += 1; @@ -166,7 +166,7 @@ mod test { // Restart the original timer let mut timer = timer; - do timer.start(10, 0) |timer, _| { + do timer.start(1, 0) |timer, _| { unsafe { *count_ptr += 1; } timer.close(||()); } From 819d07af7f73af36a2bef102b92e5a8701122312 Mon Sep 17 00:00:00 2001 From: Ralph Bodenner Date: Sun, 16 Jun 2013 23:21:49 -0700 Subject: [PATCH 43/96] Update doc references to new names for std, extra, and std::libc --- src/README.txt | 4 ++-- src/libextra/std.rc | 12 ++++++------ src/libstd/core.rc | 4 ++-- src/libstd/libc.rs | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/README.txt b/src/README.txt index 1b06c4259fc6..f229068731f4 100644 --- a/src/README.txt +++ b/src/README.txt @@ -4,8 +4,8 @@ Source layout: librustc/ The self-hosted compiler -libcore/ The core library (imported and linked by default) -libstd/ The standard library (slightly more peripheral code) +libstd/ The standard library (imported and linked by default) +libextra/ The "extras" library (slightly more peripheral code) libsyntax/ The Rust parser and pretty-printer rt/ The runtime system diff --git a/src/libextra/std.rc b/src/libextra/std.rc index 93759bea35f7..f5c98f9a11d4 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -10,19 +10,19 @@ /*! -The Rust standard library. +The Rust "extras" library. -The Rust standand library provides a number of useful features that are -not required in or otherwise suitable for the core library. +The Rust extras library (`extra`) provides a number of useful features that +are not required in or otherwise suitable for the standard library (`std`). */ #[link(name = "extra", vers = "0.7-pre", uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297", - url = "https://github.com/mozilla/rust/tree/master/src/libstd")]; + url = "https://github.com/mozilla/rust/tree/master/src/libextra")]; -#[comment = "The Rust standard library"]; +#[comment = "The Rust extras library"]; #[license = "MIT/ASL2"]; #[crate_type = "lib"]; @@ -128,7 +128,7 @@ pub mod test; pub mod serialize; // A curious inner-module that's not exported that contains the binding -// 'extra' so that macro-expanded references to std::serialize and such +// 'extra' so that macro-expanded references to extra::serialize and such // can be resolved within libextra. #[doc(hidden)] pub mod std { diff --git a/src/libstd/core.rc b/src/libstd/core.rc index 8e09a9b17fdb..e1f8137a4a9d 100644 --- a/src/libstd/core.rc +++ b/src/libstd/core.rc @@ -38,7 +38,7 @@ with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, etc. Additionally, `std` contains a `prelude` module that reexports many of the -most common std modules, types and traits. The contents of the prelude are +most common `std` modules, types and traits. The contents of the prelude are imported into every *module* by default. Implicitly, all modules behave as if they contained the following prologue: @@ -66,7 +66,7 @@ they contained the following prologue: #[deny(non_camel_case_types)]; #[deny(missing_doc)]; -// Make core testable by not duplicating lang items. See #2912 +// Make std testable by not duplicating lang items. See #2912 #[cfg(test)] extern mod realstd(name = "std"); #[cfg(test)] pub use kinds = realstd::kinds; #[cfg(test)] pub use ops = realstd::ops; diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 26205c930f0c..37562a014fb7 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -14,8 +14,8 @@ * This module contains bindings to the C standard library, * organized into modules by their defining standard. * Additionally, it contains some assorted platform-specific definitions. -* For convenience, most functions and types are reexported from `core::libc`, -* so `pub use core::libc::*` will import the available +* For convenience, most functions and types are reexported from `std::libc`, +* so `pub use std::libc::*` will import the available * C bindings as appropriate for the target platform. The exact * set of functions available are platform specific. * From f1d971ae189180cbcf3fd37a35ae3fb183833168 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 17 Jun 2013 17:05:51 +1000 Subject: [PATCH 44/96] std: add Zero impls for &[] and &str. --- src/libstd/str.rs | 20 ++++++++++++++++++++ src/libstd/vec.rs | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index aa6b1470b264..d8aab1a8dcc5 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -2202,6 +2202,12 @@ impl<'self> Iterator for StrBytesRevIterator<'self> { } } +// This works because every lifetime is a sub-lifetime of 'static +impl<'self> Zero for &'self str { + fn zero() -> &'self str { "" } + fn is_zero(&self) -> bool { self.is_empty() } +} + impl Zero for ~str { fn zero() -> ~str { ~"" } fn is_zero(&self) -> bool { self.len() == 0 } @@ -3317,4 +3323,18 @@ mod tests { t("zzz", "zz", ~["","z"]); t("zzzzz", "zz", ~["","","z"]); } + + #[test] + fn test_str_zero() { + use num::Zero; + fn t() { + let s: S = Zero::zero(); + assert_eq!(s.as_slice(), ""); + assert!(s.is_zero()); + } + + t::<&str>(); + t::<@str>(); + t::<~str>(); + } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1a236a49a322..cdd9d71273ae 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2629,6 +2629,12 @@ impl Clone for ~[A] { } } +// This works because every lifetime is a sub-lifetime of 'static +impl<'self, A> Zero for &'self [A] { + fn zero() -> &'self [A] { &'self [] } + fn is_zero(&self) -> bool { self.is_empty() } +} + impl Zero for ~[A] { fn zero() -> ~[A] { ~[] } fn is_zero(&self) -> bool { self.len() == 0 } @@ -4293,4 +4299,20 @@ mod tests { } assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]); } + + #[test] + fn test_vec_zero() { + use num::Zero; + macro_rules! t ( + ($ty:ty) => { + let v: $ty = Zero::zero(); + assert!(v.is_empty()); + assert!(v.is_zero()); + } + ); + + t!(&[int]); + t!(@[int]); + t!(~[int]); + } } From 5acc8e5a51e97a6ab5f0aaceedefcf8cd10a0c1b Mon Sep 17 00:00:00 2001 From: Ralph Bodenner Date: Mon, 17 Jun 2013 00:07:52 -0700 Subject: [PATCH 45/96] Reproduce text changes from @brson PR 7176 and fix a typo therein --- src/libextra/std.rc | 11 +++++++---- src/libstd/core.rc | 27 ++++++++++++++------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/libextra/std.rc b/src/libextra/std.rc index f5c98f9a11d4..96c53266c6f1 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -10,10 +10,13 @@ /*! -The Rust "extras" library. +Rust extras. -The Rust extras library (`extra`) provides a number of useful features that -are not required in or otherwise suitable for the standard library (`std`). +The `extra` crate is a set of useful modules for a variety of +purposes, including collections, numerics, I/O, serialization, +and concurrency. + +Rust extras are part of the standard Rust distribution. */ @@ -22,7 +25,7 @@ are not required in or otherwise suitable for the standard library (`std`). uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297", url = "https://github.com/mozilla/rust/tree/master/src/libextra")]; -#[comment = "The Rust extras library"]; +#[comment = "Rust extras"]; #[license = "MIT/ASL2"]; #[crate_type = "lib"]; diff --git a/src/libstd/core.rc b/src/libstd/core.rc index e1f8137a4a9d..f37f65c1edcd 100644 --- a/src/libstd/core.rc +++ b/src/libstd/core.rc @@ -12,19 +12,20 @@ # The Rust standard library -The Rust standard library provides runtime features required by the language, -including the task scheduler and memory allocators, as well as library -support for Rust built-in types, platform abstractions, and other commonly -used features. +The Rust standard library is a group of interrelated modules defining +the core language traits, operations on built-in data types, collections, +platform abstractions, the task scheduler, runtime support for language +features and other common functionality. -`std` includes modules corresponding to each of the integer types, each of -the floating point types, the `bool` type, tuples, characters, strings -(`str`), vectors (`vec`), managed boxes (`managed`), owned boxes (`owned`), -and unsafe and borrowed pointers (`ptr`). Additionally, `std` provides -pervasive types (`option` and `result`), task creation and communication -primitives (`task`, `comm`), platform abstractions (`os` and `path`), basic -I/O abstractions (`io`), common traits (`kinds`, `ops`, `cmp`, `num`, -`to_str`), and complete bindings to the C standard library (`libc`). +`std` includes modules corresponding to each of the integer types, +each of the floating point types, the `bool` type, tuples, characters, +strings (`str`), vectors (`vec`), managed boxes (`managed`), owned +boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`). +Additionally, `std` provides pervasive types (`option` and `result`), +task creation and communication primitives (`task`, `comm`), platform +abstractions (`os` and `path`), basic I/O abstractions (`io`), common +traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings +to the C standard library (`libc`). # Standard library injection and the Rust prelude @@ -38,7 +39,7 @@ with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, etc. Additionally, `std` contains a `prelude` module that reexports many of the -most common `std` modules, types and traits. The contents of the prelude are +most common types, traits and functions. The contents of the prelude are imported into every *module* by default. Implicitly, all modules behave as if they contained the following prologue: From c9e7bb7d4a3fa8d33d40eb6ca0e357f4bd7c39ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Sun, 16 Jun 2013 11:04:53 +0200 Subject: [PATCH 46/96] Improved std::ascii - Fixed tests - Added methods - Renamed casting methods to be shorter closes #7150 --- src/libstd/prelude.rs | 2 +- src/libstd/str/ascii.rs | 112 +++++++++++++++++++++++++++++++--------- src/libstd/to_str.rs | 2 +- 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 60165ed5daeb..309df27e151d 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -61,7 +61,7 @@ pub use path::Path; pub use path::PosixPath; pub use path::WindowsPath; pub use ptr::RawPtr; -pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr}; +pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr, ToBytesConsume}; pub use str::{Str, StrVector, StrSlice, OwnedStr, StrUtil, NullTerminatedStr}; pub use from_str::{FromStr}; pub use to_bytes::IterBytes; diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs index 618d5095777a..635510b3a78f 100644 --- a/src/libstd/str/ascii.rs +++ b/src/libstd/str/ascii.rs @@ -17,8 +17,9 @@ use cast; use old_iter::BaseIter; use iterator::IteratorUtil; use vec::{CopyableVector, ImmutableVector, OwnedVector}; +use to_bytes::IterBytes; -/// Datatype to hold one ascii character. It is 8 bit long. +/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero. #[deriving(Clone, Eq)] pub struct Ascii { priv chr: u8 } @@ -72,6 +73,9 @@ pub trait AsciiCast { /// Convert to an ascii type fn to_ascii(&self) -> T; + /// Convert to an ascii type, not doing any range asserts + unsafe fn to_ascii_nocheck(&self) -> T; + /// Check if convertible to ascii fn is_ascii(&self) -> bool; } @@ -80,7 +84,12 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] { #[inline(always)] fn to_ascii(&self) -> &'self[Ascii] { assert!(self.is_ascii()); - unsafe{ cast::transmute(*self) } + unsafe {self.to_ascii_nocheck()} + } + + #[inline(always)] + unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] { + cast::transmute(*self) } #[inline(always)] @@ -96,8 +105,13 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self str { #[inline(always)] fn to_ascii(&self) -> &'self[Ascii] { assert!(self.is_ascii()); - let (p,len): (*u8, uint) = unsafe{ cast::transmute(*self) }; - unsafe{ cast::transmute((p, len - 1))} + unsafe {self.to_ascii_nocheck()} + } + + #[inline(always)] + unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] { + let (p,len): (*u8, uint) = cast::transmute(*self); + cast::transmute((p, len - 1)) } #[inline(always)] @@ -110,6 +124,11 @@ impl AsciiCast for u8 { #[inline(always)] fn to_ascii(&self) -> Ascii { assert!(self.is_ascii()); + unsafe {self.to_ascii_nocheck()} + } + + #[inline(always)] + unsafe fn to_ascii_nocheck(&self) -> Ascii { Ascii{ chr: *self } } @@ -123,6 +142,11 @@ impl AsciiCast for char { #[inline(always)] fn to_ascii(&self) -> Ascii { assert!(self.is_ascii()); + unsafe {self.to_ascii_nocheck()} + } + + #[inline(always)] + unsafe fn to_ascii_nocheck(&self) -> Ascii { Ascii{ chr: *self as u8 } } @@ -135,26 +159,38 @@ impl AsciiCast for char { /// Trait for copyless casting to an ascii vector. pub trait OwnedAsciiCast { /// Take ownership and cast to an ascii vector without trailing zero element. - fn to_ascii_consume(self) -> ~[Ascii]; + fn into_ascii(self) -> ~[Ascii]; + + /// Take ownership and cast to an ascii vector without trailing zero element. + /// Does not perform validation checks. + unsafe fn into_ascii_nocheck(self) -> ~[Ascii]; } impl OwnedAsciiCast for ~[u8] { #[inline(always)] - fn to_ascii_consume(self) -> ~[Ascii] { + fn into_ascii(self) -> ~[Ascii] { assert!(self.is_ascii()); - unsafe {cast::transmute(self)} + unsafe {self.into_ascii_nocheck()} + } + + #[inline(always)] + unsafe fn into_ascii_nocheck(self) -> ~[Ascii] { + cast::transmute(self) } } impl OwnedAsciiCast for ~str { #[inline(always)] - fn to_ascii_consume(self) -> ~[Ascii] { + fn into_ascii(self) -> ~[Ascii] { assert!(self.is_ascii()); - let mut s = self; - unsafe { - str::raw::pop_byte(&mut s); - cast::transmute(s) - } + unsafe {self.into_ascii_nocheck()} + } + + #[inline(always)] + unsafe fn into_ascii_nocheck(self) -> ~[Ascii] { + let mut r: ~[Ascii] = cast::transmute(self); + r.pop(); + r } } @@ -169,6 +205,8 @@ pub trait AsciiStr { /// Convert to vector representing a upper cased ascii string. fn to_upper(&self) -> ~[Ascii]; + /// Compares two Ascii strings ignoring case + fn eq_ignore_case(self, other: &[Ascii]) -> bool; } impl<'self> AsciiStr for &'self [Ascii] { @@ -188,20 +226,45 @@ impl<'self> AsciiStr for &'self [Ascii] { fn to_upper(&self) -> ~[Ascii] { self.map(|a| a.to_upper()) } + + #[inline(always)] + fn eq_ignore_case(self, other: &[Ascii]) -> bool { + do self.iter().zip(other.iter()).all |(&a, &b)| { a.eq_ignore_case(b) } + } } impl ToStrConsume for ~[Ascii] { #[inline(always)] - fn to_str_consume(self) -> ~str { + fn into_str(self) -> ~str { let mut cpy = self; cpy.push(0u8.to_ascii()); unsafe {cast::transmute(cpy)} } } +impl IterBytes for Ascii { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: &fn(buf: &[u8]) -> bool) -> bool { + f([self.to_byte()]) + } +} + +/// Trait to convert to a owned byte array by consuming self +pub trait ToBytesConsume { + /// Converts to a owned byte array by consuming self + fn into_bytes(self) -> ~[u8]; +} + +impl ToBytesConsume for ~[Ascii] { + fn into_bytes(self) -> ~[u8] { + unsafe {cast::transmute(self)} + } +} + #[cfg(test)] mod tests { use super::*; + use to_bytes::ToBytes; macro_rules! v2ascii ( ( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]); @@ -245,6 +308,8 @@ mod tests { assert_eq!("YMCA".to_ascii().to_lower().to_str_ascii(), ~"ymca"); assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().to_str_ascii(), ~"ABCDEFXYZ:.;"); + assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii())); + assert!("".is_ascii()); assert!("a".is_ascii()); assert!(!"\u2009".is_ascii()); @@ -253,21 +318,22 @@ mod tests { #[test] fn test_owned_ascii_vec() { - // FIXME: #4318 Compiler crashes on moving self - //assert_eq!(~"( ;".to_ascii_consume(), v2ascii!(~[40, 32, 59])); - //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume(), v2ascii!(~[40, 32, 59])); - //assert_eq!(~"( ;".to_ascii_consume_with_null(), v2ascii!(~[40, 32, 59, 0])); - //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume_with_null(), - // v2ascii!(~[40, 32, 59, 0])); + assert_eq!((~"( ;").into_ascii(), v2ascii!(~[40, 32, 59])); + assert_eq!((~[40u8, 32u8, 59u8]).into_ascii(), v2ascii!(~[40, 32, 59])); } #[test] fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); } #[test] - fn test_ascii_to_str_consume() { - // FIXME: #4318 Compiler crashes on moving self - //assert_eq!(v2ascii!(~[40, 32, 59]).to_str_consume(), ~"( ;"); + fn test_ascii_into_str() { + assert_eq!(v2ascii!(~[40, 32, 59]).into_str(), ~"( ;"); + } + + #[test] + fn test_ascii_to_bytes() { + assert_eq!(v2ascii!(~[40, 32, 59]).to_bytes(false), ~[40u8, 32u8, 59u8]); + assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), ~[40u8, 32u8, 59u8]); } #[test] #[should_fail] diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index bfda92d46a28..46e50b6f76e0 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -31,7 +31,7 @@ pub trait ToStr { /// Trait for converting a type to a string, consuming it in the process. pub trait ToStrConsume { /// Cosume and convert to a string. - fn to_str_consume(self) -> ~str; + fn into_str(self) -> ~str; } impl ToStr for () { From 868f9a88d6a0a495c10baa35a2fb359b5681375f Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 11:38:29 -0700 Subject: [PATCH 47/96] Use DIBuilder in debuginfo --- src/librustc/lib/llvm.rs | 185 +++- src/librustc/middle/trans/base.rs | 6 +- src/librustc/middle/trans/debuginfo.rs | 1129 +++++++++--------------- src/rustllvm/RustWrapper.cpp | 201 +++++ src/rustllvm/rustllvm.def.in | 17 + src/rustllvm/rustllvm.h | 2 + 6 files changed, 832 insertions(+), 708 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 289bb4f63f59..ece0c1cb1909 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -224,13 +224,51 @@ pub type SectionIteratorRef = *SectionIterator_opaque; pub enum Pass_opaque {} pub type PassRef = *Pass_opaque; +pub mod debuginfo { + use core::prelude::*; + use super::{ValueRef}; + + pub enum DIBuilder_opaque {} + pub type DIBuilderRef = *DIBuilder_opaque; + + pub type DIDescriptor = ValueRef; + pub type DIScope = DIDescriptor; + pub type DILocation = DIDescriptor; + pub type DIFile = DIScope; + pub type DILexicalBlock = DIScope; + pub type DISubprogram = DIScope; + pub type DIType = DIDescriptor; + pub type DIBasicType = DIType; + pub type DIDerivedType = DIType; + pub type DICompositeType = DIDerivedType; + pub type DIVariable = DIDescriptor; + pub type DIArray = DIDescriptor; + pub type DISubrange = DIDescriptor; + + pub enum DIDescriptorFlags { + FlagPrivate = 1 << 0, + FlagProtected = 1 << 1, + FlagFwdDecl = 1 << 2, + FlagAppleBlock = 1 << 3, + FlagBlockByrefStruct = 1 << 4, + FlagVirtual = 1 << 5, + FlagArtificial = 1 << 6, + FlagExplicit = 1 << 7, + FlagPrototyped = 1 << 8, + FlagObjcClassComplete = 1 << 9, + FlagObjectPointer = 1 << 10, + FlagVector = 1 << 11, + FlagStaticMember = 1 << 12 + } +} + pub mod llvm { use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef}; use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef}; use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef}; use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef}; - use super::{ValueRef,PassRef}; - + use super::{ValueRef, PassRef}; + use super::debuginfo::*; use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong}; #[link_args = "-Lrustllvm -lrustllvm"] @@ -1885,6 +1923,149 @@ pub mod llvm { AlignStack: Bool, Dialect: c_uint) -> ValueRef; + + #[fast_ffi] + pub unsafe fn DIBuilder_new(M: ModuleRef) -> DIBuilderRef; + + #[fast_ffi] + pub unsafe fn DIBuilder_delete(Builder: DIBuilderRef); + + #[fast_ffi] + pub unsafe fn DIBuilder_finalize(Builder: DIBuilderRef); + + #[fast_ffi] + pub unsafe fn DIBuilder_createCompileUnit( + Builder: DIBuilderRef, + Lang: c_uint, + File: *c_char, + Dir: *c_char, + Producer: *c_char, + isOptimized: bool, + Flags: *c_char, + RuntimeVer: c_uint, + SplitName: *c_char); + + #[fast_ffi] + pub unsafe fn DIBuilder_createFile( + Builder: DIBuilderRef, + Filename: *c_char, + Directory: *c_char) -> DIFile; + + #[fast_ffi] + pub unsafe fn DIBuilder_createSubroutineType( + Builder: DIBuilderRef, + File: DIFile, + ParameterTypes: DIArray) -> DICompositeType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createFunction( + Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *c_char, + LinkageName: *c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + isLocalToUnit: bool, + isDefinition: bool, + ScopeLine: c_uint, + Flags: c_uint, + isOptimized: bool, + Fn: ValueRef, + TParam: ValueRef, + Decl: ValueRef) -> DISubprogram; + + #[fast_ffi] + pub unsafe fn DIBuilder_createBasicType( + Builder: DIBuilderRef, + Name: *c_char, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + Encoding: c_uint) -> DIBasicType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createPointerType( + Builder: DIBuilderRef, + PointeeTy: DIType, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + Name: *c_char) -> DIDerivedType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createStructType( + Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *c_char, + File: DIFile, + LineNumber: c_uint, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + Flags: c_uint, + DerivedFrom: DIType, + Elements: DIArray, + RunTimeLang: c_uint, + VTableHolder: ValueRef) -> DICompositeType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createMemberType( + Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *c_char, + File: DIFile, + LineNo: c_uint, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + OffsetInBits: c_ulonglong, + Flags: c_uint, + Ty: DIType) -> DIDerivedType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createLexicalBlock( + Builder: DIBuilderRef, + Scope: DIDescriptor, + File: DIFile, + Line: c_uint, + Col: c_uint) -> DILexicalBlock; + + #[fast_ffi] + pub unsafe fn DIBuilder_createLocalVariable( + Builder: DIBuilderRef, + Tag: c_uint, + Scope: DIDescriptor, + Name: *c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + AlwaysPreserve: bool, + Flags: c_uint, + ArgNo: c_uint) -> DIVariable; + + #[fast_ffi] + pub unsafe fn DIBuilder_createVectorType( + Builder: DIBuilderRef, + Size: c_ulonglong, + AlignInBits: c_ulonglong, + Ty: DIType, + Subscripts: DIArray) -> DIType; + + #[fast_ffi] + pub unsafe fn DIBuilder_getOrCreateSubrange( + Builder: DIBuilderRef, + Lo: c_longlong, + Count: c_longlong) -> DISubrange; + + #[fast_ffi] + pub unsafe fn DIBuilder_getOrCreateArray( + Builder: DIBuilderRef, + Ptr: *DIDescriptor, + Count: c_uint) -> DIArray; + + #[fast_ffi] + pub unsafe fn DIBuilder_insertDeclare( + Builder: DIBuilderRef, + Val: ValueRef, + VarInfo: DIVariable, + InsertBefore: *c_void) -> *c_void; } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 53f2729c38e9..580e7fa1900a 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3074,6 +3074,7 @@ pub fn trans_crate(sess: session::Session, // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = link_meta.name.to_owned() + ".rc"; + Some(debuginfo::mk_ctxt(llmod, copy llmod_id)) // FIXME(#6511): get LLVM building with --enable-threads so this // function can be called // if !llvm::LLVMRustStartMultithreading() { @@ -3102,7 +3103,10 @@ pub fn trans_crate(sess: session::Session, fill_crate_map(ccx, ccx.crate_map); glue::emit_tydescs(ccx); write_abi_version(ccx); - + if ccx.sess.opts.debuginfo { + debuginfo::finalize(ccx); + } + // Translate the metadata. write_metadata(ccx, crate); if ccx.sess.trans_stats() { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 87c33ce64f54..a01c2b89bf9d 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -11,9 +11,9 @@ use core::prelude::*; use driver::session; -use lib::llvm::ValueRef; use lib::llvm::llvm; -use middle::trans::context::task_llcx; +use lib::llvm::{ValueRef, ModuleRef, ContextRef}; +use lib::llvm::debuginfo::*; use middle::trans::common::*; use middle::trans::machine; use middle::trans::type_of; @@ -21,21 +21,17 @@ use middle::trans; use middle::ty; use util::ppaux::ty_to_str; -use core::cast; use core::hashmap::HashMap; use core::libc; -use core::option; -use core::ptr; -use core::str; -use core::sys; -use core::vec; +use core::libc::c_uint; +use core::str::as_c_str; use syntax::codemap::span; +use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; -static LLVMDebugVersion: int = (9 << 16); +static LLVMDebugVersion: int = (12 << 16); -static DW_LANG_RUST: int = 0x9000; -static DW_VIRTUALITY_none: int = 0; +static DW_LANG_RUST: int = 12; //0x9000; static CompileUnitTag: int = 17; static FileDescriptorTag: int = 41; @@ -59,302 +55,185 @@ static DW_ATE_signed_char: int = 0x06; static DW_ATE_unsigned: int = 0x07; static DW_ATE_unsigned_char: int = 0x08; -fn llstr(s: &str) -> ValueRef { - do str::as_c_str(s) |sbuf| { - unsafe { - llvm::LLVMMDStringInContext(task_llcx(), - sbuf, - s.len() as libc::c_uint) - } - } -} -fn lltag(lltag: int) -> ValueRef { - lli32(LLVMDebugVersion | lltag) -} -fn lli32(val: int) -> ValueRef { - C_i32(val as i32) -} -fn lli64(val: int) -> ValueRef { - C_i64(val as i64) -} -fn lli1(bval: bool) -> ValueRef { - C_i1(bval) -} -fn llmdnode(elems: &[ValueRef]) -> ValueRef { - unsafe { - llvm::LLVMMDNodeInContext(task_llcx(), - vec::raw::to_ptr(elems), - elems.len() as libc::c_uint) - } -} -fn llunused() -> ValueRef { - lli32(0x0) -} -fn llnull() -> ValueRef { - unsafe { - cast::transmute(ptr::null::()) - } -} - -fn add_named_metadata(cx: &CrateContext, name: ~str, val: ValueRef) { - str::as_c_str(name, |sbuf| { - unsafe { - llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val) - } - }) -} - //////////////// pub struct DebugContext { - llmetadata: metadata_cache, + //llmetadata: metadata_cache, names: namegen, - crate_file: ~str + crate_file: ~str, + builder: DIBuilderRef, + + created_files: @mut HashMap<~str, DIFile>, + created_functions: @mut HashMap, + created_blocks: @mut HashMap, + created_types: @mut HashMap } -pub fn mk_ctxt(crate: ~str) -> DebugContext { +/** Create new DebugContext */ +pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugContext { + debug!("mk_ctxt"); + let builder = unsafe { llvm::DIBuilder_new(llmod) }; DebugContext { - llmetadata: @mut HashMap::new(), - names: new_namegen(), - crate_file: crate - } + //llmetadata: @mut HashMap::new(), + names: new_namegen(intr), + crate_file: crate, + builder: builder, + created_files: @mut HashMap::new(), + created_functions: @mut HashMap::new(), + created_blocks: @mut HashMap::new(), + created_types: @mut HashMap::new(), +} } -fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { - let mut existing = match cache.pop(&mdtag) { - Some(arr) => arr, None => ~[] +#[inline(always)] +fn get_builder(cx: @CrateContext) -> DIBuilderRef { + let dbg_cx = cx.dbg_cx.get_ref(); + return dbg_cx.builder; +} + +fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { + return unsafe { + llvm::DIBuilder_getOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) }; - existing.push(val); - cache.insert(mdtag, existing); } -struct Metadata { - node: ValueRef, - data: T -} - -struct FileMetadata { - path: ~str -} -struct CompileUnitMetadata { - name: ~str -} -struct SubProgramMetadata { - id: ast::node_id -} -struct LocalVarMetadata { - id: ast::node_id -} -struct TyDescMetadata { - hash: uint -} -struct BlockMetadata { - start: codemap::Loc, - end: codemap::Loc -} -struct ArgumentMetadata { - id: ast::node_id -} -struct RetvalMetadata { - id: ast::node_id -} - -type metadata_cache = @mut HashMap; - -enum debug_metadata { - file_metadata(@Metadata), - compile_unit_metadata(@Metadata), - subprogram_metadata(@Metadata), - local_var_metadata(@Metadata), - tydesc_metadata(@Metadata), - block_metadata(@Metadata), - argument_metadata(@Metadata), - retval_metadata(@Metadata), -} - -fn cast_safely(val: T) -> U { +/** Create any deferred debug metadata nodes */ +pub fn finalize(cx: @CrateContext) { + debug!("finalize"); + create_compile_unit(cx); unsafe { - let val2 = val; - return cast::transmute(val2); - } + llvm::DIBuilder_finalize(get_builder(cx)); + llvm::DIBuilder_delete(get_builder(cx)); + }; } -fn md_from_metadata(val: debug_metadata) -> T { - match val { - file_metadata(md) => cast_safely(md), - compile_unit_metadata(md) => cast_safely(md), - subprogram_metadata(md) => cast_safely(md), - local_var_metadata(md) => cast_safely(md), - tydesc_metadata(md) => cast_safely(md), - block_metadata(md) => cast_safely(md), - argument_metadata(md) => cast_safely(md), - retval_metadata(md) => cast_safely(md) - } +fn filename_from_span(cx: @CrateContext, sp: codemap::span) -> ~str { + /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name } -fn cached_metadata(cache: metadata_cache, - mdtag: int, - eq_fn: &fn(md: T) -> bool) - -> Option { - if cache.contains_key(&mdtag) { - let items = cache.get(&mdtag); - for items.each |item| { - let md: T = md_from_metadata::(*item); - if eq_fn(copy md) { - return option::Some(copy md); - } - } - } - return option::None; +//fn filename_from_span<'cx>(cx: &'cx CrateContext, sp: codemap::span) -> &'cx str { +// let fname: &str = cx.sess.codemap.lookup_char_pos(sp.lo).file.name; +// return fname; +//} + +fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { + let full_path = + if str::starts_with(full_path, work_dir) { + str::slice(full_path, str::len(work_dir) + 1u, + str::len(full_path)).to_owned() + } else { + full_path.to_owned() + }; + + return (full_path, work_dir.to_owned()); } -fn create_compile_unit(cx: &mut CrateContext) -> @Metadata { - let cache = get_cache(cx); - let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file; - let tg = CompileUnitTag; - match cached_metadata::<@Metadata>(cache, tg, - |md| md.data.name == crate_name) { - option::Some(md) => return md, - option::None => () - } +fn create_compile_unit(cx: @CrateContext) { + let crate_name: &str = cx.dbg_cx.get_ref().crate_file; let (_, work_dir) = get_file_path_and_dir( cx.sess.working_dir.to_str(), crate_name); - let unit_metadata = ~[lltag(tg), - llunused(), - lli32(DW_LANG_RUST), - llstr(crate_name), - llstr(work_dir), - llstr(env!("CFG_VERSION")), - lli1(true), // deprecated: main compile unit - lli1(cx.sess.opts.optimize != session::No), - llstr(""), // flags (???) - lli32(0) // runtime version (???) - ]; - let unit_node = llmdnode(unit_metadata); - add_named_metadata(cx, ~"llvm.dbg.cu", unit_node); - let mdval = @Metadata { - node: unit_node, - data: CompileUnitMetadata { - name: crate_name - } - }; - update_cache(cache, tg, compile_unit_metadata(mdval)); + + let producer = fmt!("rustc version %s", env!("CFG_VERSION")); - return mdval; + do as_c_str(crate_name) |crate_name| { + do as_c_str(work_dir) |work_dir| { + do as_c_str(producer) |producer| { + do as_c_str("") |flags| { + do as_c_str("") |split_name| { unsafe { + llvm::DIBuilder_createCompileUnit(get_builder(cx), + DW_LANG_RUST as c_uint, crate_name, work_dir, producer, + cx.sess.opts.optimize != session::No, + flags, 0, split_name); + }}}}}}; } -fn get_cache(cx: &CrateContext) -> metadata_cache { - cx.dbg_cx.get_ref().llmetadata -} +fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { + let mut dbg_cx = cx.dbg_cx.get_ref(); -fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { - (if full_path.starts_with(work_dir) { - full_path.slice(work_dir.len() + 1u, - full_path.len()).to_owned() - } else { - full_path.to_owned() - }, work_dir.to_owned()) -} - -fn create_file(cx: &mut CrateContext, full_path: ~str) - -> @Metadata { - let cache = get_cache(cx);; - let tg = FileDescriptorTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| md.data.path == full_path) { - option::Some(md) => return md, - option::None => () + match dbg_cx.created_files.find(&full_path.to_owned()) { + Some(file_md) => return *file_md, + None => () } + debug!("create_file: %s", full_path); + let (file_path, work_dir) = get_file_path_and_dir(cx.sess.working_dir.to_str(), full_path); - let unit_node = create_compile_unit(cx).node; - let file_md = ~[lltag(tg), - llstr(file_path), - llstr(work_dir), - unit_node]; - let val = llmdnode(file_md); - let mdval = @Metadata { - node: val, - data: FileMetadata { - path: full_path - } - }; - update_cache(cache, tg, file_metadata(mdval)); - return mdval; + + let file_md = + do as_c_str(file_path) |file_path| { + do as_c_str(work_dir) |work_dir| { unsafe { + llvm::DIBuilder_createFile(get_builder(cx), file_path, work_dir) + }}}; + + dbg_cx.created_files.insert(full_path.to_owned(), file_md); + return file_md; } fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { cm.lookup_char_pos(sp.lo).line } -fn create_block(mut cx: block) -> @Metadata { - let cache = get_cache(cx.ccx()); - while cx.node_info.is_none() { - match cx.parent { - Some(b) => cx = b, +fn create_block(bcx: block) -> DILexicalBlock { + let mut bcx = bcx; + let mut dbg_cx = bcx.ccx().dbg_cx.get_ref(); + + while bcx.node_info.is_none() { + match bcx.parent { + Some(b) => bcx = b, None => fail!() } } - let sp = cx.node_info.get().span; + let sp = bcx.node_info.get().span; + let id = bcx.node_info.get().id; - let start = cx.sess().codemap.lookup_char_pos(sp.lo); - let fname = /*bad*/copy start.file.name; - let end = cx.sess().codemap.lookup_char_pos(sp.hi); - let tg = LexicalBlockTag; - /*match cached_metadata::<@Metadata>( - cache, tg, - {|md| start == md.data.start && end == md.data.end}) { - option::Some(md) { return md; } - option::None {} - }*/ - - let parent = match cx.parent { - None => create_function(cx.fcx).node, - Some(bcx) => create_block(bcx).node - }; - let file_node = create_file(cx.ccx(), /* bad */ fname.to_owned()); - let unique_id = match cache.find(&LexicalBlockTag) { - option::Some(v) => v.len() as int, - option::None => 0 - }; - let lldata = ~[lltag(tg), - parent, - lli32(start.line.to_int()), - lli32(start.col.to_int()), - file_node.node, - lli32(unique_id) - ]; - let val = llmdnode(lldata); - let mdval = @Metadata { - node: val, - data: BlockMetadata { - start: start, - end: end - } - }; - //update_cache(cache, tg, block_metadata(mdval)); - return mdval; -} - -fn size_and_align_of(cx: &mut CrateContext, t: ty::t) -> (int, int) { - let llty = type_of::type_of(cx, t); - (machine::llsize_of_real(cx, llty) as int, - machine::llalign_of_pref(cx, llty) as int) -} - -fn create_basic_type(cx: &mut CrateContext, t: ty::t, span: span) - -> @Metadata { - let cache = get_cache(cx); - let tg = BasicTypeDescriptorTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| ty::type_id(t) == md.data.hash) { - option::Some(md) => return md, - option::None => () + match dbg_cx.created_blocks.find(&id) { + Some(block) => return *block, + None => () } + debug!("create_block: %s", bcx.sess().codemap.span_to_str(sp)); + + let start = bcx.sess().codemap.lookup_char_pos(sp.lo); + let end = bcx.sess().codemap.lookup_char_pos(sp.hi); + + let parent = match bcx.parent { + None => create_function(bcx.fcx), + Some(b) => create_block(b) + }; + + let file_md = create_file(bcx.ccx(), start.file.name); + + let block_md = unsafe { + llvm::LLVMDIBuilderCreateLexicalBlock( + dcx.builder, + parent, file_md, + start.line.to_int() as c_uint, start.col.to_int() as c_uint) + }; + + dbg_cx.created_blocks.insert(id, block_md); + + return block_md; +} + +fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { + let llty = type_of::type_of(cx, t); + (machine::llsize_of_real(cx, llty), + machine::llalign_of_pref(cx, llty)) +} + +fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ + let mut dbg_cx = cx.dbg_cx.get_ref(); + let ty_id = ty::type_id(t); + match dbg_cx.created_types.find(&ty_id) { + Some(ty_md) => return *ty_md, + None => () + } + + debug!("create_basic_type: %?", ty::get(t)); + let (name, encoding) = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned), ty::ty_bool => (~"bool", DW_ATE_boolean), @@ -378,383 +257,255 @@ fn create_basic_type(cx: &mut CrateContext, t: ty::t, span: span) ast::ty_f32 => (~"f32", DW_ATE_float), ast::ty_f64 => (~"f64", DW_ATE_float) }, - _ => cx.sess.bug("debuginfo::create_basic_type - t is invalid type") + _ => cx.sess.bug(~"debuginfo::create_basic_type - t is invalid type") }; - let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - let cu_node = create_compile_unit(cx); let (size, align) = size_and_align_of(cx, t); - let lldata = ~[lltag(tg), - cu_node.node, - llstr(name), - file_node.node, - lli32(0), //XXX source line - lli64(size * 8), // size in bits - lli64(align * 8), // alignment in bits - lli64(0), //XXX offset? - lli32(0), //XXX flags? - lli32(encoding)]; - let llnode = llmdnode(lldata); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - update_cache(cache, tg, tydesc_metadata(mdval)); - add_named_metadata(cx, ~"llvm.dbg.ty", llnode); - return mdval; + let ty_md = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateBasicType( + dcx.builder, name, + size * 8 as u64, align * 8 as u64, encoding as c_uint) + }}; + + dbg_cx.created_types.insert(ty_id, ty_md); + return ty_md; } -fn create_pointer_type(cx: &mut CrateContext, t: ty::t, span: span, - pointee: @Metadata) - -> @Metadata { - let tg = PointerTypeTag; - /*let cache = cx.llmetadata; - match cached_metadata::<@Metadata>( - cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { - option::Some(md) { return md; } - option::None {} - }*/ +fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); - let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - //let cu_node = create_compile_unit(cx, fname); let name = ty_to_str(cx.tcx, t); - let llnode = create_derived_type(tg, file_node.node, name, 0, size * 8, - align * 8, 0, pointee.node); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - //update_cache(cache, tg, tydesc_metadata(mdval)); - add_named_metadata(cx, ~"llvm.dbg.ty", llnode); - return mdval; + let ptr_md = do as_c_str(name) |name| { unsafe { + llvm::DIBuilder_createPointerType(get_builder(cx), + pointee, size * 8 as u64, align * 8 as u64, name) + }}; + return ptr_md; } -struct StructCtxt { - file: ValueRef, - name: @str, - line: int, - members: ~[ValueRef], - total_size: int, - align: int +struct StructContext { + cx: @CrateContext, + file: DIFile, + name: ~str, + line: uint, + members: ~[DIDerivedType], + total_size: uint, + align: uint } -fn finish_structure(cx: @mut StructCtxt) -> ValueRef { - return create_composite_type(StructureTypeTag, - cx.name, - cx.file, - cx.line, - cx.total_size, - cx.align, - 0, - None, - Some(/*bad*/copy cx.members)); +impl StructContext { + fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + let scx = ~StructContext { + cx: cx, + file: file, + name: name, + line: line, + members: ~[], + total_size: 0, + align: 64 //XXX different alignment per arch? + }; + return scx; + } + + fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { + let mem_t = do as_c_str(name) |name| { unsafe { + llvm::DIBuilder_createMemberType(get_builder(self.cx), + ptr::null(), name, self.file, line as c_uint, + size * 8 as u64, align * 8 as u64, self.total_size as u64, + 0, ty) + }}; + // XXX What about member alignment??? + self.members.push(mem_t); + self.total_size += size * 8; + } + + fn finalize(&self) -> DICompositeType { + let members_md = create_DIArray(get_builder(self.cx), self.members); + + let struct_md = + do as_c_str(self.name) |name| { unsafe { + llvm::LLVMDIBuilderCreateStructType( + dcx.builder, ptr::null(), name, + self.file, self.line as c_uint, + self.total_size as u64, self.align as u64, 0, ptr::null(), + members_md, 0, ptr::null()) + }}; + return struct_md; + } } -fn create_structure(file: @Metadata, name: @str, line: int) - -> @mut StructCtxt { - let cx = @mut StructCtxt { - file: file.node, - name: name, - line: line, - members: ~[], - total_size: 0, - align: 64 //XXX different alignment per arch? - }; - return cx; -} - -fn create_derived_type(type_tag: int, file: ValueRef, name: &str, line: int, - size: int, align: int, offset: int, ty: ValueRef) - -> ValueRef { - let lldata = ~[lltag(type_tag), - file, - llstr(name), - file, - lli32(line), - lli64(size), - lli64(align), - lli64(offset), - lli32(0), - ty]; - return llmdnode(lldata); -} - -fn add_member(cx: @mut StructCtxt, - name: &str, - line: int, - size: int, - align: int, - ty: ValueRef) { - cx.members.push(create_derived_type(MemberTag, cx.file, name, line, - size * 8, align * 8, cx.total_size, - ty)); - cx.total_size += size * 8; -} - -fn create_struct(cx: &mut CrateContext, t: ty::t, fields: ~[ty::field], - span: span) -> @Metadata { +fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - let scx = create_structure(file_node, (ty_to_str(cx.tcx, t)).to_managed(), - line_from_span(cx.sess.codemap, span) as int); + let file_md = create_file(cx, fname); + let line = line_from_span(cx.sess.codemap, span); + + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), line); for fields.each |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); - add_member(scx, cx.sess.str_of(field.ident), - line_from_span(cx.sess.codemap, span) as int, - size as int, align as int, ty_md.node); + scx.add_member(cx.sess.str_of(field.ident), + line_from_span(cx.sess.codemap, span), + size, align, ty_md); } - let mdval = @Metadata { - node: finish_structure(scx), - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - return mdval; -} - -fn create_tuple(cx: &mut CrateContext, t: ty::t, elements: &[ty::t], span: span) - -> @Metadata { - let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - let scx = create_structure(file_node, - cx.sess.str_of( - ((/*bad*/copy cx.dbg_cx).get().names) - ("tuple")), - line_from_span(cx.sess.codemap, span) as int); - for elements.each |element| { - let ty_md = create_ty(cx, *element, span); - let (size, align) = size_and_align_of(cx, *element); - add_member(scx, "", line_from_span(cx.sess.codemap, span) as int, - size as int, align as int, ty_md.node); - } - let mdval = @Metadata { - node: finish_structure(scx), - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - return mdval; + return scx.finalize(); } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr() -> (ValueRef, int, int) { - let null = ptr::null(); - let size = sys::size_of::() as int; - let align = sys::min_align_of::() as int; - let vp = create_derived_type(PointerTypeTag, null, "", 0, +fn voidptr() -> (DIDerivedType, uint, uint) { + let size = sys::size_of::(); + let align = sys::min_align_of::(); + let vp = ptr::null(); + /* + let vp = create_derived_type(PointerTypeTag, null, ~"", 0, size, align, 0, null); + */ return (vp, size, align); } -fn create_boxed_type(cx: &mut CrateContext, contents: ty::t, - span: span, boxed: @Metadata) - -> @Metadata { - //let tg = StructureTypeTag; - /*let cache = cx.llmetadata; - match cached_metadata::<@Metadata>( - cache, tg, {|md| ty::hash_ty(contents) == ty::hash_ty(md.data.hash)}) { - option::Some(md) { return md; } - option::None {} - }*/ +fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - //let cu_node = create_compile_unit_metadata(cx, fname); + let file_md = create_file(cx, fname); + + let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); + let mut scx = StructContext::create(cx, file_md, name, loc.line); + + for elements.each |element| { + let ty_md = create_ty(cx, *element, span); + let (size, align) = size_and_align_of(cx, *element); + scx.add_member("", line_from_span(cx.sess.codemap, span), + size, align, ty_md); + } + return scx.finalize(); +} + +fn create_boxed_type(cx: @CrateContext, contents: ty::t, + span: span, boxed: DIType) -> DICompositeType { + let fname = filename_from_span(cx, span); + let file_md = create_file(cx, fname); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - let scx = create_structure(file_node, (fmt!("box<%s>", name)).to_managed(), 0); - add_member(scx, "refcnt", 0, sys::size_of::() as int, - sys::min_align_of::() as int, refcount_type.node); + + let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); + scx.add_member("refcnt", 0, sys::size_of::(), + sys::min_align_of::(), refcount_type); // the tydesc and other pointers should be irrelevant to the // debugger, so treat them as void* types let (vp, vpsize, vpalign) = voidptr(); - add_member(scx, "tydesc", 0, vpsize, vpalign, vp); - add_member(scx, "prev", 0, vpsize, vpalign, vp); - add_member(scx, "next", 0, vpsize, vpalign, vp); + scx.add_member("tydesc", 0, vpsize, vpalign, vp); + scx.add_member("prev", 0, vpsize, vpalign, vp); + scx.add_member("next", 0, vpsize, vpalign, vp); let (size, align) = size_and_align_of(cx, contents); - add_member(scx, "boxed", 0, size, align, boxed.node); - let llnode = finish_structure(scx); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(contents) - } - }; - //update_cache(cache, tg, tydesc_metadata(mdval)); - add_named_metadata(cx, ~"llvm.dbg.ty", llnode); - return mdval; + scx.add_member("boxed", 0, size, align, boxed); + return scx.finalize(); } -fn create_composite_type(type_tag: int, name: &str, file: ValueRef, - line: int, size: int, align: int, offset: int, - derived: Option, - members: Option<~[ValueRef]>) - -> ValueRef { - let lldata = ~[lltag(type_tag), - file, - llstr(name), // type name - file, // source file definition - lli32(line), // source line definition - lli64(size), // size of members - lli64(align), // align - lli32/*64*/(offset), // offset - lli32(0), // flags - if derived.is_none() { - llnull() - } else { // derived from - derived.get() - }, - if members.is_none() { - llnull() - } else { //members - llmdnode(members.get()) - }, - lli32(0), // runtime language - llnull() - ]; - return llmdnode(lldata); -} - -fn create_fixed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, - len: int, span: span) -> @Metadata { - let t_md = create_ty(cx, elem_t, span); +fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, + len: uint, span: span) -> DIType { + let elem_ty_md = create_ty(cx, elem_t, span); let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let (size, align) = size_and_align_of(cx, elem_t); - let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(len - 1)]); - let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - let array = create_composite_type(ArrayTypeTag, name, file_node.node, 0, - size * len, align, 0, Some(t_md.node), - Some(~[subrange])); - @Metadata { - node: array, - data: TyDescMetadata { - hash: ty::type_id(vec_t) - } - } + + let subrange = unsafe { + llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, (len-1) as i64) }; + + let subscripts = create_DIArray(get_builder(cx), [subrange]); + return unsafe { + llvm::DIBuilder_createVectorType(get_builder(cx), + size * len as u64, align as u64, elem_ty_md, subscripts) + }; } -fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, - vec_ty_span: codemap::span) - -> @Metadata { +fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, + vec_ty_span: codemap::span) -> DICompositeType { let fname = filename_from_span(cx, vec_ty_span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - let vec_scx = create_structure(file_node, - ty_to_str(cx.tcx, vec_t).to_managed(), 0); + + let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); + let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); - add_member(vec_scx, "fill", 0, sys::size_of::() as int, - sys::min_align_of::() as int, size_t_type.node); - add_member(vec_scx, "alloc", 0, sys::size_of::() as int, - sys::min_align_of::() as int, size_t_type.node); - let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(0)]); + vec_scx.add_member("fill", 0, sys::size_of::(), + sys::min_align_of::(), size_t_type); + vec_scx.add_member("alloc", 0, sys::size_of::(), + sys::min_align_of::(), size_t_type); + let subrange = unsafe { llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, 0_i64) }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - let data_ptr = create_composite_type(ArrayTypeTag, name, file_node.node, 0, - arr_size, arr_align, 0, - Some(elem_ty_md.node), - Some(~[subrange])); - add_member(vec_scx, "data", 0, 0, // clang says the size should be 0 - sys::min_align_of::() as int, data_ptr); - let llnode = finish_structure(vec_scx); - let vec_md = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(vec_t) - } - }; - let box_scx = create_structure(file_node, (fmt!("box<%s>", name)).to_managed(), 0); + let subscripts = create_DIArray(get_builder(cx), [subrange]); + let data_ptr = unsafe { llvm::DIBuilder_createVectorType(get_builder(cx), + arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; + vec_scx.add_member("data", 0, 0, // clang says the size should be 0 + sys::min_align_of::(), data_ptr); + let vec_md = vec_scx.finalize(); + + let mut box_scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, vec_ty_span); - add_member(box_scx, "refcnt", 0, sys::size_of::() as int, - sys::min_align_of::() as int, refcount_type.node); + box_scx.add_member("refcnt", 0, sys::size_of::(), + sys::min_align_of::(), refcount_type); let (vp, vpsize, vpalign) = voidptr(); - add_member(box_scx, "tydesc", 0, vpsize, vpalign, vp); - add_member(box_scx, "prev", 0, vpsize, vpalign, vp); - add_member(box_scx, "next", 0, vpsize, vpalign, vp); - let size = 2 * sys::size_of::() as int; - let align = sys::min_align_of::() as int; - add_member(box_scx, "boxed", 0, size, align, vec_md.node); - let llnode = finish_structure(box_scx); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(elem_t) - } - }; + box_scx.add_member("tydesc", 0, vpsize, vpalign, vp); + box_scx.add_member("prev", 0, vpsize, vpalign, vp); + box_scx.add_member("next", 0, vpsize, vpalign, vp); + let size = 2 * sys::size_of::(); + let align = sys::min_align_of::(); + box_scx.add_member("boxed", 0, size, align, vec_md); + let mdval = box_scx.finalize(); return mdval; } -fn create_vec_slice(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) - -> @Metadata { +fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t).to_managed(), 0); + + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); let (_, ptr_size, ptr_align) = voidptr(); - add_member(scx, "vec", 0, ptr_size, ptr_align, elem_ptr.node); - add_member(scx, "length", 0, sys::size_of::() as int, - sys::min_align_of::() as int, uint_type.node); - let llnode = finish_structure(scx); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(vec_t) - } - }; - return mdval; + scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); + scx.add_member("length", 0, sys::size_of::(), + sys::min_align_of::(), uint_type); + return scx.finalize(); } -fn create_fn_ty(cx: &mut CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, - span: span) -> @Metadata { +fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, + span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let (vp, _, _) = voidptr(); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); - let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span).node }; - let members = ~[output_ptr_md.node, vp] + inputs_vals; - let llnode = create_composite_type(SubroutineTag, "", file_node.node, - 0, 0, 0, 0, None, Some(members)); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(fn_ty) - } + let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) }; + let members = ~[output_ptr_md, vp] + inputs_vals; + + return unsafe { + llvm::DIBuilder_createSubroutineType(get_builder(cx), file_md, + create_DIArray(get_builder(cx), members)) }; - return mdval; } -fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) - -> @Metadata { +fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { + let mut dbg_cx = cx.dbg_cx.get_ref(); + let ty_id = ty::type_id(t); + match dbg_cx.created_types.find(&ty_id) { + Some(ty_md) => return *ty_md, + None => () + } + debug!("create_ty: %?", ty::get(t)); - /*let cache = get_cache(cx); - match cached_metadata::<@Metadata>( - cache, tg, {|md| t == md.data.hash}) { - option::Some(md) { return md; } - option::None {} - }*/ let sty = copy ty::get(t).sty; - match sty { + let ty_md = match sty { ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) => create_basic_type(cx, t, span), ty::ty_estr(ref vstore) => { let i8_t = ty::mk_i8(); match *vstore { ty::vstore_fixed(len) => { - create_fixed_vec(cx, t, i8_t, len as int + 1, span) + create_fixed_vec(cx, t, i8_t, len + 1, span) }, ty::vstore_uniq | ty::vstore_box => { let box_md = create_boxed_vec(cx, t, i8_t, span); @@ -776,7 +527,7 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) ty::ty_evec(ref mt, ref vstore) => { match *vstore { ty::vstore_fixed(len) => { - create_fixed_vec(cx, t, mt.ty, len as int, span) + create_fixed_vec(cx, t, mt.ty, len, span) }, ty::vstore_uniq | ty::vstore_box => { let box_md = create_boxed_vec(cx, t, mt.ty, span); @@ -812,30 +563,17 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) ty::ty_tup(ref elements) => { create_tuple(cx, t, *elements, span) }, - _ => cx.sess.bug("debuginfo: unexpected type in create_ty") - } + _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") + }; + + dbg_cx.created_types.insert(ty_id, ty_md); + return ty_md; } -fn filename_from_span(cx: &CrateContext, sp: codemap::span) -> @str { - cx.sess.codemap.lookup_char_pos(sp.lo).file.name -} - -fn create_var(type_tag: int, context: ValueRef, name: &str, file: ValueRef, - line: int, ret_ty: ValueRef) -> ValueRef { - let lldata = ~[lltag(type_tag), - context, - llstr(name), - file, - lli32(line), - ret_ty, - lli32(0) - ]; - return llmdnode(lldata); -} - -pub fn create_local_var(bcx: block, local: @ast::local) - -> @Metadata { +pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { + debug!("create_local_var"); let cx = bcx.ccx(); + /* let cache = get_cache(cx); let tg = AutoVariableTag; match cached_metadata::<@Metadata>( @@ -843,49 +581,56 @@ pub fn create_local_var(bcx: block, local: @ast::local) option::Some(md) => return md, option::None => () } + */ let name = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) _ => fail!("no single variable name for local") }; - let loc = cx.sess.codemap.lookup_char_pos(local.span.lo); + let name: &str = cx.sess.str_of(ident); + debug!("create_local_var: %s", name); + + let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, /*bad*/ loc.file.name.to_owned()); + let filemd = create_file(cx, /*bad*/copy loc.file.name); let context = match bcx.parent { - None => create_function(bcx.fcx).node, - Some(_) => create_block(bcx).node + None => create_function(bcx.fcx), + Some(_) => create_block(bcx) }; - let mdnode = create_var(tg, context, cx.sess.str_of(name), - filemd.node, loc.line as int, tymd.node); - let mdval = @Metadata { - node: mdnode, - data: LocalVarMetadata { - id: local.node.id - } - }; - update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); - // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc - let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { - Some(v) => v, - None => { - bcx.tcx().sess.span_bug( - local.span, - fmt!("No entry in lllocals table for %?", local.node.id)); + let mdval = do as_c_str(*cx.sess.str_of(name)) |name| { unsafe { + llvm::DIBuilder_createLocalVariable(get_builder(cx), AutoVariableTag as u32, + ptr::null(), name, filemd, loc.line as c_uint, tymd, false, 0, 0) + }}; + + let llptr = match bcx.fcx.lllocals.find(&local.node.id) { + option::Some(&local_mem(v)) => v, + option::Some(_) => { + bcx.tcx().sess.span_bug(local.span, "local is bound to something weird"); } + option::None => { + match bcx.fcx.lllocals.get_copy(&local.node.pat.id) { + local_imm(v) => v, + _ => bcx.tcx().sess.span_bug(local.span, "local is bound to something weird") + } + } }; - let declargs = ~[llmdnode([llptr]), mdnode]; - trans::build::Call(bcx, cx.intrinsics.get_copy(&("llvm.dbg.declare")), + /* + llvm::DIBuilder_insertDeclare(get_builder(cx), llptr, mdval, + + let declargs = ~[llmdnode(~[llptr]), mdnode]; + trans::build::Call(bcx, *cx.intrinsics.get(&~"llvm.dbg.declare"), declargs); + */ return mdval; -} + } -pub fn create_arg(bcx: block, arg: ast::arg, sp: span) - -> Option<@Metadata> { - let fcx = bcx.fcx; - let cx = fcx.ccx; +pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { + debug!("create_arg"); + let fcx = bcx.fcx, cx = *fcx.ccx; + /* let cache = get_cache(cx); let tg = ArgVariableTag; match cached_metadata::<@Metadata>( @@ -893,6 +638,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) option::Some(md) => return Some(md), option::None => () } + */ let loc = cx.sess.codemap.lookup_char_pos(sp.lo); if "" == loc.file.name { @@ -900,35 +646,30 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) } let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, /* bad */ loc.file.name.to_owned()); + let filemd = create_file(cx, /*bad*/copy loc.file.name); let context = create_function(bcx.fcx); match arg.pat.node { ast::pat_ident(_, path, _) => { // XXX: This is wrong; it should work for multiple bindings. - let mdnode = create_var( - tg, - context.node, - cx.sess.str_of(*path.idents.last()), - filemd.node, - loc.line as int, - tymd.node - ); + let ident = path.idents.last(); + let name: &str = cx.sess.str_of(*ident); + let mdnode = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + ArgVariableTag as u32, context, name, + filemd, loc.line as c_uint, tymd, false, 0, 0) + // XXX need to pass a real argument number + }}; - let mdval = @Metadata { - node: mdnode, - data: ArgumentMetadata { - id: arg.id - } + let llptr = match fcx.llargs.get_copy(&arg.id) { + local_mem(v) | local_imm(v) => v, }; - update_cache(cache, tg, argument_metadata(mdval)); - - let llptr = fcx.llargs.get_copy(&arg.id); - let declargs = ~[llmdnode([llptr]), mdnode]; - trans::build::Call(bcx, - cx.intrinsics.get_copy(&("llvm.dbg.declare")), - declargs); - return Some(mdval); + + /* + llvm::DIBuilder_insertDeclare(get_builder(cx), mdnode, llptr, mdnode + */ + + return Some(mdnode); } _ => { return None; @@ -936,32 +677,27 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) } } -pub fn update_source_pos(cx: block, s: span) { - if !cx.sess().opts.debuginfo || (*s.lo == 0 && *s.hi == 0) { - return; - } - let cm = cx.sess().codemap; - let blockmd = create_block(cx); - let loc = cm.lookup_char_pos(s.lo); - let scopedata = ~[lli32(loc.line.to_int()), - lli32(loc.col.to_int()), - blockmd.node, - llnull()]; - let dbgscope = llmdnode(scopedata); +fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { + let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { - llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope); + return llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); } } -pub fn create_function(fcx: fn_ctxt) -> @Metadata { - let mut cx = fcx.ccx; - - debug!("~~"); + let cm = bcx.sess().codemap; + let blockmd = create_block(bcx); + let loc = cm.lookup_char_pos(sp.lo); + let dbgscope = create_debug_loc(loc.line.to_int(), loc.col.to_int(), blockmd); + unsafe { + llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbgscope); + } +} +pub fn create_function(fcx: fn_ctxt) -> DISubprogram { + let cx = *fcx.ccx; + let mut dbg_cx = cx.dbg_cx.get_ref(); let fcx = &mut *fcx; - let sp = fcx.span.get(); - debug!("%s", cx.sess.codemap.span_to_str(sp)); let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) { ast_map::node_item(item, _) => { @@ -978,7 +714,6 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - let dbg_cx = cx.dbg_cx.get_ref(); ((dbg_cx.names)("fn"), decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, @@ -988,62 +723,46 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata { _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - debug!("%?", ident); - debug!("%?", id); - - let cache = get_cache(cx); - match cached_metadata::<@Metadata>( - cache, SubprogramTag, |md| md.data.id == id) { - option::Some(md) => return md, - option::None => () + match dbg_cx.created_functions.find(&id) { + Some(fn_md) => return *fn_md, + None => () } + debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); + let loc = cx.sess.codemap.lookup_char_pos(sp.lo); - let file_node = create_file(cx, loc.file.name.to_owned()).node; - let ty_node = if cx.sess.opts.extra_debuginfo { + let file_md = create_file(cx, loc.file.name); + + let ret_ty_md = if cx.sess.opts.extra_debuginfo { match ret_ty.node { - ast::ty_nil => llnull(), + ast::ty_nil => ptr::null(), _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), - ret_ty.span).node + ret_ty.span) } } else { - llnull() + ptr::null() }; - let sub_node = create_composite_type(SubroutineTag, "", file_node, 0, 0, - 0, 0, option::None, - option::Some(~[ty_node])); - let fn_metadata = ~[lltag(SubprogramTag), - llunused(), - file_node, - llstr(cx.sess.str_of(ident)), - //XXX fully-qualified C++ name: - llstr(cx.sess.str_of(ident)), - llstr(""), //XXX MIPS name????? - file_node, - lli32(loc.line as int), - sub_node, - lli1(false), //XXX static (check export) - lli1(true), // defined in compilation unit - lli32(DW_VIRTUALITY_none), // virtual-ness - lli32(0i), //index into virt func - /*llnull()*/ lli32(0), // base type with vtbl - lli32(256), // flags - lli1(cx.sess.opts.optimize != session::No), - fcx.llfn - //list of template params - //func decl descriptor - //list of func vars - ]; - let val = llmdnode(fn_metadata); - add_named_metadata(cx, ~"llvm.dbg.sp", val); - let mdval = @Metadata { - node: val, - data: SubProgramMetadata { - id: id - } - }; - update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); + let fn_ty = unsafe { + llvm::DIBuilder_createSubroutineType(get_builder(cx), + file_md, create_DIArray(get_builder(cx), [ret_ty_md])) + }; - return mdval; + let fn_md = + do as_c_str(cx.sess.str_of(ident)) |name| { + do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { + llvm::LLVMDIBuilderCreateFunction( + dcx.builder, + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, + FlagPrototyped as c_uint, + cx.sess.opts.optimize != session::No, + fcx.llfn, ptr::null(), ptr::null()) + }}}; + + dbg_cx.created_functions.insert(id, fn_md); + return fn_md; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index ba87624e2dde..315e7c4bcb12 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -560,3 +560,204 @@ extern "C" bool LLVMRustStartMultithreading() { assert(lock.release()); return ret; } + + +typedef DIBuilder* DIBuilderRef; + +template +DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } + +extern "C" DIBuilderRef DIBuilder_new(LLVMModuleRef M) { + return new DIBuilder(*unwrap(M)); +} + +extern "C" void DIBuilder_delete(DIBuilderRef Builder) { + delete Builder; +} + +extern "C" void DIBuilder_finalize(DIBuilderRef Builder) { + Builder->finalize(); +} + +extern "C" void DIBuilder_createCompileUnit( + DIBuilderRef Builder, + unsigned Lang, + const char* File, + const char* Dir, + const char* Producer, + bool isOptimized, + const char* Flags, + unsigned RuntimeVer, + const char* SplitName) { + Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized, + Flags, RuntimeVer, SplitName); +} + +extern "C" LLVMValueRef DIBuilder_createFile( + DIBuilderRef Builder, + const char* Filename, + const char* Directory) { + return wrap(Builder->createFile(Filename, Directory)); +} + +extern "C" LLVMValueRef DIBuilder_createSubroutineType( + DIBuilderRef Builder, + LLVMValueRef File, + LLVMValueRef ParameterTypes) { + return wrap(Builder->createSubroutineType( + unwrapDI(File), + unwrapDI(ParameterTypes))); +} + +extern "C" LLVMValueRef DIBuilder_createFunction( + DIBuilderRef Builder, + LLVMValueRef Scope, + const char* Name, + const char* LinkageName, + LLVMValueRef File, + unsigned LineNo, + LLVMValueRef Ty, + bool isLocalToUnit, + bool isDefinition, + unsigned ScopeLine, + unsigned Flags, + bool isOptimized, + LLVMValueRef Fn, + LLVMValueRef TParam, + LLVMValueRef Decl) { + return wrap(Builder->createFunction( + unwrapDI(Scope), Name, LinkageName, + unwrapDI(File), LineNo, + unwrapDI(Ty), isLocalToUnit, isDefinition, ScopeLine, + Flags, isOptimized, + unwrap(Fn), + unwrapDI(TParam), + unwrapDI(Decl))); +} + +extern "C" LLVMValueRef DIBuilder_createBasicType( + DIBuilderRef Builder, + const char* Name, + uint64_t SizeInBits, + uint64_t AlignInBits, + unsigned Encoding) { + return wrap(Builder->createBasicType( + Name, SizeInBits, + AlignInBits, Encoding)); +} + +extern "C" LLVMValueRef DIBuilder_createPointerType( + DIBuilderRef Builder, + LLVMValueRef PointeeTy, + uint64_t SizeInBits, + uint64_t AlignInBits, + const char* Name) { + return wrap(Builder->createPointerType( + unwrapDI(PointeeTy), SizeInBits, AlignInBits, Name)); +} + +extern "C" LLVMValueRef DIBuilder_createStructType( + DIBuilderRef Builder, + LLVMValueRef Scope, + const char* Name, + LLVMValueRef File, + unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + unsigned Flags, + LLVMValueRef DerivedFrom, + LLVMValueRef Elements, + unsigned RunTimeLang, + LLVMValueRef VTableHolder) { + return wrap(Builder->createStructType( + unwrapDI(Scope), Name, + unwrapDI(File), LineNumber, + SizeInBits, AlignInBits, Flags, + unwrapDI(DerivedFrom), + unwrapDI(Elements), RunTimeLang, + unwrapDI(VTableHolder))); +} + +extern "C" LLVMValueRef DIBuilder_createMemberType( + DIBuilderRef Builder, + LLVMValueRef Scope, + const char* Name, + LLVMValueRef File, + unsigned LineNo, + uint64_t SizeInBits, + uint64_t AlignInBits, + uint64_t OffsetInBits, + unsigned Flags, + LLVMValueRef Ty) { + return wrap(Builder->createMemberType( + unwrapDI(Scope), Name, + unwrapDI(File), LineNo, + SizeInBits, AlignInBits, OffsetInBits, Flags, + unwrapDI(Ty))); +} + +extern "C" LLVMValueRef DIBuilder_createLexicalBlock( + DIBuilderRef Builder, + LLVMValueRef Scope, + LLVMValueRef File, + unsigned Line, + unsigned Col) { + return wrap(Builder->createLexicalBlock( + unwrapDI(Scope), + unwrapDI(File), Line, Col)); +} + +extern "C" LLVMValueRef DIBuilder_createLocalVariable( + DIBuilderRef Builder, + unsigned Tag, + LLVMValueRef Scope, + const char* Name, + LLVMValueRef File, + unsigned LineNo, + LLVMValueRef Ty, + bool AlwaysPreserve, + unsigned Flags, + unsigned ArgNo) { + return wrap(Builder->createLocalVariable(Tag, + unwrapDI(Scope), Name, + unwrapDI(File), + LineNo, + unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); +} + +extern "C" LLVMValueRef DIBuilder_createVectorType( + DIBuilderRef Builder, + uint64_t Size, + uint64_t AlignInBits, + LLVMValueRef Ty, + LLVMValueRef Subscripts) { + return wrap(Builder->createVectorType(Size, AlignInBits, + unwrapDI(Ty), + unwrapDI(Subscripts))); +} + +extern "C" LLVMValueRef DIBuilder_getOrCreateSubrange( + DIBuilderRef Builder, + int64_t Lo, + int64_t Count) { + return wrap(Builder->getOrCreateSubrange(Lo, Count)); +} + +extern "C" LLVMValueRef DIBuilder_getOrCreateArray( + DIBuilderRef Builder, + LLVMValueRef* Ptr, + unsigned Count) { + return wrap(Builder->getOrCreateArray( + ArrayRef(reinterpret_cast(Ptr), Count))); +} + +extern "C" LLVMValueRef DIBuilder_insertDeclare( + DIBuilderRef Builder, + LLVMValueRef Val, + LLVMValueRef VarInfo, + LLVMValueRef InsertBefore) { + return wrap(Builder->insertDeclare( + unwrap(Val), + unwrapDI(VarInfo), + unwrap(InsertBefore))); +} diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index f53971657819..71d574aecbec 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -588,3 +588,20 @@ LLVMInlineAsm LLVMInitializePasses LLVMAddPass LLVMCreatePass +DIBuilder_new +DIBuilder_delete +DIBuilder_finalize +DIBuilder_createCompileUnit +DIBuilder_createLocalVariable +DIBuilder_createFunction +DIBuilder_createFile +DIBuilder_createLexicalBlock +DIBuilder_createBasicType +DIBuilder_createPointerType +DIBuilder_createMemberType +DIBuilder_createStructType +DIBuilder_getOrCreateSubrange +DIBuilder_createVectorType +DIBuilder_createSubroutineType +DIBuilder_getOrCreateArray +DIBuilder_insertDeclare diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 6f11202800cd..d4202abd2854 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -43,6 +43,8 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Vectorize.h" +#include "llvm/DebugInfo.h" +#include "llvm/DIBuilder.h" #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" #include "llvm-c/ExecutionEngine.h" From 6cc318978796ca67e9350561601dee9931c1da12 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 11 Jun 2013 00:57:25 -0700 Subject: [PATCH 48/96] Made the while DebugContext mutable, not just created_* hashes Disabled create_arg --- src/librustc/lib/llvm.rs | 43 +-- src/librustc/middle/trans/debuginfo.rs | 349 +++++++++++++------------ src/rustllvm/RustWrapper.cpp | 45 ++-- src/rustllvm/rustllvm.def.in | 35 +-- 4 files changed, 248 insertions(+), 224 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index ece0c1cb1909..a367de059b8b 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1925,16 +1925,16 @@ pub mod llvm { #[fast_ffi] - pub unsafe fn DIBuilder_new(M: ModuleRef) -> DIBuilderRef; + pub unsafe fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef; #[fast_ffi] - pub unsafe fn DIBuilder_delete(Builder: DIBuilderRef); + pub unsafe fn LLVMDIBuilderDispose(Builder: DIBuilderRef); #[fast_ffi] - pub unsafe fn DIBuilder_finalize(Builder: DIBuilderRef); + pub unsafe fn LLVMDIBuilderFinalize(Builder: DIBuilderRef); #[fast_ffi] - pub unsafe fn DIBuilder_createCompileUnit( + pub unsafe fn LLVMDIBuilderCreateCompileUnit( Builder: DIBuilderRef, Lang: c_uint, File: *c_char, @@ -1946,19 +1946,19 @@ pub mod llvm { SplitName: *c_char); #[fast_ffi] - pub unsafe fn DIBuilder_createFile( + pub unsafe fn LLVMDIBuilderCreateFile( Builder: DIBuilderRef, Filename: *c_char, Directory: *c_char) -> DIFile; #[fast_ffi] - pub unsafe fn DIBuilder_createSubroutineType( + pub unsafe fn LLVMDIBuilderCreateSubroutineType( Builder: DIBuilderRef, File: DIFile, ParameterTypes: DIArray) -> DICompositeType; #[fast_ffi] - pub unsafe fn DIBuilder_createFunction( + pub unsafe fn LLVMDIBuilderCreateFunction( Builder: DIBuilderRef, Scope: DIDescriptor, Name: *c_char, @@ -1976,7 +1976,7 @@ pub mod llvm { Decl: ValueRef) -> DISubprogram; #[fast_ffi] - pub unsafe fn DIBuilder_createBasicType( + pub unsafe fn LLVMDIBuilderCreateBasicType( Builder: DIBuilderRef, Name: *c_char, SizeInBits: c_ulonglong, @@ -1984,7 +1984,7 @@ pub mod llvm { Encoding: c_uint) -> DIBasicType; #[fast_ffi] - pub unsafe fn DIBuilder_createPointerType( + pub unsafe fn LLVMDIBuilderCreatePointerType( Builder: DIBuilderRef, PointeeTy: DIType, SizeInBits: c_ulonglong, @@ -1992,7 +1992,7 @@ pub mod llvm { Name: *c_char) -> DIDerivedType; #[fast_ffi] - pub unsafe fn DIBuilder_createStructType( + pub unsafe fn LLVMDIBuilderCreateStructType( Builder: DIBuilderRef, Scope: DIDescriptor, Name: *c_char, @@ -2007,7 +2007,7 @@ pub mod llvm { VTableHolder: ValueRef) -> DICompositeType; #[fast_ffi] - pub unsafe fn DIBuilder_createMemberType( + pub unsafe fn LLVMDIBuilderCreateMemberType( Builder: DIBuilderRef, Scope: DIDescriptor, Name: *c_char, @@ -2020,7 +2020,7 @@ pub mod llvm { Ty: DIType) -> DIDerivedType; #[fast_ffi] - pub unsafe fn DIBuilder_createLexicalBlock( + pub unsafe fn LLVMDIBuilderCreateLexicalBlock( Builder: DIBuilderRef, Scope: DIDescriptor, File: DIFile, @@ -2028,7 +2028,7 @@ pub mod llvm { Col: c_uint) -> DILexicalBlock; #[fast_ffi] - pub unsafe fn DIBuilder_createLocalVariable( + pub unsafe fn LLVMDIBuilderCreateLocalVariable( Builder: DIBuilderRef, Tag: c_uint, Scope: DIDescriptor, @@ -2041,7 +2041,7 @@ pub mod llvm { ArgNo: c_uint) -> DIVariable; #[fast_ffi] - pub unsafe fn DIBuilder_createVectorType( + pub unsafe fn LLVMDIBuilderCreateVectorType( Builder: DIBuilderRef, Size: c_ulonglong, AlignInBits: c_ulonglong, @@ -2049,23 +2049,30 @@ pub mod llvm { Subscripts: DIArray) -> DIType; #[fast_ffi] - pub unsafe fn DIBuilder_getOrCreateSubrange( + pub unsafe fn LLVMDIBuilderGetOrCreateSubrange( Builder: DIBuilderRef, Lo: c_longlong, Count: c_longlong) -> DISubrange; #[fast_ffi] - pub unsafe fn DIBuilder_getOrCreateArray( + pub unsafe fn LLVMDIBuilderGetOrCreateArray( Builder: DIBuilderRef, Ptr: *DIDescriptor, Count: c_uint) -> DIArray; #[fast_ffi] - pub unsafe fn DIBuilder_insertDeclare( + pub unsafe fn LLVMDIBuilderInsertDeclareAtEnd( Builder: DIBuilderRef, Val: ValueRef, VarInfo: DIVariable, - InsertBefore: *c_void) -> *c_void; + InsertAtEnd: BasicBlockRef) -> ValueRef; + + #[fast_ffi] + pub unsafe fn LLVMDIBuilderInsertDeclareBefore( + Builder: DIBuilderRef, + Val: ValueRef, + VarInfo: DIVariable, + InsertBefore: ValueRef) -> ValueRef; } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a01c2b89bf9d..2a1b2b575f7e 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -24,7 +24,11 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; +use core::ptr; +use core::str; use core::str::as_c_str; +use core::sys; +use core::vec; use syntax::codemap::span; use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; @@ -57,43 +61,45 @@ static DW_ATE_unsigned_char: int = 0x08; //////////////// -pub struct DebugContext { - //llmetadata: metadata_cache, +pub type DebugContext = @mut _DebugContext; + +struct _DebugContext { names: namegen, crate_file: ~str, builder: DIBuilderRef, - - created_files: @mut HashMap<~str, DIFile>, - created_functions: @mut HashMap, - created_blocks: @mut HashMap, - created_types: @mut HashMap + curr_loc: (int, int), + created_files: HashMap<~str, DIFile>, + created_functions: HashMap, + created_blocks: HashMap, + created_types: HashMap } /** Create new DebugContext */ pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugContext { debug!("mk_ctxt"); - let builder = unsafe { llvm::DIBuilder_new(llmod) }; - DebugContext { - //llmetadata: @mut HashMap::new(), + let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; + let dcx = @mut _DebugContext { names: new_namegen(intr), crate_file: crate, builder: builder, - created_files: @mut HashMap::new(), - created_functions: @mut HashMap::new(), - created_blocks: @mut HashMap::new(), - created_types: @mut HashMap::new(), -} + curr_loc: (-1, -1), + created_files: HashMap::new(), + created_functions: HashMap::new(), + created_blocks: HashMap::new(), + created_types: HashMap::new(), + }; + return dcx; } #[inline(always)] -fn get_builder(cx: @CrateContext) -> DIBuilderRef { - let dbg_cx = cx.dbg_cx.get_ref(); - return dbg_cx.builder; +fn dbg_cx(cx: &CrateContext) -> DebugContext +{ + return cx.dbg_cx.get(); } fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { return unsafe { - llvm::DIBuilder_getOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) }; } @@ -101,9 +107,10 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { pub fn finalize(cx: @CrateContext) { debug!("finalize"); create_compile_unit(cx); - unsafe { - llvm::DIBuilder_finalize(get_builder(cx)); - llvm::DIBuilder_delete(get_builder(cx)); + let dcx = dbg_cx(cx); + unsafe { + llvm::LLVMDIBuilderFinalize(dcx.builder); + llvm::LLVMDIBuilderDispose(dcx.builder); }; } @@ -123,52 +130,52 @@ fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { str::len(full_path)).to_owned() } else { full_path.to_owned() - }; + }; return (full_path, work_dir.to_owned()); } fn create_compile_unit(cx: @CrateContext) { - let crate_name: &str = cx.dbg_cx.get_ref().crate_file; + let crate_name: &str = dbg_cx(cx).crate_file; let (_, work_dir) = get_file_path_and_dir( cx.sess.working_dir.to_str(), crate_name); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); - + do as_c_str(crate_name) |crate_name| { do as_c_str(work_dir) |work_dir| { do as_c_str(producer) |producer| { do as_c_str("") |flags| { do as_c_str("") |split_name| { unsafe { - llvm::DIBuilder_createCompileUnit(get_builder(cx), - DW_LANG_RUST as c_uint, crate_name, work_dir, producer, + llvm::LLVMDIBuilderCreateCompileUnit(dbg_cx(cx).builder, + DW_LANG_RUST as c_uint, crate_name, work_dir, producer, cx.sess.opts.optimize != session::No, flags, 0, split_name); }}}}}}; } fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { - let mut dbg_cx = cx.dbg_cx.get_ref(); - - match dbg_cx.created_files.find(&full_path.to_owned()) { + let dcx = dbg_cx(cx); + + match dcx.created_files.find(&full_path.to_owned()) { Some(file_md) => return *file_md, None => () } debug!("create_file: %s", full_path); - + let (file_path, work_dir) = get_file_path_and_dir(cx.sess.working_dir.to_str(), full_path); - let file_md = + let file_md = do as_c_str(file_path) |file_path| { do as_c_str(work_dir) |work_dir| { unsafe { - llvm::DIBuilder_createFile(get_builder(cx), file_path, work_dir) + llvm::LLVMDIBuilderCreateFile(dcx.builder, file_path, work_dir) }}}; - - dbg_cx.created_files.insert(full_path.to_owned(), file_md); + + dcx.created_files.insert(full_path.to_owned(), file_md); return file_md; } @@ -178,8 +185,9 @@ fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; - let mut dbg_cx = bcx.ccx().dbg_cx.get_ref(); - + let cx = bcx.ccx(); + let mut dcx = dbg_cx(cx); + while bcx.node_info.is_none() { match bcx.parent { Some(b) => bcx = b, @@ -188,33 +196,33 @@ fn create_block(bcx: block) -> DILexicalBlock { } let sp = bcx.node_info.get().span; let id = bcx.node_info.get().id; - - match dbg_cx.created_blocks.find(&id) { + + match dcx.created_blocks.find(&id) { Some(block) => return *block, None => () } - + debug!("create_block: %s", bcx.sess().codemap.span_to_str(sp)); - + let start = bcx.sess().codemap.lookup_char_pos(sp.lo); - let end = bcx.sess().codemap.lookup_char_pos(sp.hi); + //let end = bcx.sess().codemap.lookup_char_pos(sp.hi); let parent = match bcx.parent { None => create_function(bcx.fcx), Some(b) => create_block(b) }; - + let file_md = create_file(bcx.ccx(), start.file.name); - let block_md = unsafe { + let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( - dcx.builder, - parent, file_md, + dcx.builder, + parent, file_md, start.line.to_int() as c_uint, start.col.to_int() as c_uint) }; - - dbg_cx.created_blocks.insert(id, block_md); - + + dcx.created_blocks.insert(id, block_md); + return block_md; } @@ -225,14 +233,14 @@ fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ - let mut dbg_cx = cx.dbg_cx.get_ref(); + let mut dcx = dbg_cx(cx); let ty_id = ty::type_id(t); - match dbg_cx.created_types.find(&ty_id) { + match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } - - debug!("create_basic_type: %?", ty::get(t)); + + debug!("create_basic_type: %?", ty::get(t)); let (name, encoding) = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned), @@ -263,11 +271,11 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + dcx.builder, name, size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; - - dbg_cx.created_types.insert(ty_id, ty_md); + + dcx.created_types.insert(ty_id, ty_md); return ty_md; } @@ -275,7 +283,7 @@ fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::DIBuilder_createPointerType(get_builder(cx), + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, pointee, size * 8 as u64, align * 8 as u64, name) }}; return ptr_md; @@ -304,11 +312,11 @@ impl StructContext { }; return scx; } - + fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { let mem_t = do as_c_str(name) |name| { unsafe { - llvm::DIBuilder_createMemberType(get_builder(self.cx), - ptr::null(), name, self.file, line as c_uint, + llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, + ptr::null(), name, self.file, line as c_uint, size * 8 as u64, align * 8 as u64, self.total_size as u64, 0, ty) }}; @@ -316,11 +324,12 @@ impl StructContext { self.members.push(mem_t); self.total_size += size * 8; } - + fn finalize(&self) -> DICompositeType { - let members_md = create_DIArray(get_builder(self.cx), self.members); - - let struct_md = + let dcx = dbg_cx(self.cx); + let members_md = create_DIArray(dcx.builder, self.members); + + let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( dcx.builder, ptr::null(), name, @@ -336,7 +345,7 @@ fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); let line = line_from_span(cx.sess.codemap, span); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), line); for fields.each |field| { let field_t = field.mt.ty; @@ -350,24 +359,24 @@ fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr() -> (DIDerivedType, uint, uint) { +fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); - let vp = ptr::null(); - /* - let vp = create_derived_type(PointerTypeTag, null, ~"", 0, - size, align, 0, null); - */ + let vp = do as_c_str("*void") |name| { unsafe { + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), + size*8 as u64, align*8 as u64, name) + }}; return (vp, size, align); } fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { + let dcx = dbg_cx(cx); let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); let mut scx = StructContext::create(cx, file_md, name, loc.line); - + for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); @@ -384,13 +393,13 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - + let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); // the tydesc and other pointers should be irrelevant to the // debugger, so treat them as void* types - let (vp, vpsize, vpalign) = voidptr(); + let (vp, vpsize, vpalign) = voidptr(cx); scx.add_member("tydesc", 0, vpsize, vpalign, vp); scx.add_member("prev", 0, vpsize, vpalign, vp); scx.add_member("next", 0, vpsize, vpalign, vp); @@ -401,40 +410,42 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { + let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); let (size, align) = size_and_align_of(cx, elem_t); - let subrange = unsafe { - llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, (len-1) as i64) }; + let subrange = unsafe { + llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; - let subscripts = create_DIArray(get_builder(cx), [subrange]); - return unsafe { - llvm::DIBuilder_createVectorType(get_builder(cx), + let subscripts = create_DIArray(dcx.builder, [subrange]); + return unsafe { + llvm::LLVMDIBuilderCreateVectorType(dcx.builder, size * len as u64, align as u64, elem_ty_md, subscripts) }; } fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: codemap::span) -> DICompositeType { + let dcx = dbg_cx(cx); let fname = filename_from_span(cx, vec_ty_span); let file_md = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - + let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - + let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); vec_scx.add_member("fill", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); vec_scx.add_member("alloc", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); - let subrange = unsafe { llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, 0_i64) }; + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, 0_i64) }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - - let subscripts = create_DIArray(get_builder(cx), [subrange]); - let data_ptr = unsafe { llvm::DIBuilder_createVectorType(get_builder(cx), + + let subscripts = create_DIArray(dcx.builder, [subrange]); + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); @@ -445,7 +456,7 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let refcount_type = create_basic_type(cx, int_t, vec_ty_span); box_scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); - let (vp, vpsize, vpalign) = voidptr(); + let (vp, vpsize, vpalign) = voidptr(cx); box_scx.add_member("tydesc", 0, vpsize, vpalign, vp); box_scx.add_member("prev", 0, vpsize, vpalign, vp); box_scx.add_member("next", 0, vpsize, vpalign, vp); @@ -462,9 +473,9 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - let (_, ptr_size, ptr_align) = voidptr(); + let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); scx.add_member("length", 0, sys::size_of::(), sys::min_align_of::(), uint_type); @@ -473,24 +484,25 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { + let dcx = dbg_cx(cx); let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); - let (vp, _, _) = voidptr(); + let (vp, _, _) = voidptr(cx); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) }; let members = ~[output_ptr_md, vp] + inputs_vals; - - return unsafe { - llvm::DIBuilder_createSubroutineType(get_builder(cx), file_md, - create_DIArray(get_builder(cx), members)) + + return unsafe { + llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, + create_DIArray(dcx.builder, members)) }; } fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { - let mut dbg_cx = cx.dbg_cx.get_ref(); + let mut dcx = dbg_cx(cx); let ty_id = ty::type_id(t); - match dbg_cx.created_types.find(&ty_id) { + match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } @@ -565,25 +577,16 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { }, _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") }; - - dbg_cx.created_types.insert(ty_id, ty_md); + + dcx.created_types.insert(ty_id, ty_md); return ty_md; } pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { - debug!("create_local_var"); let cx = bcx.ccx(); - /* - let cache = get_cache(cx); - let tg = AutoVariableTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| md.data.id == local.node.id) { - option::Some(md) => return md, - option::None => () - } - */ + let dcx = dbg_cx(cx); - let name = match local.node.pat.node { + let ident = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) _ => fail!("no single variable name for local") @@ -594,59 +597,51 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, /*bad*/copy loc.file.name); + let filemd = create_file(cx, loc.file.name); let context = match bcx.parent { None => create_function(bcx.fcx), Some(_) => create_block(bcx) }; - - let mdval = do as_c_str(*cx.sess.str_of(name)) |name| { unsafe { - llvm::DIBuilder_createLocalVariable(get_builder(cx), AutoVariableTag as u32, - ptr::null(), name, filemd, loc.line as c_uint, tymd, false, 0, 0) + + let var_md = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateLocalVariable( + dcx.builder, AutoVariableTag as u32, + context, name, filemd, + loc.line as c_uint, tymd, false, 0, 0) }}; - - let llptr = match bcx.fcx.lllocals.find(&local.node.id) { - option::Some(&local_mem(v)) => v, - option::Some(_) => { - bcx.tcx().sess.span_bug(local.span, "local is bound to something weird"); + + // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc + let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { + Some(v) => v, + None => { + bcx.tcx().sess.span_bug( + local.span, + fmt!("No entry in lllocals table for %?", local.node.id)); } - option::None => { - match bcx.fcx.lllocals.get_copy(&local.node.pat.id) { - local_imm(v) => v, - _ => bcx.tcx().sess.span_bug(local.span, "local is bound to something weird") - } - } }; - /* - llvm::DIBuilder_insertDeclare(get_builder(cx), llptr, mdval, - - let declargs = ~[llmdnode(~[llptr]), mdnode]; - trans::build::Call(bcx, *cx.intrinsics.get(&~"llvm.dbg.declare"), - declargs); - */ - return mdval; + unsafe { + llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); } + return var_md; +} pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { debug!("create_arg"); let fcx = bcx.fcx, cx = *fcx.ccx; - /* - let cache = get_cache(cx); - let tg = ArgVariableTag; - match cached_metadata::<@Metadata>( - cache, ArgVariableTag, |md| md.data.id == arg.id) { - option::Some(md) => return Some(md), - option::None => () - } - */ + let dcx = dbg_cx(cx); let loc = cx.sess.codemap.lookup_char_pos(sp.lo); if "" == loc.file.name { return None; } + // FIXME: Disabled for now because "node_id_type(bcx, arg.id)" below blows up: + // "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" + // (same as https://github.com/mozilla/rust/issues/5848) + return None; + let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, /*bad*/copy loc.file.name); + let filemd = create_file(cx, loc.file.name); let context = create_function(bcx.fcx); match arg.pat.node { @@ -656,19 +651,15 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, - ArgVariableTag as u32, context, name, + ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) - // XXX need to pass a real argument number + // FIXME need to pass a real argument number }}; - - let llptr = match fcx.llargs.get_copy(&arg.id) { - local_mem(v) | local_imm(v) => v, - }; - - /* - llvm::DIBuilder_insertDeclare(get_builder(cx), mdnode, llptr, mdnode - */ - + + let llptr = fcx.llargs.get_copy(&arg.id); + unsafe { + llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, mdnode, bcx.llbb); + } return Some(mdnode); } _ => { @@ -684,9 +675,23 @@ fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { } } +pub fn update_source_pos(bcx: block, sp: span) { + if !bcx.sess().opts.debuginfo || (*sp.lo == 0 && *sp.hi == 0) { + return; + } + + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(sp)); + let cm = bcx.sess().codemap; - let blockmd = create_block(bcx); let loc = cm.lookup_char_pos(sp.lo); + let cx = bcx.ccx(); + let mut dcx = dbg_cx(cx); + if (loc.line.to_int(), loc.col.to_int()) == dcx.curr_loc { + return; + } + + dcx.curr_loc = (loc.line.to_int(), loc.col.to_int()); + let blockmd = create_block(bcx); let dbgscope = create_debug_loc(loc.line.to_int(), loc.col.to_int(), blockmd); unsafe { llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbgscope); @@ -695,7 +700,7 @@ fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let cx = *fcx.ccx; - let mut dbg_cx = cx.dbg_cx.get_ref(); + let mut dcx = dbg_cx(cx); let fcx = &mut *fcx; let sp = fcx.span.get(); @@ -714,7 +719,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - ((dbg_cx.names)("fn"), decl.output, expr.id) + ((dcx.names)("fn"), decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") @@ -722,8 +727,8 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - - match dbg_cx.created_functions.find(&id) { + + match dcx.created_functions.find(&id) { Some(fn_md) => return *fn_md, None => () } @@ -742,27 +747,27 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } else { ptr::null() }; - + let fn_ty = unsafe { - llvm::DIBuilder_createSubroutineType(get_builder(cx), - file_md, create_DIArray(get_builder(cx), [ret_ty_md])) + llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, + file_md, create_DIArray(dcx.builder, [ret_ty_md])) }; - - let fn_md = + + let fn_md = do as_c_str(cx.sess.str_of(ident)) |name| { do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { llvm::LLVMDIBuilderCreateFunction( - dcx.builder, - file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, - loc.line as c_uint, + dcx.builder, + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, FlagPrototyped as c_uint, - cx.sess.opts.optimize != session::No, + cx.sess.opts.optimize != session::No, fcx.llfn, ptr::null(), ptr::null()) }}}; - - dbg_cx.created_functions.insert(id, fn_md); + + dcx.created_functions.insert(id, fn_md); return fn_md; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 315e7c4bcb12..b7a67f984f73 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -567,19 +567,19 @@ typedef DIBuilder* DIBuilderRef; template DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } -extern "C" DIBuilderRef DIBuilder_new(LLVMModuleRef M) { +extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) { return new DIBuilder(*unwrap(M)); } -extern "C" void DIBuilder_delete(DIBuilderRef Builder) { +extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) { delete Builder; } -extern "C" void DIBuilder_finalize(DIBuilderRef Builder) { +extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) { Builder->finalize(); } -extern "C" void DIBuilder_createCompileUnit( +extern "C" void LLVMDIBuilderCreateCompileUnit( DIBuilderRef Builder, unsigned Lang, const char* File, @@ -593,14 +593,14 @@ extern "C" void DIBuilder_createCompileUnit( Flags, RuntimeVer, SplitName); } -extern "C" LLVMValueRef DIBuilder_createFile( +extern "C" LLVMValueRef LLVMDIBuilderCreateFile( DIBuilderRef Builder, const char* Filename, const char* Directory) { return wrap(Builder->createFile(Filename, Directory)); } -extern "C" LLVMValueRef DIBuilder_createSubroutineType( +extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType( DIBuilderRef Builder, LLVMValueRef File, LLVMValueRef ParameterTypes) { @@ -609,7 +609,7 @@ extern "C" LLVMValueRef DIBuilder_createSubroutineType( unwrapDI(ParameterTypes))); } -extern "C" LLVMValueRef DIBuilder_createFunction( +extern "C" LLVMValueRef LLVMDIBuilderCreateFunction( DIBuilderRef Builder, LLVMValueRef Scope, const char* Name, @@ -635,7 +635,7 @@ extern "C" LLVMValueRef DIBuilder_createFunction( unwrapDI(Decl))); } -extern "C" LLVMValueRef DIBuilder_createBasicType( +extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType( DIBuilderRef Builder, const char* Name, uint64_t SizeInBits, @@ -646,7 +646,7 @@ extern "C" LLVMValueRef DIBuilder_createBasicType( AlignInBits, Encoding)); } -extern "C" LLVMValueRef DIBuilder_createPointerType( +extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType( DIBuilderRef Builder, LLVMValueRef PointeeTy, uint64_t SizeInBits, @@ -656,7 +656,7 @@ extern "C" LLVMValueRef DIBuilder_createPointerType( unwrapDI(PointeeTy), SizeInBits, AlignInBits, Name)); } -extern "C" LLVMValueRef DIBuilder_createStructType( +extern "C" LLVMValueRef LLVMDIBuilderCreateStructType( DIBuilderRef Builder, LLVMValueRef Scope, const char* Name, @@ -678,7 +678,7 @@ extern "C" LLVMValueRef DIBuilder_createStructType( unwrapDI(VTableHolder))); } -extern "C" LLVMValueRef DIBuilder_createMemberType( +extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType( DIBuilderRef Builder, LLVMValueRef Scope, const char* Name, @@ -696,7 +696,7 @@ extern "C" LLVMValueRef DIBuilder_createMemberType( unwrapDI(Ty))); } -extern "C" LLVMValueRef DIBuilder_createLexicalBlock( +extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock( DIBuilderRef Builder, LLVMValueRef Scope, LLVMValueRef File, @@ -707,7 +707,7 @@ extern "C" LLVMValueRef DIBuilder_createLexicalBlock( unwrapDI(File), Line, Col)); } -extern "C" LLVMValueRef DIBuilder_createLocalVariable( +extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable( DIBuilderRef Builder, unsigned Tag, LLVMValueRef Scope, @@ -725,7 +725,7 @@ extern "C" LLVMValueRef DIBuilder_createLocalVariable( unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); } -extern "C" LLVMValueRef DIBuilder_createVectorType( +extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType( DIBuilderRef Builder, uint64_t Size, uint64_t AlignInBits, @@ -736,14 +736,14 @@ extern "C" LLVMValueRef DIBuilder_createVectorType( unwrapDI(Subscripts))); } -extern "C" LLVMValueRef DIBuilder_getOrCreateSubrange( +extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange( DIBuilderRef Builder, int64_t Lo, int64_t Count) { return wrap(Builder->getOrCreateSubrange(Lo, Count)); } -extern "C" LLVMValueRef DIBuilder_getOrCreateArray( +extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray( DIBuilderRef Builder, LLVMValueRef* Ptr, unsigned Count) { @@ -751,7 +751,18 @@ extern "C" LLVMValueRef DIBuilder_getOrCreateArray( ArrayRef(reinterpret_cast(Ptr), Count))); } -extern "C" LLVMValueRef DIBuilder_insertDeclare( +extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( + DIBuilderRef Builder, + LLVMValueRef Val, + LLVMValueRef VarInfo, + LLVMBasicBlockRef InsertAtEnd) { + return wrap(Builder->insertDeclare( + unwrap(Val), + unwrapDI(VarInfo), + unwrap(InsertAtEnd))); +} + +extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore( DIBuilderRef Builder, LLVMValueRef Val, LLVMValueRef VarInfo, diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 71d574aecbec..d1ed69feb04b 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -588,20 +588,21 @@ LLVMInlineAsm LLVMInitializePasses LLVMAddPass LLVMCreatePass -DIBuilder_new -DIBuilder_delete -DIBuilder_finalize -DIBuilder_createCompileUnit -DIBuilder_createLocalVariable -DIBuilder_createFunction -DIBuilder_createFile -DIBuilder_createLexicalBlock -DIBuilder_createBasicType -DIBuilder_createPointerType -DIBuilder_createMemberType -DIBuilder_createStructType -DIBuilder_getOrCreateSubrange -DIBuilder_createVectorType -DIBuilder_createSubroutineType -DIBuilder_getOrCreateArray -DIBuilder_insertDeclare +LLVMDIBuilderCreate +LLVMDIBuilderDispose +LLVMDIBuilderFinalize +LLVMDIBuilderCreateCompileUnit +LLVMDIBuilderCreateLocalVariable +LLVMDIBuilderCreateFunction +LLVMDIBuilderCreateFile +LLVMDIBuilderCreateLexicalBlock +LLVMDIBuilderCreateBasicType +LLVMDIBuilderCreatePointerType +LLVMDIBuilderCreateMemberType +LLVMDIBuilderCreateStructType +LLVMDIBuilderGetOrCreateSubrange +LLVMDIBuilderCreateVectorType +LLVMDIBuilderCreateSubroutineType +LLVMDIBuilderGetOrCreateArray +LLVMDIBuilderInsertDeclareAtEnd +LLVMDIBuilderInsertDeclareBefore From 1079e41143e2f94fc0f969b967aaf89b2f4448a2 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 10 Jun 2013 12:32:12 -0700 Subject: [PATCH 49/96] Move "return" basic block after all other function blocks. --- src/librustc/lib/llvm.rs | 6 ++++++ src/librustc/middle/trans/base.rs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index a367de059b8b..81d5efa6314c 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -966,6 +966,12 @@ pub mod llvm { -> BasicBlockRef; #[fast_ffi] pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef); + + #[fast_ffi] + pub unsafe fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef, MoveAfter: BasicBlockRef); + + #[fast_ffi] + pub unsafe fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef, MoveBefore: BasicBlockRef); /* Operations on instructions */ #[fast_ffi] diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 580e7fa1900a..70b6c2ba0362 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1907,6 +1907,8 @@ pub fn trans_closure(ccx: @mut CrateContext, finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); + + unsafe { llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); } // Insert the mandatory first few basic blocks before lltop. finish_fn(fcx, lltop); From 6db3302b354c47dba4463752e21c37049860b761 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 10 Jun 2013 16:28:10 -0700 Subject: [PATCH 50/96] Debug loc for local var declarations --- src/librustc/middle/trans/debuginfo.rs | 32 +++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 2a1b2b575f7e..4b00b027968b 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -67,7 +67,7 @@ struct _DebugContext { names: namegen, crate_file: ~str, builder: DIBuilderRef, - curr_loc: (int, int), + curr_loc: (uint, uint), created_files: HashMap<~str, DIFile>, created_functions: HashMap, created_blocks: HashMap, @@ -82,7 +82,7 @@ pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugCon names: new_namegen(intr), crate_file: crate, builder: builder, - curr_loc: (-1, -1), + curr_loc: (0, 0), created_files: HashMap::new(), created_functions: HashMap::new(), created_blocks: HashMap::new(), @@ -619,9 +619,13 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { fmt!("No entry in lllocals table for %?", local.node.id)); } }; + + set_debug_location(bcx, loc.line, loc.col.to_uint()); unsafe { - llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } + return var_md; } @@ -668,10 +672,12 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { } } -fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { - let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; +fn set_debug_location(bcx: block, line: uint, col: uint) { + let blockmd = create_block(bcx); + let elems = ~[C_i32(line as i32), C_i32(col as i32), blockmd, ptr::null()]; unsafe { - return llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); + let dbg_loc = llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); + llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); } } @@ -686,16 +692,14 @@ pub fn update_source_pos(bcx: block, sp: span) { let loc = cm.lookup_char_pos(sp.lo); let cx = bcx.ccx(); let mut dcx = dbg_cx(cx); - if (loc.line.to_int(), loc.col.to_int()) == dcx.curr_loc { + + let loc = (loc.line, loc.col.to_uint()); + if loc == dcx.curr_loc { return; } - - dcx.curr_loc = (loc.line.to_int(), loc.col.to_int()); - let blockmd = create_block(bcx); - let dbgscope = create_debug_loc(loc.line.to_int(), loc.col.to_int(), blockmd); - unsafe { - llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbgscope); - } + debug!("setting_location to %u %u", loc.first(), loc.second()); + dcx.curr_loc = loc; + set_debug_location(bcx, loc.first(), loc.second()); } pub fn create_function(fcx: fn_ctxt) -> DISubprogram { From 00bb15bf726e0aa440557131224bdab77dd46682 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 10 Jun 2013 18:34:51 -0700 Subject: [PATCH 51/96] Removed extraneous string allocations. Misc refactoring. --- src/librustc/middle/trans/debuginfo.rs | 126 ++++++++++--------------- 1 file changed, 50 insertions(+), 76 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 4b00b027968b..c0e7f6472a6b 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -75,11 +75,11 @@ struct _DebugContext { } /** Create new DebugContext */ -pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugContext { +pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { debug!("mk_ctxt"); let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; let dcx = @mut _DebugContext { - names: new_namegen(intr), + names: new_namegen(), crate_file: crate, builder: builder, curr_loc: (0, 0), @@ -114,33 +114,9 @@ pub fn finalize(cx: @CrateContext) { }; } -fn filename_from_span(cx: @CrateContext, sp: codemap::span) -> ~str { - /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name -} - -//fn filename_from_span<'cx>(cx: &'cx CrateContext, sp: codemap::span) -> &'cx str { -// let fname: &str = cx.sess.codemap.lookup_char_pos(sp.lo).file.name; -// return fname; -//} - -fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { - let full_path = - if str::starts_with(full_path, work_dir) { - str::slice(full_path, str::len(work_dir) + 1u, - str::len(full_path)).to_owned() - } else { - full_path.to_owned() - }; - - return (full_path, work_dir.to_owned()); -} - fn create_compile_unit(cx: @CrateContext) { let crate_name: &str = dbg_cx(cx).crate_file; - - let (_, work_dir) = get_file_path_and_dir( - cx.sess.working_dir.to_str(), crate_name); - + let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); do as_c_str(crate_name) |crate_name| { @@ -158,29 +134,33 @@ fn create_compile_unit(cx: @CrateContext) { fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { let dcx = dbg_cx(cx); - match dcx.created_files.find(&full_path.to_owned()) { + match dcx.created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } debug!("create_file: %s", full_path); - let (file_path, work_dir) = - get_file_path_and_dir(cx.sess.working_dir.to_str(), - full_path); - + let work_dir = cx.sess.working_dir.to_str(); + let file_name = + if full_path.starts_with(work_dir) { + full_path.slice(work_dir.len() + 1u, full_path.len()) + } else { + full_path + }; + let file_md = - do as_c_str(file_path) |file_path| { + do as_c_str(file_name) |file_name| { do as_c_str(work_dir) |work_dir| { unsafe { - llvm::LLVMDIBuilderCreateFile(dcx.builder, file_path, work_dir) + llvm::LLVMDIBuilderCreateFile(dcx.builder, file_name, work_dir) }}}; dcx.created_files.insert(full_path.to_owned(), file_md); return file_md; } -fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { - cm.lookup_char_pos(sp.lo).line +fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { + return cx.sess.codemap.lookup_char_pos(span.lo); } fn create_block(bcx: block) -> DILexicalBlock { @@ -194,7 +174,7 @@ fn create_block(bcx: block) -> DILexicalBlock { None => fail!() } } - let sp = bcx.node_info.get().span; + let span = bcx.node_info.get().span; let id = bcx.node_info.get().id; match dcx.created_blocks.find(&id) { @@ -202,23 +182,21 @@ fn create_block(bcx: block) -> DILexicalBlock { None => () } - debug!("create_block: %s", bcx.sess().codemap.span_to_str(sp)); - - let start = bcx.sess().codemap.lookup_char_pos(sp.lo); - //let end = bcx.sess().codemap.lookup_char_pos(sp.hi); + debug!("create_block: %s", bcx.sess().codemap.span_to_str(span)); let parent = match bcx.parent { None => create_function(bcx.fcx), Some(b) => create_block(b) }; - - let file_md = create_file(bcx.ccx(), start.file.name); + let cx = bcx.ccx(); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( dcx.builder, parent, file_md, - start.line.to_int() as c_uint, start.col.to_int() as c_uint) + loc.line as c_uint, loc.col.to_uint() as c_uint) }; dcx.created_blocks.insert(id, block_md); @@ -342,18 +320,16 @@ impl StructContext { } fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); - let line = line_from_span(cx.sess.codemap, span); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); - let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), line); + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), loc.line); for fields.each |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); scx.add_member(cx.sess.str_of(field.ident), - line_from_span(cx.sess.codemap, span), - size, align, ty_md); + loc.line, size, align, ty_md); } return scx.finalize(); } @@ -371,8 +347,8 @@ fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { let dcx = dbg_cx(cx); - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); let mut scx = StructContext::create(cx, file_md, name, loc.line); @@ -380,16 +356,15 @@ fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); - scx.add_member("", line_from_span(cx.sess.codemap, span), - size, align, ty_md); + scx.add_member("", loc.line, size, align, ty_md); } return scx.finalize(); } fn create_boxed_type(cx: @CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); @@ -412,8 +387,8 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { @@ -427,10 +402,10 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, } fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, - vec_ty_span: codemap::span) -> DICompositeType { + vec_ty_span: span) -> DICompositeType { let dcx = dbg_cx(cx); - let fname = filename_from_span(cx, vec_ty_span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, vec_ty_span); + let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); @@ -468,8 +443,8 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, } fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); @@ -485,8 +460,8 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { let dcx = dbg_cx(cx); - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); @@ -593,7 +568,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { }; let name: &str = cx.sess.str_of(ident); debug!("create_local_var: %s", name); - + let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); @@ -629,12 +604,12 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { return var_md; } -pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { +pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { debug!("create_arg"); let fcx = bcx.fcx, cx = *fcx.ccx; let dcx = dbg_cx(cx); - let loc = cx.sess.codemap.lookup_char_pos(sp.lo); + let loc = span_start(cx, span); if "" == loc.file.name { return None; } @@ -654,7 +629,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) // FIXME need to pass a real argument number @@ -681,16 +656,15 @@ fn set_debug_location(bcx: block, line: uint, col: uint) { } } -pub fn update_source_pos(bcx: block, sp: span) { - if !bcx.sess().opts.debuginfo || (*sp.lo == 0 && *sp.hi == 0) { +pub fn update_source_pos(bcx: block, span: span) { + if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } - debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(sp)); + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); - let cm = bcx.sess().codemap; - let loc = cm.lookup_char_pos(sp.lo); let cx = bcx.ccx(); + let loc = span_start(cx, span); let mut dcx = dbg_cx(cx); let loc = (loc.line, loc.col.to_uint()); @@ -706,7 +680,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let cx = *fcx.ccx; let mut dcx = dbg_cx(cx); let fcx = &mut *fcx; - let sp = fcx.span.get(); + let span = fcx.span.get(); let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) { ast_map::node_item(item, _) => { @@ -739,7 +713,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); - let loc = cx.sess.codemap.lookup_char_pos(sp.lo); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let ret_ty_md = if cx.sess.opts.extra_debuginfo { From 62e86e044db030b2ffb7883075720360a8dccdd4 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 11 Jun 2013 12:41:09 -0700 Subject: [PATCH 52/96] Fixed compile warnings. Fixed whitespace "errors". --- src/librustc/lib/llvm.rs | 8 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 181 +++++++++++++------------ 3 files changed, 96 insertions(+), 95 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 81d5efa6314c..d248627907ac 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -966,10 +966,10 @@ pub mod llvm { -> BasicBlockRef; #[fast_ffi] pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef); - + #[fast_ffi] pub unsafe fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef, MoveAfter: BasicBlockRef); - + #[fast_ffi] pub unsafe fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef, MoveBefore: BasicBlockRef); @@ -2072,13 +2072,13 @@ pub mod llvm { Val: ValueRef, VarInfo: DIVariable, InsertAtEnd: BasicBlockRef) -> ValueRef; - + #[fast_ffi] pub unsafe fn LLVMDIBuilderInsertDeclareBefore( Builder: DIBuilderRef, Val: ValueRef, VarInfo: DIVariable, - InsertBefore: ValueRef) -> ValueRef; + InsertBefore: ValueRef) -> ValueRef; } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 70b6c2ba0362..ddc8207dfe04 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1907,7 +1907,7 @@ pub fn trans_closure(ccx: @mut CrateContext, finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); - + unsafe { llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); } // Insert the mandatory first few basic blocks before lltop. diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index c0e7f6472a6b..bbdfefaaa596 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -25,12 +25,10 @@ use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; use core::ptr; -use core::str; use core::str::as_c_str; use core::sys; use core::vec; use syntax::codemap::span; -use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; static LLVMDebugVersion: int = (12 << 16); @@ -98,8 +96,8 @@ fn dbg_cx(cx: &CrateContext) -> DebugContext } fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { - return unsafe { - llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + return unsafe { + llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) }; } @@ -108,7 +106,7 @@ pub fn finalize(cx: @CrateContext) { debug!("finalize"); create_compile_unit(cx); let dcx = dbg_cx(cx); - unsafe { + unsafe { llvm::LLVMDIBuilderFinalize(dcx.builder); llvm::LLVMDIBuilderDispose(dcx.builder); }; @@ -118,14 +116,14 @@ fn create_compile_unit(cx: @CrateContext) { let crate_name: &str = dbg_cx(cx).crate_file; let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); - + do as_c_str(crate_name) |crate_name| { do as_c_str(work_dir) |work_dir| { do as_c_str(producer) |producer| { do as_c_str("") |flags| { do as_c_str("") |split_name| { unsafe { llvm::LLVMDIBuilderCreateCompileUnit(dbg_cx(cx).builder, - DW_LANG_RUST as c_uint, crate_name, work_dir, producer, + DW_LANG_RUST as c_uint, crate_name, work_dir, producer, cx.sess.opts.optimize != session::No, flags, 0, split_name); }}}}}}; @@ -133,28 +131,28 @@ fn create_compile_unit(cx: @CrateContext) { fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { let dcx = dbg_cx(cx); - + match dcx.created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } debug!("create_file: %s", full_path); - + let work_dir = cx.sess.working_dir.to_str(); - let file_name = + let file_name = if full_path.starts_with(work_dir) { full_path.slice(work_dir.len() + 1u, full_path.len()) } else { full_path }; - - let file_md = + + let file_md = do as_c_str(file_name) |file_name| { do as_c_str(work_dir) |work_dir| { unsafe { llvm::LLVMDIBuilderCreateFile(dcx.builder, file_name, work_dir) }}}; - + dcx.created_files.insert(full_path.to_owned(), file_md); return file_md; } @@ -166,8 +164,8 @@ fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; let cx = bcx.ccx(); - let mut dcx = dbg_cx(cx); - + let dcx = dbg_cx(cx); + while bcx.node_info.is_none() { match bcx.parent { Some(b) => bcx = b, @@ -176,14 +174,14 @@ fn create_block(bcx: block) -> DILexicalBlock { } let span = bcx.node_info.get().span; let id = bcx.node_info.get().id; - + match dcx.created_blocks.find(&id) { Some(block) => return *block, None => () } - + debug!("create_block: %s", bcx.sess().codemap.span_to_str(span)); - + let parent = match bcx.parent { None => create_function(bcx.fcx), Some(b) => create_block(b) @@ -191,16 +189,16 @@ fn create_block(bcx: block) -> DILexicalBlock { let cx = bcx.ccx(); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - - let block_md = unsafe { + + let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( - dcx.builder, - parent, file_md, - loc.line as c_uint, loc.col.to_uint() as c_uint) + dcx.builder, + parent, file_md, + loc.line as c_uint, loc.col.to_uint() as c_uint) }; - + dcx.created_blocks.insert(id, block_md); - + return block_md; } @@ -211,14 +209,14 @@ fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ - let mut dcx = dbg_cx(cx); + let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } - - debug!("create_basic_type: %?", ty::get(t)); + + debug!("create_basic_type: %?", ty::get(t)); let (name, encoding) = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned), @@ -249,10 +247,10 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + dcx.builder, name, size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; - + dcx.created_types.insert(ty_id, ty_md); return ty_md; } @@ -261,7 +259,7 @@ fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, pointee, size * 8 as u64, align * 8 as u64, name) }}; return ptr_md; @@ -290,27 +288,27 @@ impl StructContext { }; return scx; } - + fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { let mem_t = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, - ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, self.total_size as u64, + llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, + ptr::null(), name, self.file, line as c_uint, + size * 8 as u64, align * 8 as u64, self.total_size as u64, 0, ty) }}; // XXX What about member alignment??? self.members.push(mem_t); self.total_size += size * 8; } - + fn finalize(&self) -> DICompositeType { let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); - - let struct_md = + + let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, ptr::null(), name, + dcx.builder, ptr::null(), name, self.file, self.line as c_uint, self.total_size as u64, self.align as u64, 0, ptr::null(), members_md, 0, ptr::null()) @@ -322,7 +320,7 @@ impl StructContext { fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), loc.line); for fields.each |field| { let field_t = field.mt.ty; @@ -339,7 +337,7 @@ fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), size*8 as u64, align*8 as u64, name) }}; return (vp, size, align); @@ -352,7 +350,7 @@ fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); let mut scx = StructContext::create(cx, file_md, name, loc.line); - + for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); @@ -368,7 +366,7 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - + let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); @@ -391,13 +389,13 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let file_md = create_file(cx, loc.file.name); let (size, align) = size_and_align_of(cx, elem_t); - let subrange = unsafe { + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; let subscripts = create_DIArray(dcx.builder, [subrange]); - return unsafe { - llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - size * len as u64, align as u64, elem_ty_md, subscripts) + return unsafe { + llvm::LLVMDIBuilderCreateVectorType(dcx.builder, + size * len as u64, align as u64, elem_ty_md, subscripts) }; } @@ -407,9 +405,9 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let loc = span_start(cx, vec_ty_span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - + let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - + let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); vec_scx.add_member("fill", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); @@ -418,9 +416,9 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, 0_i64) }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - + let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); @@ -448,7 +446,7 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); @@ -467,15 +465,15 @@ fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t let output_ptr_md = create_pointer_type(cx, output, span, output_md); let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) }; let members = ~[output_ptr_md, vp] + inputs_vals; - - return unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, - create_DIArray(dcx.builder, members)) + + return unsafe { + llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, + create_DIArray(dcx.builder, members)) }; } fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { - let mut dcx = dbg_cx(cx); + let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, @@ -552,7 +550,7 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { }, _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") }; - + dcx.created_types.insert(ty_id, ty_md); return ty_md; } @@ -568,7 +566,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { }; let name: &str = cx.sess.str_of(ident); debug!("create_local_var: %s", name); - + let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); @@ -577,14 +575,14 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { None => create_function(bcx.fcx), Some(_) => create_block(bcx) }; - + let var_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateLocalVariable( dcx.builder, AutoVariableTag as u32, - context, name, filemd, + context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) }}; - + // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { Some(v) => v, @@ -594,30 +592,33 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { fmt!("No entry in lllocals table for %?", local.node.id)); } }; - + set_debug_location(bcx, loc.line, loc.col.to_uint()); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } - + return var_md; } pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { debug!("create_arg"); - let fcx = bcx.fcx, cx = *fcx.ccx; + if true { + // FIXME(5848) create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows + // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" + return None; + } + + let fcx = bcx.fcx; + let cx = *fcx.ccx; let dcx = dbg_cx(cx); let loc = span_start(cx, span); if "" == loc.file.name { return None; } - // FIXME: Disabled for now because "node_id_type(bcx, arg.id)" below blows up: - // "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" - // (same as https://github.com/mozilla/rust/issues/5848) - return None; - + let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); let filemd = create_file(cx, loc.file.name); @@ -629,12 +630,12 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, - ArgVariableTag as u32, context, name, + llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) // FIXME need to pass a real argument number }}; - + let llptr = fcx.llargs.get_copy(&arg.id); unsafe { llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, mdnode, bcx.llbb); @@ -652,7 +653,7 @@ fn set_debug_location(bcx: block, line: uint, col: uint) { let elems = ~[C_i32(line as i32), C_i32(col as i32), blockmd, ptr::null()]; unsafe { let dbg_loc = llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); - llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); + llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); } } @@ -660,13 +661,13 @@ pub fn update_source_pos(bcx: block, span: span) { if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } - + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); let cx = bcx.ccx(); let loc = span_start(cx, span); - let mut dcx = dbg_cx(cx); - + let dcx = dbg_cx(cx); + let loc = (loc.line, loc.col.to_uint()); if loc == dcx.curr_loc { return; @@ -678,7 +679,7 @@ pub fn update_source_pos(bcx: block, span: span) { pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let cx = *fcx.ccx; - let mut dcx = dbg_cx(cx); + let dcx = dbg_cx(cx); let fcx = &mut *fcx; let span = fcx.span.get(); @@ -705,7 +706,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - + match dcx.created_functions.find(&id) { Some(fn_md) => return *fn_md, None => () @@ -725,27 +726,27 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } else { ptr::null() }; - + let fn_ty = unsafe { llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, create_DIArray(dcx.builder, [ret_ty_md])) }; - - let fn_md = + + let fn_md = do as_c_str(cx.sess.str_of(ident)) |name| { do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { llvm::LLVMDIBuilderCreateFunction( - dcx.builder, - file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, - loc.line as c_uint, + dcx.builder, + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, FlagPrototyped as c_uint, - cx.sess.opts.optimize != session::No, + cx.sess.opts.optimize != session::No, fcx.llfn, ptr::null(), ptr::null()) }}}; - + dcx.created_functions.insert(id, fn_md); return fn_md; } From 65dd6218afe62fa36e701ceb27bd4e17ec764acc Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 12:23:42 -0700 Subject: [PATCH 53/96] Fixed remaining issues to pass debug-test/* tests. Made debugger scripts source line insensitive. --- src/librustc/lib/llvm.rs | 8 ++++++ src/librustc/middle/trans/debuginfo.rs | 36 ++++++++++++++++---------- src/rustllvm/RustWrapper.cpp | 11 ++++++++ src/rustllvm/rustllvm.def.in | 1 + src/test/debug-info/basic-types.rs | 9 ++++--- src/test/debug-info/box.rs | 9 ++++--- src/test/debug-info/struct.rs | 9 ++++--- src/test/debug-info/tuple.rs | 9 ++++--- src/test/debug-info/vec.rs | 9 ++++--- 9 files changed, 73 insertions(+), 28 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index d248627907ac..559db3f9b848 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2045,6 +2045,14 @@ pub mod llvm { AlwaysPreserve: bool, Flags: c_uint, ArgNo: c_uint) -> DIVariable; + + #[fast_ffi] + pub unsafe fn LLVMDIBuilderCreateArrayType( + Builder: DIBuilderRef, + Size: c_ulonglong, + AlignInBits: c_ulonglong, + Ty: DIType, + Subscripts: DIArray) -> DIType; #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateVectorType( diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index bbdfefaaa596..07aedf4b2c90 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -24,6 +24,7 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; +use core::cmp; use core::ptr; use core::str::as_c_str; use core::sys; @@ -204,8 +205,7 @@ fn create_block(bcx: block) -> DILexicalBlock { fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); - (machine::llsize_of_real(cx, llty), - machine::llalign_of_pref(cx, llty)) + (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ @@ -277,6 +277,7 @@ struct StructContext { impl StructContext { fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + debug!("StructContext::create: %s", name); let scx = ~StructContext { cx: cx, file: file, @@ -284,39 +285,48 @@ impl StructContext { line: line, members: ~[], total_size: 0, - align: 64 //XXX different alignment per arch? + align: 1 }; return scx; } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { + debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", self.name, name, size, align); + let offset = roundup(self.total_size, align); let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, self.total_size as u64, + size * 8 as u64, align * 8 as u64, offset * 8 as u64, 0, ty) }}; - // XXX What about member alignment??? self.members.push(mem_t); - self.total_size += size * 8; + self.total_size = offset + size; + // struct alignment is the max alignment of its' members + self.align = cmp::max(self.align, align); } fn finalize(&self) -> DICompositeType { + debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, ptr::null(), name, + dcx.builder, self.file, name, self.file, self.line as c_uint, - self.total_size as u64, self.align as u64, 0, ptr::null(), + self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), members_md, 0, ptr::null()) }}; return struct_md; } } +#[inline(always)] +fn roundup(x: uint, a: uint) -> uint { + ((x + (a - 1)) / a) * a +} + fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -390,12 +400,12 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { - llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; + llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, len as i64) }; let subscripts = create_DIArray(dcx.builder, [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - size * len as u64, align as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) }; } @@ -418,8 +428,8 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); let vec_md = vec_scx.finalize(); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index b7a67f984f73..6537e232f8b3 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -725,6 +725,17 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable( unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); } +extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType( + DIBuilderRef Builder, + uint64_t Size, + uint64_t AlignInBits, + LLVMValueRef Ty, + LLVMValueRef Subscripts) { + return wrap(Builder->createArrayType(Size, AlignInBits, + unwrapDI(Ty), + unwrapDI(Subscripts))); +} + extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType( DIBuilderRef Builder, uint64_t Size, diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index d1ed69feb04b..2a3f7de9bf5a 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -601,6 +601,7 @@ LLVMDIBuilderCreatePointerType LLVMDIBuilderCreateMemberType LLVMDIBuilderCreateStructType LLVMDIBuilderGetOrCreateSubrange +LLVMDIBuilderCreateArrayType LLVMDIBuilderCreateVectorType LLVMDIBuilderCreateSubroutineType LLVMDIBuilderGetOrCreateArray diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs index 20da6b557f18..616740c850c5 100644 --- a/src/test/debug-info/basic-types.rs +++ b/src/test/debug-info/basic-types.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values) // as its numerical value along with its associated ASCII char, there @@ -17,8 +17,9 @@ // its numerical value. // compile-flags:-Z extra-debug-info -// debugger:break 67 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print b // check:$1 = false // debugger:print i @@ -66,5 +67,7 @@ fn main() { let f: float = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; - let _z = (); + _zzz(); } + +fn _zzz() {()} diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs index 54aa0c12578b..3e5483ad75b3 100644 --- a/src/test/debug-info/box.rs +++ b/src/test/debug-info/box.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print a->boxed // check:$1 = 1 // debugger:print b->boxed @@ -28,5 +29,7 @@ fn main() { let b = ~(2, 3.5); let c = @4; let d = @false; - let _z = 0; + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/struct.rs b/src/test/debug-info/struct.rs index 16ba6cda5900..ddfac9cbeea8 100644 --- a/src/test/debug-info/struct.rs +++ b/src/test/debug-info/struct.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print pair // check:$1 = {x = 1, y = 2} // debugger:print pair.x @@ -28,5 +29,7 @@ struct Pair { fn main() { let pair = Pair { x: 1, y: 2 }; - let _z = (); + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/tuple.rs b/src/test/debug-info/tuple.rs index 35e2977f562e..a50996871cee 100644 --- a/src/test/debug-info/tuple.rs +++ b/src/test/debug-info/tuple.rs @@ -8,16 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 20 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print t // check:$1 = {4, 5.5, true} fn main() { let t = (4, 5.5, true); - let _z = (); + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index 3876f1c46d48..c87849ac4b6d 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print a // check:$1 = {1, 2, 3} // debugger:print b.vec[0] @@ -28,5 +29,7 @@ fn main() { let b = &[4, 5, 6]; let c = @[7, 8, 9]; let d = ~[10, 11, 12]; - let _z = 0; + _zzz(); } + +fn _zzz() {()} \ No newline at end of file From 51d82f572fe3e286f45b60a9594a2fafd286cb39 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 11 Jun 2013 18:06:38 -0700 Subject: [PATCH 54/96] Converted vec::map to member. --- src/compiletest/procsrv.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index b5404e38ec96..93fe258d167e 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -23,7 +23,7 @@ fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] { assert!(prog.ends_with(".exe")); let aux_path = prog.slice(0u, prog.len() - 4u).to_owned() + ".libaux"; - env = do vec::map(env) |pair| { + env = do env.map() |pair| { let (k,v) = copy *pair; if k == ~"PATH" { (~"PATH", v + ";" + lib_path + ";" + aux_path) } else { (k,v) } From 2b45591daf9edb09d95007ecc658ac6cbaa7ee8a Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 12:08:59 -0700 Subject: [PATCH 55/96] Made unimplemented debuginfo a note rather than a compiler error. --- src/librustc/middle/trans/debuginfo.rs | 28 +++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 07aedf4b2c90..12c774046d8b 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -482,6 +482,17 @@ fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t }; } +fn create_unimpl_ty(cx: @CrateContext, t: ty::t) -> DIType { + let dcx = dbg_cx(cx); + let name = ty_to_str(cx.tcx, t); + let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { + llvm::LLVMDIBuilderCreateBasicType( + dcx.builder, name, + 0_u64, 8_u64, DW_ATE_unsigned as c_uint) + }}; + return md; +} + fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); @@ -512,7 +523,8 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { } }, ty::ty_enum(_did, ref _substs) => { - cx.sess.span_bug(span, "debuginfo for enum NYI") + cx.sess.span_note(span, "debuginfo for enum NYI"); + create_unimpl_ty(cx, t) } ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => { let boxed = create_ty(cx, mt.ty, span); @@ -538,7 +550,8 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { create_pointer_type(cx, t, span, pointee) }, ty::ty_rptr(ref _region, ref _mt) => { - cx.sess.span_bug(span, "debuginfo for rptr NYI") + cx.sess.span_note(span, "debuginfo for rptr NYI"); + create_unimpl_ty(cx, t) }, ty::ty_bare_fn(ref barefnty) => { let inputs = barefnty.sig.inputs.map(|a| *a); @@ -546,10 +559,12 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { create_fn_ty(cx, t, inputs, output, span) }, ty::ty_closure(ref _closurety) => { - cx.sess.span_bug(span, "debuginfo for closure NYI") + cx.sess.span_note(span, "debuginfo for closure NYI"); + create_unimpl_ty(cx, t) }, ty::ty_trait(_did, ref _substs, ref _vstore, _) => { - cx.sess.span_bug(span, "debuginfo for trait NYI") + cx.sess.span_note(span, "debuginfo for trait NYI"); + create_unimpl_ty(cx, t) }, ty::ty_struct(did, ref substs) => { let fields = ty::struct_fields(cx.tcx, did, substs); @@ -572,7 +587,10 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let ident = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) - _ => fail!("no single variable name for local") + _ => { + bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI"); + return ptr::null(); + } }; let name: &str = cx.sess.str_of(ident); debug!("create_local_var: %s", name); From 1e682e29eb8f5ddaf36e6374f46d8d8ac364d824 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 11:59:49 -0700 Subject: [PATCH 56/96] Refactoring and tidy warnings cleanup. --- src/librustc/lib/llvm.rs | 11 +-- src/librustc/middle/trans/base.rs | 8 ++- src/librustc/middle/trans/debuginfo.rs | 99 +++++++++++++------------- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 559db3f9b848..c00bb390edd2 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -225,12 +225,11 @@ pub enum Pass_opaque {} pub type PassRef = *Pass_opaque; pub mod debuginfo { - use core::prelude::*; use super::{ValueRef}; - + pub enum DIBuilder_opaque {} pub type DIBuilderRef = *DIBuilder_opaque; - + pub type DIDescriptor = ValueRef; pub type DIScope = DIDescriptor; pub type DILocation = DIDescriptor; @@ -295,6 +294,8 @@ pub mod llvm { pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; #[fast_ffi] pub unsafe fn LLVMDisposeModule(M: ModuleRef); + #[fast_ffi] + pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; /** Data layout. See Module::getDataLayout. */ #[fast_ffi] @@ -2045,14 +2046,14 @@ pub mod llvm { AlwaysPreserve: bool, Flags: c_uint, ArgNo: c_uint) -> DIVariable; - + #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateArrayType( Builder: DIBuilderRef, Size: c_ulonglong, AlignInBits: c_ulonglong, Ty: DIType, - Subscripts: DIArray) -> DIType; + Subscripts: DIArray) -> DIType; #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateVectorType( diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index ddc8207dfe04..467185f007e5 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1908,7 +1908,11 @@ pub fn trans_closure(ccx: @mut CrateContext, finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); - unsafe { llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); } + // Put return block after all other blocks. + // This somewhat improves single-stepping experience in debugger. + unsafe { + llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); + } // Insert the mandatory first few basic blocks before lltop. finish_fn(fcx, lltop); @@ -3108,7 +3112,7 @@ pub fn trans_crate(sess: session::Session, if ccx.sess.opts.debuginfo { debuginfo::finalize(ccx); } - + // Translate the metadata. write_metadata(ccx, crate); if ccx.sess.trans_stats() { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 12c774046d8b..1f8b75d9e77d 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -32,9 +32,7 @@ use core::vec; use syntax::codemap::span; use syntax::{ast, codemap, ast_util, ast_map}; -static LLVMDebugVersion: int = (12 << 16); - -static DW_LANG_RUST: int = 12; //0x9000; +static DW_LANG_RUST: int = 0x9000; static CompileUnitTag: int = 17; static FileDescriptorTag: int = 41; @@ -65,6 +63,7 @@ pub type DebugContext = @mut _DebugContext; struct _DebugContext { names: namegen, crate_file: ~str, + llcontext: ContextRef, builder: DIBuilderRef, curr_loc: (uint, uint), created_files: HashMap<~str, DIFile>, @@ -73,13 +72,16 @@ struct _DebugContext { created_types: HashMap } -/** Create new DebugContext */ +/// Create new DebugContext pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { debug!("mk_ctxt"); let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; + // DIBuilder inherits context from the module, so we'd better use the same one + let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; let dcx = @mut _DebugContext { names: new_namegen(), crate_file: crate, + llcontext: llcontext, builder: builder, curr_loc: (0, 0), created_files: HashMap::new(), @@ -91,18 +93,11 @@ pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { } #[inline(always)] -fn dbg_cx(cx: &CrateContext) -> DebugContext -{ +fn dbg_cx(cx: &CrateContext) -> DebugContext { return cx.dbg_cx.get(); } -fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { - return unsafe { - llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) - }; -} - -/** Create any deferred debug metadata nodes */ +/// Create any deferred debug metadata nodes pub fn finalize(cx: @CrateContext) { debug!("finalize"); create_compile_unit(cx); @@ -113,6 +108,12 @@ pub fn finalize(cx: @CrateContext) { }; } +fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { + return unsafe { + llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + }; +} + fn create_compile_unit(cx: @CrateContext) { let crate_name: &str = dbg_cx(cx).crate_file; let work_dir = cx.sess.working_dir.to_str(); @@ -158,6 +159,7 @@ fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { return file_md; } +/// Return codemap::Loc corresponding to the beginning of the span fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { return cx.sess.codemap.lookup_char_pos(span.lo); } @@ -208,7 +210,7 @@ fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } -fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ +fn create_basic_type(cx: @CrateContext, t: ty::t, _span: span) -> DIType{ let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); match dcx.created_types.find(&ty_id) { @@ -255,7 +257,7 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ return ty_md; } -fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) -> DIType { +fn create_pointer_type(cx: @CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { @@ -291,7 +293,8 @@ impl StructContext { } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { - debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", self.name, name, size, align); + debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", + self.name, name, size, align); let offset = roundup(self.total_size, align); let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, @@ -306,7 +309,8 @@ impl StructContext { } fn finalize(&self) -> DICompositeType { - debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); + debug!("StructContext(%s)::finalize: total_size=%u, align=%u", + self.name, self.total_size, self.align); let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); @@ -323,8 +327,8 @@ impl StructContext { } #[inline(always)] -fn roundup(x: uint, a: uint) -> uint { - ((x + (a - 1)) / a) * a +fn roundup(x: uint, a: uint) -> uint { + ((x + (a - 1)) / a) * a } fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { @@ -353,7 +357,7 @@ fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { return (vp, size, align); } -fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { +fn create_tuple(cx: @CrateContext, _t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { let dcx = dbg_cx(cx); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -391,12 +395,10 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, return scx.finalize(); } -fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, +fn create_fixed_vec(cx: @CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); - let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { @@ -465,7 +467,7 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) return scx.finalize(); } -fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, +fn create_fn_ty(cx: @CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { let dcx = dbg_cx(cx); let loc = span_start(cx, span); @@ -487,7 +489,7 @@ fn create_unimpl_ty(cx: @CrateContext, t: ty::t) -> DIType { let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + dcx.builder, name, 0_u64, 8_u64, DW_ATE_unsigned as c_uint) }}; return md; @@ -621,7 +623,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { } }; - set_debug_location(bcx, loc.line, loc.col.to_uint()); + set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); @@ -633,7 +635,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { debug!("create_arg"); if true { - // FIXME(5848) create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows + // XXX create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" return None; } @@ -661,12 +663,15 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) - // FIXME need to pass a real argument number + // XXX need to pass in a real argument number }}; let llptr = fcx.llargs.get_copy(&arg.id); + set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { - llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, mdnode, bcx.llbb); + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( + dcx.builder, llptr, mdnode, bcx.llbb); + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } return Some(mdnode); } @@ -676,33 +681,31 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { } } -fn set_debug_location(bcx: block, line: uint, col: uint) { - let blockmd = create_block(bcx); - let elems = ~[C_i32(line as i32), C_i32(col as i32), blockmd, ptr::null()]; +fn set_debug_location(cx: @CrateContext, scope: DIScope, line: uint, col: uint) { + let dcx = dbg_cx(cx); + if dcx.curr_loc == (line, col) { + return; + } + debug!("setting debug location to %u %u", line, col); + dcx.curr_loc = (line, col); + + let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { - let dbg_loc = llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); - llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); + let dbg_loc = llvm::LLVMMDNodeInContext( + dcx.llcontext, vec::raw::to_ptr(elems), + elems.len() as libc::c_uint); + llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc); } } +/// Set current debug location at the beginning of the span pub fn update_source_pos(bcx: block, span: span) { if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } - debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); - - let cx = bcx.ccx(); - let loc = span_start(cx, span); - let dcx = dbg_cx(cx); - - let loc = (loc.line, loc.col.to_uint()); - if loc == dcx.curr_loc { - return; - } - debug!("setting_location to %u %u", loc.first(), loc.second()); - dcx.curr_loc = loc; - set_debug_location(bcx, loc.first(), loc.second()); + let loc = span_start(bcx.ccx(), span); + set_debug_location(bcx.ccx(), create_block(bcx), loc.line, loc.col.to_uint()) } pub fn create_function(fcx: fn_ctxt) -> DISubprogram { From adff46250ed9e9b3c31da65b2997a5458e41305a Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 17 Jun 2013 08:42:05 -0700 Subject: [PATCH 57/96] Fixed rebase fallout . --- src/librustc/lib/llvm.rs | 2 - src/librustc/middle/trans/base.rs | 7 +- src/librustc/middle/trans/context.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 237 ++++++++++++------------- src/rustllvm/RustWrapper.cpp | 4 +- 5 files changed, 122 insertions(+), 130 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index c00bb390edd2..835dd55711b5 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -294,8 +294,6 @@ pub mod llvm { pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; #[fast_ffi] pub unsafe fn LLVMDisposeModule(M: ModuleRef); - #[fast_ffi] - pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; /** Data layout. See Module::getDataLayout. */ #[fast_ffi] diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 467185f007e5..55fc22a8fcc0 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3080,7 +3080,6 @@ pub fn trans_crate(sess: session::Session, // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = link_meta.name.to_owned() + ".rc"; - Some(debuginfo::mk_ctxt(llmod, copy llmod_id)) // FIXME(#6511): get LLVM building with --enable-threads so this // function can be called // if !llvm::LLVMRustStartMultithreading() { @@ -3109,9 +3108,9 @@ pub fn trans_crate(sess: session::Session, fill_crate_map(ccx, ccx.crate_map); glue::emit_tydescs(ccx); write_abi_version(ccx); - if ccx.sess.opts.debuginfo { - debuginfo::finalize(ccx); - } + if ccx.sess.opts.debuginfo { + debuginfo::finalize(ccx); + } // Translate the metadata. write_metadata(ccx, crate); diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 75d7aaa88a6d..7aab1d0239e6 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -148,7 +148,7 @@ impl CrateContext { lib::llvm::associate_type(tn, @"tydesc", tydesc_type); let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { - Some(debuginfo::mk_ctxt(name.to_owned())) + Some(debuginfo::DebugContext::new(llmod, name.to_owned())) } else { None }; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 1f8b75d9e77d..91e3276d8aa6 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -58,9 +58,7 @@ static DW_ATE_unsigned_char: int = 0x08; //////////////// -pub type DebugContext = @mut _DebugContext; - -struct _DebugContext { +pub struct DebugContext { names: namegen, crate_file: ~str, llcontext: ContextRef, @@ -72,39 +70,43 @@ struct _DebugContext { created_types: HashMap } -/// Create new DebugContext -pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { - debug!("mk_ctxt"); - let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; - // DIBuilder inherits context from the module, so we'd better use the same one - let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; - let dcx = @mut _DebugContext { - names: new_namegen(), - crate_file: crate, - llcontext: llcontext, - builder: builder, - curr_loc: (0, 0), - created_files: HashMap::new(), - created_functions: HashMap::new(), - created_blocks: HashMap::new(), - created_types: HashMap::new(), - }; - return dcx; +impl DebugContext { + pub fn new(llmod: ModuleRef, crate: ~str) -> DebugContext { + debug!("DebugContext::new"); + let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; + // DIBuilder inherits context from the module, so we'd better use the same one + let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; + return DebugContext { + names: new_namegen(), + crate_file: crate, + llcontext: llcontext, + builder: builder, + curr_loc: (0, 0), + created_files: HashMap::new(), + created_functions: HashMap::new(), + created_blocks: HashMap::new(), + created_types: HashMap::new(), + }; + } } -#[inline(always)] -fn dbg_cx(cx: &CrateContext) -> DebugContext { - return cx.dbg_cx.get(); +#[inline] +fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext { + cx.dbg_cx.get_mut_ref() +} + +#[inline] +fn DIB(cx: &CrateContext) -> DIBuilderRef { + cx.dbg_cx.get_ref().builder } /// Create any deferred debug metadata nodes -pub fn finalize(cx: @CrateContext) { +pub fn finalize(cx: @mut CrateContext) { debug!("finalize"); create_compile_unit(cx); - let dcx = dbg_cx(cx); unsafe { - llvm::LLVMDIBuilderFinalize(dcx.builder); - llvm::LLVMDIBuilderDispose(dcx.builder); + llvm::LLVMDIBuilderFinalize(DIB(cx)); + llvm::LLVMDIBuilderDispose(DIB(cx)); }; } @@ -114,8 +116,9 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { }; } -fn create_compile_unit(cx: @CrateContext) { - let crate_name: &str = dbg_cx(cx).crate_file; +fn create_compile_unit(cx: @mut CrateContext) { + let dcx = dbg_cx(cx); + let crate_name: &str = dcx.crate_file; let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); @@ -124,17 +127,15 @@ fn create_compile_unit(cx: @CrateContext) { do as_c_str(producer) |producer| { do as_c_str("") |flags| { do as_c_str("") |split_name| { unsafe { - llvm::LLVMDIBuilderCreateCompileUnit(dbg_cx(cx).builder, + llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder, DW_LANG_RUST as c_uint, crate_name, work_dir, producer, cx.sess.opts.optimize != session::No, flags, 0, split_name); }}}}}}; } -fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { - let dcx = dbg_cx(cx); - - match dcx.created_files.find_equiv(&full_path) { +fn create_file(cx: @mut CrateContext, full_path: &str) -> DIFile { + match dbg_cx(cx).created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } @@ -152,22 +153,21 @@ fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { let file_md = do as_c_str(file_name) |file_name| { do as_c_str(work_dir) |work_dir| { unsafe { - llvm::LLVMDIBuilderCreateFile(dcx.builder, file_name, work_dir) + llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir) }}}; - dcx.created_files.insert(full_path.to_owned(), file_md); + dbg_cx(cx).created_files.insert(full_path.to_owned(), file_md); return file_md; } /// Return codemap::Loc corresponding to the beginning of the span -fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { +fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { return cx.sess.codemap.lookup_char_pos(span.lo); } fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; let cx = bcx.ccx(); - let dcx = dbg_cx(cx); while bcx.node_info.is_none() { match bcx.parent { @@ -178,7 +178,7 @@ fn create_block(bcx: block) -> DILexicalBlock { let span = bcx.node_info.get().span; let id = bcx.node_info.get().id; - match dcx.created_blocks.find(&id) { + match dbg_cx(cx).created_blocks.find(&id) { Some(block) => return *block, None => () } @@ -195,25 +195,24 @@ fn create_block(bcx: block) -> DILexicalBlock { let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( - dcx.builder, + DIB(cx), parent, file_md, loc.line as c_uint, loc.col.to_uint() as c_uint) }; - dcx.created_blocks.insert(id, block_md); + dbg_cx(cx).created_blocks.insert(id, block_md); return block_md; } -fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { +fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } -fn create_basic_type(cx: @CrateContext, t: ty::t, _span: span) -> DIType{ - let dcx = dbg_cx(cx); +fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { let ty_id = ty::type_id(t); - match dcx.created_types.find(&ty_id) { + match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } @@ -249,26 +248,26 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, _span: span) -> DIType{ let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + DIB(cx), name, size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; - dcx.created_types.insert(ty_id, ty_md); + dbg_cx(cx).created_types.insert(ty_id, ty_md); return ty_md; } -fn create_pointer_type(cx: @CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { +fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, + llvm::LLVMDIBuilderCreatePointerType(DIB(cx), pointee, size * 8 as u64, align * 8 as u64, name) }}; return ptr_md; } struct StructContext { - cx: @CrateContext, + builder: DIBuilderRef, file: DIFile, name: ~str, line: uint, @@ -278,10 +277,10 @@ struct StructContext { } impl StructContext { - fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> ~StructContext { debug!("StructContext::create: %s", name); let scx = ~StructContext { - cx: cx, + builder: DIB(cx), file: file, name: name, line: line, @@ -297,8 +296,8 @@ impl StructContext { self.name, name, size, align); let offset = roundup(self.total_size, align); let mem_t = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, - ptr::null(), name, self.file, line as c_uint, + llvm::LLVMDIBuilderCreateMemberType( + self.builder, ptr::null(), name, self.file, line as c_uint, size * 8 as u64, align * 8 as u64, offset * 8 as u64, 0, ty) }}; @@ -311,13 +310,12 @@ impl StructContext { fn finalize(&self) -> DICompositeType { debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); - let dcx = dbg_cx(self.cx); - let members_md = create_DIArray(dcx.builder, self.members); + let members_md = create_DIArray(self.builder, self.members); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, self.file, name, + self.builder, self.file, name, self.file, self.line as c_uint, self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), members_md, 0, ptr::null()) @@ -326,45 +324,44 @@ impl StructContext { } } -#[inline(always)] +#[inline] fn roundup(x: uint, a: uint) -> uint { ((x + (a - 1)) / a) * a } -fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { +fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: span) + -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), loc.line); + let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, t), file_md, loc.line); for fields.each |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); - scx.add_member(cx.sess.str_of(field.ident), - loc.line, size, align, ty_md); + scx.add_member(cx.sess.str_of(field.ident), loc.line, size, align, ty_md); } return scx.finalize(); } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { +fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), + llvm::LLVMDIBuilderCreatePointerType(DIB(cx), ptr::null(), size*8 as u64, align*8 as u64, name) }}; return (vp, size, align); } -fn create_tuple(cx: @CrateContext, _t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { - let dcx = dbg_cx(cx); +fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span) + -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); - let mut scx = StructContext::create(cx, file_md, name, loc.line); - + let name = (cx.sess.str_of((dbg_cx(cx).names)("tuple"))).to_owned(); + let mut scx = StructContext::new(cx, name, file_md, loc.line); for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); @@ -373,7 +370,7 @@ fn create_tuple(cx: @CrateContext, _t: ty::t, elements: &[ty::t], span: span) -> return scx.finalize(); } -fn create_boxed_type(cx: @CrateContext, contents: ty::t, +fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -381,7 +378,7 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); + let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); // the tydesc and other pointers should be irrelevant to the @@ -395,48 +392,50 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, return scx.finalize(); } -fn create_fixed_vec(cx: @CrateContext, _vec_t: ty::t, elem_t: ty::t, +fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { - let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { - llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, len as i64) }; + llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, len as i64) + }; - let subscripts = create_DIArray(dcx.builder, [subrange]); + let subscripts = create_DIArray(DIB(cx), [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + llvm::LLVMDIBuilderCreateArrayType(DIB(cx), size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) }; } -fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, +fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: span) -> DICompositeType { - let dcx = dbg_cx(cx); let loc = span_start(cx, vec_ty_span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - + let mut vec_scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); vec_scx.add_member("fill", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); vec_scx.add_member("alloc", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); - let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, 0_i64) }; + let subrange = unsafe { + llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, 0_i64) + }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateArrayType(dcx.builder, - arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) }; + let subscripts = create_DIArray(DIB(cx), [subrange]); + let data_ptr = unsafe { + llvm::LLVMDIBuilderCreateArrayType(DIB(cx), + arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) + }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); let vec_md = vec_scx.finalize(); - let mut box_scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); + let mut box_scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, vec_ty_span); box_scx.add_member("refcnt", 0, sys::size_of::(), @@ -452,24 +451,24 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, return mdval; } -fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { +fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) + -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); + let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); scx.add_member("length", 0, sys::size_of::(), - sys::min_align_of::(), uint_type); + sys::min_align_of::(), uint_type); return scx.finalize(); } -fn create_fn_ty(cx: @CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, +fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { - let dcx = dbg_cx(cx); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); @@ -479,26 +478,24 @@ fn create_fn_ty(cx: @CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty:: let members = ~[output_ptr_md, vp] + inputs_vals; return unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, - create_DIArray(dcx.builder, members)) + llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_md, + create_DIArray(DIB(cx), members)) }; } -fn create_unimpl_ty(cx: @CrateContext, t: ty::t) -> DIType { - let dcx = dbg_cx(cx); +fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + DIB(cx), name, 0_u64, 8_u64, DW_ATE_unsigned as c_uint) }}; return md; } -fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { - let dcx = dbg_cx(cx); +fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { let ty_id = ty::type_id(t); - match dcx.created_types.find(&ty_id) { + match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } @@ -578,13 +575,12 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") }; - dcx.created_types.insert(ty_id, ty_md); + dbg_cx(cx).created_types.insert(ty_id, ty_md); return ty_md; } pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let cx = bcx.ccx(); - let dcx = dbg_cx(cx); let ident = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), @@ -608,7 +604,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let var_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateLocalVariable( - dcx.builder, AutoVariableTag as u32, + DIB(cx), AutoVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) }}; @@ -625,7 +621,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { - let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_md, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } @@ -641,8 +637,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { } let fcx = bcx.fcx; - let cx = *fcx.ccx; - let dcx = dbg_cx(cx); + let cx = fcx.ccx; let loc = span_start(cx, span); if "" == loc.file.name { @@ -652,7 +647,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); let filemd = create_file(cx, loc.file.name); - let context = create_function(bcx.fcx); + let context = create_function(fcx); match arg.pat.node { ast::pat_ident(_, path, _) => { @@ -660,7 +655,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx), ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) // XXX need to pass in a real argument number @@ -670,7 +665,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( - dcx.builder, llptr, mdnode, bcx.llbb); + DIB(cx), llptr, mdnode, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } return Some(mdnode); @@ -681,18 +676,17 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { } } -fn set_debug_location(cx: @CrateContext, scope: DIScope, line: uint, col: uint) { - let dcx = dbg_cx(cx); - if dcx.curr_loc == (line, col) { +fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: uint) { + if dbg_cx(cx).curr_loc == (line, col) { return; } debug!("setting debug location to %u %u", line, col); - dcx.curr_loc = (line, col); + dbg_cx(cx).curr_loc = (line, col); let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { let dbg_loc = llvm::LLVMMDNodeInContext( - dcx.llcontext, vec::raw::to_ptr(elems), + dbg_cx(cx).llcontext, vec::raw::to_ptr(elems), elems.len() as libc::c_uint); llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc); } @@ -709,8 +703,7 @@ pub fn update_source_pos(bcx: block, span: span) { } pub fn create_function(fcx: fn_ctxt) -> DISubprogram { - let cx = *fcx.ccx; - let dcx = dbg_cx(cx); + let cx = fcx.ccx; let fcx = &mut *fcx; let span = fcx.span.get(); @@ -729,7 +722,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - ((dcx.names)("fn"), decl.output, expr.id) + ((dbg_cx(cx).names)("fn"), decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") @@ -738,7 +731,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - match dcx.created_functions.find(&id) { + match dbg_cx(cx).created_functions.find(&id) { Some(fn_md) => return *fn_md, None => () } @@ -759,15 +752,15 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { }; let fn_ty = unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, - file_md, create_DIArray(dcx.builder, [ret_ty_md])) - }; + llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), + file_md, create_DIArray(DIB(cx), [ret_ty_md])) + }; let fn_md = do as_c_str(cx.sess.str_of(ident)) |name| { do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { llvm::LLVMDIBuilderCreateFunction( - dcx.builder, + DIB(cx), file_md, name, linkage, file_md, loc.line as c_uint, @@ -778,6 +771,6 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { fcx.llfn, ptr::null(), ptr::null()) }}}; - dcx.created_functions.insert(id, fn_md); + dbg_cx(cx).created_functions.insert(id, fn_md); return fn_md; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 6537e232f8b3..614c1723c5fb 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -565,7 +565,9 @@ extern "C" bool LLVMRustStartMultithreading() { typedef DIBuilder* DIBuilderRef; template -DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } +DIT unwrapDI(LLVMValueRef ref) { + return DIT(ref ? unwrap(ref) : NULL); +} extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) { return new DIBuilder(*unwrap(M)); From 6914ff9d0142a4b1e82f809ebb8de805d8319698 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 13 Jun 2013 10:07:34 -0700 Subject: [PATCH 58/96] rustc: map node ids through a table that ensures bitset indexes in dataflow are dense --- src/librustc/middle/borrowck/check_loans.rs | 4 +- src/librustc/middle/borrowck/move_data.rs | 4 +- src/librustc/middle/dataflow.rs | 93 ++++++++++++++++----- 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index e384d35373e6..be87beba7784 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -82,7 +82,7 @@ impl<'self> CheckLoanCtxt<'self> { //! are issued for future scopes and thus they may have been //! *issued* but not yet be in effect. - for self.dfcx_loans.each_bit_on_entry(scope_id) |loan_index| { + for self.dfcx_loans.each_bit_on_entry_frozen(scope_id) |loan_index| { let loan = &self.all_loans[loan_index]; if !op(loan) { return false; @@ -134,7 +134,7 @@ impl<'self> CheckLoanCtxt<'self> { //! we encounter `scope_id`. let mut result = ~[]; - for self.dfcx_loans.each_gen_bit(scope_id) |loan_index| { + for self.dfcx_loans.each_gen_bit_frozen(scope_id) |loan_index| { result.push(loan_index); } return result; diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index bd560fca9854..d19afd0f5fc9 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -504,7 +504,7 @@ impl FlowedMoveData { let opt_loan_path_index = self.move_data.existing_move_path(loan_path); - for self.dfcx_moves.each_bit_on_entry(id) |index| { + for self.dfcx_moves.each_bit_on_entry_frozen(id) |index| { let move = &self.move_data.moves[index]; let moved_path = move.path; if base_indices.contains(&moved_path) { @@ -560,7 +560,7 @@ impl FlowedMoveData { } }; - for self.dfcx_assign.each_bit_on_entry(id) |index| { + for self.dfcx_assign.each_bit_on_entry_frozen(id) |index| { let assignment = &self.move_data.var_assignments[index]; if assignment.path == loan_path_index && !f(assignment) { return false; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 8037bacd3e72..8403b1616f41 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -22,6 +22,7 @@ use core::cast; use core::io; use core::uint; use core::vec; +use core::hashmap::HashMap; use syntax::ast; use syntax::ast_util; use syntax::ast_util::id_range; @@ -37,9 +38,6 @@ pub struct DataFlowContext { /// the data flow operator priv oper: O, - /// range of ids that appear within the item in question - priv id_range: id_range, - /// number of bits to propagate per id priv bits_per_id: uint, @@ -47,6 +45,9 @@ pub struct DataFlowContext { /// equal to bits_per_id/uint::bits rounded up. priv words_per_id: uint, + // mapping from node to bitset index. + priv nodeid_to_bitset: HashMap, + // Bit sets per id. The following three fields (`gens`, `kills`, // and `on_entry`) all have the same structure. For each id in // `id_range`, there is a range of words equal to `words_per_id`. @@ -108,19 +109,17 @@ impl DataFlowContext { debug!("DataFlowContext::new(id_range=%?, bits_per_id=%?, words_per_id=%?)", id_range, bits_per_id, words_per_id); - let len = (id_range.max - id_range.min) as uint * words_per_id; - let gens = vec::from_elem(len, 0); - let kills = vec::from_elem(len, 0); - let elem = if oper.initial_value() {uint::max_value} else {0}; - let on_entry = vec::from_elem(len, elem); + let gens = ~[]; + let kills = ~[]; + let on_entry = ~[]; DataFlowContext { tcx: tcx, method_map: method_map, words_per_id: words_per_id, + nodeid_to_bitset: HashMap::new(), bits_per_id: bits_per_id, oper: oper, - id_range: id_range, gens: gens, kills: kills, on_entry: on_entry @@ -149,7 +148,7 @@ impl DataFlowContext { } } - fn apply_gen_kill(&self, id: ast::node_id, bits: &mut [uint]) { + fn apply_gen_kill(&mut self, id: ast::node_id, bits: &mut [uint]) { //! Applies the gen and kill sets for `id` to `bits` debug!("apply_gen_kill(id=%?, bits=%s) [before]", @@ -164,7 +163,7 @@ impl DataFlowContext { id, mut_bits_to_str(bits)); } - fn apply_kill(&self, id: ast::node_id, bits: &mut [uint]) { + fn apply_kill(&mut self, id: ast::node_id, bits: &mut [uint]) { debug!("apply_kill(id=%?, bits=%s) [before]", id, mut_bits_to_str(bits)); let (start, end) = self.compute_id_range(id); @@ -174,18 +173,56 @@ impl DataFlowContext { id, mut_bits_to_str(bits)); } - fn compute_id_range(&self, absolute_id: ast::node_id) -> (uint, uint) { - assert!(absolute_id >= self.id_range.min); - assert!(absolute_id < self.id_range.max); - - let relative_id = absolute_id - self.id_range.min; - let start = (relative_id as uint) * self.words_per_id; + fn compute_id_range_frozen(&self, id: ast::node_id) -> (uint, uint) { + let n = *self.nodeid_to_bitset.get(&id); + let start = n * self.words_per_id; let end = start + self.words_per_id; (start, end) } + fn compute_id_range(&mut self, id: ast::node_id) -> (uint, uint) { + let mut expanded = false; + let len = self.nodeid_to_bitset.len(); + let n = do self.nodeid_to_bitset.find_or_insert_with(id) |_| { + expanded = true; + len + }; + if expanded { + let entry = if self.oper.initial_value() { uint::max_value } else {0}; + for self.words_per_id.times { + self.gens.push(0); + self.kills.push(0); + self.on_entry.push(entry); + } + } + let start = *n * self.words_per_id; + let end = start + self.words_per_id; - pub fn each_bit_on_entry(&self, + assert!(start < self.gens.len()); + assert!(end <= self.gens.len()); + assert!(self.gens.len() == self.kills.len()); + assert!(self.gens.len() == self.on_entry.len()); + + (start, end) + } + + + pub fn each_bit_on_entry_frozen(&self, + id: ast::node_id, + f: &fn(uint) -> bool) -> bool { + //! Iterates through each bit that is set on entry to `id`. + //! Only useful after `propagate()` has been called. + if !self.nodeid_to_bitset.contains_key(&id) { + return true; + } + let (start, end) = self.compute_id_range_frozen(id); + let on_entry = vec::slice(self.on_entry, start, end); + debug!("each_bit_on_entry_frozen(id=%?, on_entry=%s)", + id, bits_to_str(on_entry)); + self.each_bit(on_entry, f) + } + + pub fn each_bit_on_entry(&mut self, id: ast::node_id, f: &fn(uint) -> bool) -> bool { //! Iterates through each bit that is set on entry to `id`. @@ -198,7 +235,7 @@ impl DataFlowContext { self.each_bit(on_entry, f) } - pub fn each_gen_bit(&self, + pub fn each_gen_bit(&mut self, id: ast::node_id, f: &fn(uint) -> bool) -> bool { //! Iterates through each bit in the gen set for `id`. @@ -210,6 +247,20 @@ impl DataFlowContext { self.each_bit(gens, f) } + pub fn each_gen_bit_frozen(&self, + id: ast::node_id, + f: &fn(uint) -> bool) -> bool { + //! Iterates through each bit in the gen set for `id`. + if !self.nodeid_to_bitset.contains_key(&id) { + return true; + } + let (start, end) = self.compute_id_range_frozen(id); + let gens = vec::slice(self.gens, start, end); + debug!("each_gen_bit(id=%?, gens=%s)", + id, bits_to_str(gens)); + self.each_bit(gens, f) + } + fn each_bit(&self, words: &[uint], f: &fn(uint) -> bool) -> bool { @@ -285,8 +336,8 @@ impl DataFlowContext { pprust::node_pat(ps, pat) => (ps, pat.id) }; - if id >= self.id_range.min || id < self.id_range.max { - let (start, end) = self.compute_id_range(id); + if self.nodeid_to_bitset.contains_key(&id) { + let (start, end) = self.compute_id_range_frozen(id); let on_entry = vec::slice(self.on_entry, start, end); let entry_str = bits_to_str(on_entry); From fd09e40f970d996174d87d9feea9953e093368a5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 16 Jun 2013 15:41:33 -0700 Subject: [PATCH 59/96] Revert "stop using an absolute rpath" This reverts commit 708395d65d689080cc96dd091adab3fc4c5c3f27. --- src/librustc/back/rpath.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 33f578d335b0..ed70f41f3ec8 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -77,6 +77,10 @@ fn get_rpaths(os: session::os, // crates they depend on. let rel_rpaths = get_rpaths_relative_to_output(os, output, libs); + // Make backup absolute paths to the libraries. Binaries can + // be moved as long as the crates they link against don't move. + let abs_rpaths = get_absolute_rpaths(libs); + // And a final backup rpath to the global library location. let fallback_rpaths = ~[get_install_prefix_rpath(target_triple)]; @@ -88,9 +92,11 @@ fn get_rpaths(os: session::os, } log_rpaths("relative", rel_rpaths); + log_rpaths("absolute", abs_rpaths); log_rpaths("fallback", fallback_rpaths); let mut rpaths = rel_rpaths; + rpaths.push_all(abs_rpaths); rpaths.push_all(fallback_rpaths); // Remove duplicates @@ -160,6 +166,14 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { } } +fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] { + vec::map(libs, |a| get_absolute_rpath(a) ) +} + +pub fn get_absolute_rpath(lib: &Path) -> Path { + os::make_absolute(lib).dir_path() +} + #[cfg(stage0)] pub fn get_install_prefix_rpath(target_triple: &str) -> Path { let install_prefix = env!("CFG_PREFIX"); @@ -198,12 +212,13 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { #[cfg(unix, test)] mod test { use core::prelude::*; + use core::os; // FIXME(#2119): the outer attribute should be #[cfg(unix, test)], then // these redundant #[cfg(test)] blocks can be removed #[cfg(test)] #[cfg(test)] - use back::rpath::{get_install_prefix_rpath}; + use back::rpath::{get_absolute_rpath, get_install_prefix_rpath}; use back::rpath::{get_relative_to, get_rpath_relative_to_output}; use back::rpath::{minimize_rpaths, rpaths_to_flags}; use driver::session; @@ -347,4 +362,14 @@ mod test { &Path("lib/libstd.so")); assert_eq!(res.to_str(), ~"@executable_path/../lib"); } + + #[test] + fn test_get_absolute_rpath() { + let res = get_absolute_rpath(&Path("lib/libstd.so")); + debug!("test_get_absolute_rpath: %s vs. %s", + res.to_str(), + os::make_absolute(&Path("lib")).to_str()); + + assert_eq!(res, os::make_absolute(&Path("lib"))); + } } From 371a316ec93a977f9dcd305b5f532cd394fa6885 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 18 Jun 2013 12:03:14 -0700 Subject: [PATCH 60/96] Turn off jemalloc --- mk/rt.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mk/rt.mk b/mk/rt.mk index 1c498aacdddc..da950dffab5b 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -158,10 +158,10 @@ rt/$(1)/stage$(2)/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJ_$(1)_$(2)) $$(Q)$(AR_$(1)) rcs $$@ $$< rt/$(1)/stage$(2)/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS) \ - $$(RUNTIME_DEF_$(1)_$(2)) $$(LIBUV_LIB_$(1)_$(2)) $$(JEMALLOC_LIB_$(1)_$(2)) + $$(RUNTIME_DEF_$(1)_$(2)) $$(LIBUV_LIB_$(1)_$(2)) @$$(call E, link: $$@) $$(Q)$$(call CFG_LINK_CXX_$(1),$$@, $$(RUNTIME_OBJS_$(1)_$(2)) \ - $$(JEMALLOC_LIB_$(1)_$(2)) $$(CFG_GCCISH_POST_LIB_FLAGS_$(1)) $$(LIBUV_LIB_$(1)_$(2)) \ + $$(CFG_GCCISH_POST_LIB_FLAGS_$(1)) $$(LIBUV_LIB_$(1)_$(2)) \ $$(CFG_LIBUV_LINK_FLAGS_$(1)),$$(RUNTIME_DEF_$(1)_$(2)),$$(CFG_RUNTIME_$(1))) # FIXME: For some reason libuv's makefiles can't figure out the From 303d7bfc87ca370354ac4264cc23a80cbcd8a792 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 18 Jun 2013 13:29:31 -0700 Subject: [PATCH 61/96] test: xfail bench/task-perf-one-million. OOM on 32-bit linux w/o opts --- src/test/bench/task-perf-one-million.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index e1a5253444f8..e1366a3a8694 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -10,6 +10,8 @@ // Test for concurrent tasks +// xfail-test OOM on linux-32 without opts + use std::comm::*; use std::os; use std::task; From d904c72af830bd4bec773ce35897703dff2ee3b1 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 18 Jun 2013 14:45:18 -0700 Subject: [PATCH 62/96] replace #[inline(always)] with #[inline]. r=burningtree. --- src/libextra/arc.rs | 22 +- src/libextra/arena.rs | 16 +- src/libextra/bitv.rs | 82 +++---- src/libextra/dlist.rs | 4 +- src/libextra/num/complex.rs | 4 +- src/libextra/num/rational.rs | 10 +- src/libextra/rc.rs | 2 +- src/libextra/semver.rs | 20 +- src/libextra/sort.rs | 4 +- src/libextra/sync.rs | 2 +- src/libextra/treemap.rs | 50 ++-- src/libextra/workcache.rs | 2 +- src/librustc/back/passes.rs | 2 +- src/librustc/middle/borrowck/mod.rs | 6 +- src/librustc/middle/borrowck/move_data.rs | 12 +- src/librustc/middle/dataflow.rs | 2 +- src/librustc/middle/trans/adt.rs | 2 +- src/librustc/middle/ty.rs | 38 ++-- src/librustc/middle/typeck/check/mod.rs | 2 +- src/libstd/at_vec.rs | 18 +- src/libstd/bool.rs | 18 +- src/libstd/borrow.rs | 16 +- src/libstd/cast.rs | 28 +-- src/libstd/char.rs | 24 +- src/libstd/clone.rs | 18 +- src/libstd/cmp.rs | 20 +- src/libstd/comm.rs | 10 +- src/libstd/either.rs | 28 +-- src/libstd/hash.rs | 16 +- src/libstd/hashmap.rs | 22 +- src/libstd/iter.rs | 10 +- src/libstd/iterator.rs | 48 ++-- src/libstd/libc.rs | 4 +- src/libstd/managed.rs | 28 +-- src/libstd/nil.rs | 16 +- src/libstd/num/f32.rs | 258 ++++++++++----------- src/libstd/num/f64.rs | 264 +++++++++++----------- src/libstd/num/float.rs | 258 ++++++++++----------- src/libstd/num/i16.rs | 6 +- src/libstd/num/i32.rs | 6 +- src/libstd/num/i64.rs | 6 +- src/libstd/num/i8.rs | 6 +- src/libstd/num/int.rs | 12 +- src/libstd/num/int_macros.rs | 136 +++++------ src/libstd/num/num.rs | 30 +-- src/libstd/num/strconv.rs | 36 +-- src/libstd/num/uint.rs | 4 +- src/libstd/num/uint_macros.rs | 130 +++++------ src/libstd/old_iter.rs | 38 ++-- src/libstd/option.rs | 36 +-- src/libstd/owned.rs | 12 +- src/libstd/path.rs | 2 +- src/libstd/ptr.rs | 74 +++--- src/libstd/rand.rs | 6 +- src/libstd/rand/distributions.rs | 10 +- src/libstd/reflect.rs | 10 +- src/libstd/repr.rs | 10 +- src/libstd/result.rs | 62 ++--- src/libstd/rt/context.rs | 2 +- src/libstd/str.rs | 88 ++++---- src/libstd/str/ascii.rs | 56 ++--- src/libstd/sys.rs | 22 +- src/libstd/task/spawn.rs | 4 +- src/libstd/to_bytes.rs | 58 ++--- src/libstd/to_str.rs | 18 +- src/libstd/trie.rs | 56 ++--- src/libstd/tuple.rs | 36 +-- src/libstd/unstable/atomics.rs | 60 ++--- src/libstd/unstable/extfmt.rs | 2 +- src/libstd/unstable/lang.rs | 14 +- src/libstd/unstable/sync.rs | 10 +- src/libstd/util.rs | 10 +- src/libstd/vec.rs | 136 +++++------ src/libsyntax/ast.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/attr.rs | 2 +- src/libsyntax/ext/deriving/generic.rs | 10 +- src/libsyntax/opt_vec.rs | 26 +-- src/libsyntax/parse/obsolete.rs | 2 +- 79 files changed, 1317 insertions(+), 1317 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index b1bec1f95dbd..6dc37ef58d3a 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -58,7 +58,7 @@ pub struct Condvar<'self> { impl<'self> Condvar<'self> { /// Atomically exit the associated ARC and block until a signal is sent. - #[inline(always)] + #[inline] pub fn wait(&self) { self.wait_on(0) } /** @@ -67,7 +67,7 @@ impl<'self> Condvar<'self> { * * wait() is equivalent to wait_on(0). */ - #[inline(always)] + #[inline] pub fn wait_on(&self, condvar_id: uint) { assert!(!*self.failed); self.cond.wait_on(condvar_id); @@ -76,28 +76,28 @@ impl<'self> Condvar<'self> { } /// Wake up a blocked task. Returns false if there was no blocked task. - #[inline(always)] + #[inline] pub fn signal(&self) -> bool { self.signal_on(0) } /** * Wake up a blocked task on a specified condvar (as * sync::cond.signal_on). Returns false if there was no blocked task. */ - #[inline(always)] + #[inline] pub fn signal_on(&self, condvar_id: uint) -> bool { assert!(!*self.failed); self.cond.signal_on(condvar_id) } /// Wake up all blocked tasks. Returns the number of tasks woken. - #[inline(always)] + #[inline] pub fn broadcast(&self) -> uint { self.broadcast_on(0) } /** * Wake up all blocked tasks on a specified condvar (as * sync::cond.broadcast_on). Returns the number of tasks woken. */ - #[inline(always)] + #[inline] pub fn broadcast_on(&self, condvar_id: uint) -> uint { assert!(!*self.failed); self.cond.broadcast_on(condvar_id) @@ -198,7 +198,7 @@ impl MutexARC { * any tasks that subsequently try to access it (including those already * blocked on the mutex) will also fail immediately. */ - #[inline(always)] + #[inline] pub unsafe fn access(&self, blk: &fn(x: &mut T) -> U) -> U { unsafe { let state = self.x.get(); @@ -213,7 +213,7 @@ impl MutexARC { } /// As access(), but with a condvar, as sync::mutex.lock_cond(). - #[inline(always)] + #[inline] pub unsafe fn access_cond<'x, 'c, U>(&self, blk: &fn(x: &'x mut T, c: &'c Condvar) -> U) @@ -231,7 +231,7 @@ impl MutexARC { } // Common code for {mutex.access,rwlock.write}{,_cond}. -#[inline(always)] +#[inline] #[doc(hidden)] fn check_poison(is_mutex: bool, failed: bool) { if failed { @@ -322,7 +322,7 @@ impl RWARC { * that other tasks won't block forever. As MutexARC.access, it will also * poison the ARC, so subsequent readers and writers will both also fail. */ - #[inline(always)] + #[inline] pub fn write(&self, blk: &fn(x: &mut T) -> U) -> U { unsafe { let state = self.x.get(); @@ -335,7 +335,7 @@ impl RWARC { } /// As write(), but with a condvar, as sync::rwlock.write_cond(). - #[inline(always)] + #[inline] pub fn write_cond<'x, 'c, U>(&self, blk: &fn(x: &'x mut T, c: &'c Condvar) -> U) -> U { diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 2926d5958f16..db4cf564babc 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -119,7 +119,7 @@ pub fn Arena() -> Arena { arena_with_size(32u) } -#[inline(always)] +#[inline] fn round_up_to(base: uint, align: uint) -> uint { (base + (align - 1)) & !(align - 1) } @@ -156,12 +156,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) { // initialized in the arena in the low bit of the tydesc pointer. This // is necessary in order to properly do cleanup if a failure occurs // during an initializer. -#[inline(always)] +#[inline] unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint { let p_bits: uint = transmute(p); p_bits | (is_done as uint) } -#[inline(always)] +#[inline] unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) { (transmute(p & !1), p & 1 == 1) } @@ -179,7 +179,7 @@ impl Arena { return self.alloc_pod_inner(n_bytes, align); } - #[inline(always)] + #[inline] fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 { unsafe { // XXX: Borrow check @@ -199,7 +199,7 @@ impl Arena { } } - #[inline(always)] + #[inline] fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { let tydesc = sys::get_type_desc::(); @@ -223,7 +223,7 @@ impl Arena { return self.alloc_nonpod_inner(n_bytes, align); } - #[inline(always)] + #[inline] fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint) -> (*u8, *u8) { unsafe { @@ -246,7 +246,7 @@ impl Arena { } } - #[inline(always)] + #[inline] fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { let tydesc = sys::get_type_desc::(); @@ -268,7 +268,7 @@ impl Arena { } // The external interface - #[inline(always)] + #[inline] pub fn alloc<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { // XXX: Borrow check diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index e3a15f76c786..647fa81c7185 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -23,7 +23,7 @@ struct SmallBitv { } /// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits -#[inline(always)] +#[inline] fn small_mask(nbits: uint) -> uint { (1 << nbits) - 1 } @@ -33,7 +33,7 @@ impl SmallBitv { SmallBitv {bits: bits} } - #[inline(always)] + #[inline] pub fn bits_op(&mut self, right_bits: uint, nbits: uint, @@ -46,32 +46,32 @@ impl SmallBitv { mask & old_b != mask & new_b } - #[inline(always)] + #[inline] pub fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |u1, u2| u1 | u2) } - #[inline(always)] + #[inline] pub fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |u1, u2| u1 & u2) } - #[inline(always)] + #[inline] pub fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |_u1, u2| u2) } - #[inline(always)] + #[inline] pub fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool { self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2) } - #[inline(always)] + #[inline] pub fn get(&self, i: uint) -> bool { (self.bits & (1 << i)) != 0 } - #[inline(always)] + #[inline] pub fn set(&mut self, i: uint, x: bool) { if x { self.bits |= 1< bool { let mask = small_mask(nbits); mask & self.bits == mask & b.bits } - #[inline(always)] + #[inline] pub fn clear(&mut self) { self.bits = 0; } - #[inline(always)] + #[inline] pub fn set_all(&mut self) { self.bits = !0; } - #[inline(always)] + #[inline] pub fn is_true(&self, nbits: uint) -> bool { small_mask(nbits) & !self.bits == 0 } - #[inline(always)] + #[inline] pub fn is_false(&self, nbits: uint) -> bool { small_mask(nbits) & self.bits == 0 } - #[inline(always)] + #[inline] pub fn invert(&mut self) { self.bits = !self.bits; } } @@ -115,7 +115,7 @@ struct BigBitv { * a mask that has a 1 for each defined bit in the nth element of a big_bitv, * assuming n bits. */ -#[inline(always)] +#[inline] fn big_mask(nbits: uint, elem: uint) -> uint { let rmd = nbits % uint::bits; let nelems = nbits/uint::bits + if rmd == 0 {0} else {1}; @@ -132,7 +132,7 @@ impl BigBitv { BigBitv {storage: storage} } - #[inline(always)] + #[inline] pub fn process(&mut self, b: &BigBitv, nbits: uint, @@ -154,35 +154,35 @@ impl BigBitv { changed } - #[inline(always)] + #[inline] pub fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) -> bool { uint::range(0, self.storage.len(), |i| op(&mut self.storage[i])) } - #[inline(always)] + #[inline] pub fn invert(&mut self) { for self.each_storage |w| { *w = !*w } } - #[inline(always)] + #[inline] pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool { self.process(b, nbits, |w1, w2| w1 | w2) } - #[inline(always)] + #[inline] pub fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool { self.process(b, nbits, |w1, w2| w1 & w2) } - #[inline(always)] + #[inline] pub fn become(&mut self, b: &BigBitv, nbits: uint) -> bool { self.process(b, nbits, |_, w| w) } - #[inline(always)] + #[inline] pub fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool { self.process(b, nbits, |w1, w2| w1 & !w2) } - #[inline(always)] + #[inline] pub fn get(&self, i: uint) -> bool { let w = i / uint::bits; let b = i % uint::bits; @@ -190,7 +190,7 @@ impl BigBitv { x == 1 } - #[inline(always)] + #[inline] pub fn set(&mut self, i: uint, x: bool) { let w = i / uint::bits; let b = i % uint::bits; @@ -199,7 +199,7 @@ impl BigBitv { else { self.storage[w] & !flag }; } - #[inline(always)] + #[inline] pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool { let len = b.storage.len(); for uint::iterate(0, len) |i| { @@ -229,7 +229,7 @@ fn die() -> ! { } impl Bitv { - #[inline(always)] + #[inline] fn do_op(&mut self, op: Op, other: &Bitv) -> bool { if self.nbits != other.nbits { die(); @@ -279,7 +279,7 @@ impl Bitv { * Sets `self` to the union of `self` and `v1`. Both bitvectors must be * the same length. Returns 'true' if `self` changed. */ - #[inline(always)] + #[inline] pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) } /** @@ -288,7 +288,7 @@ impl Bitv { * Sets `self` to the intersection of `self` and `v1`. Both bitvectors * must be the same length. Returns 'true' if `self` changed. */ - #[inline(always)] + #[inline] pub fn intersect(&mut self, v1: &Bitv) -> bool { self.do_op(Intersect, v1) } @@ -299,11 +299,11 @@ impl Bitv { * Both bitvectors must be the same length. Returns `true` if `self` was * changed */ - #[inline(always)] + #[inline] pub fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) } /// Retrieve the value at index `i` - #[inline(always)] + #[inline] pub fn get(&self, i: uint) -> bool { assert!((i < self.nbits)); match self.rep { @@ -317,7 +317,7 @@ impl Bitv { * * `i` must be less than the length of the bitvector. */ - #[inline(always)] + #[inline] pub fn set(&mut self, i: uint, x: bool) { assert!((i < self.nbits)); match self.rep { @@ -332,7 +332,7 @@ impl Bitv { * Both bitvectors must be the same length. Returns `true` if both * bitvectors contain identical elements. */ - #[inline(always)] + #[inline] pub fn equal(&self, v1: &Bitv) -> bool { if self.nbits != v1.nbits { return false; } match self.rep { @@ -348,7 +348,7 @@ impl Bitv { } /// Set all bits to 0 - #[inline(always)] + #[inline] pub fn clear(&mut self) { match self.rep { Small(ref mut b) => b.clear(), @@ -357,7 +357,7 @@ impl Bitv { } /// Set all bits to 1 - #[inline(always)] + #[inline] pub fn set_all(&mut self) { match self.rep { Small(ref mut b) => b.set_all(), @@ -365,7 +365,7 @@ impl Bitv { } /// Invert all bits - #[inline(always)] + #[inline] pub fn invert(&mut self) { match self.rep { Small(ref mut b) => b.invert(), @@ -381,13 +381,13 @@ impl Bitv { * * Returns `true` if `v0` was changed. */ - #[inline(always)] + #[inline] pub fn difference(&mut self, v: &Bitv) -> bool { self.do_op(Difference, v) } /// Returns true if all bits are 1 - #[inline(always)] + #[inline] pub fn is_true(&self) -> bool { match self.rep { Small(ref b) => b.is_true(self.nbits), @@ -398,7 +398,7 @@ impl Bitv { } } - #[inline(always)] + #[inline] pub fn each(&self, f: &fn(bool) -> bool) -> bool { let mut i = 0; while i < self.nbits { @@ -508,7 +508,7 @@ impl Bitv { impl Clone for Bitv { /// Makes a copy of a bitvector - #[inline(always)] + #[inline] fn clone(&self) -> Bitv { match self.rep { Small(ref b) => { @@ -562,7 +562,7 @@ impl ops::Index for Bitv { } } -#[inline(always)] +#[inline] fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool { if bits == 0 { return true; @@ -623,7 +623,7 @@ impl BitvSet { return Bitv{ nbits:cap, rep: Big(~bitv) }; } - #[inline(always)] + #[inline] fn other_op(&mut self, other: &BitvSet, f: &fn(uint, uint) -> uint) { fn nbits(mut w: uint) -> uint { let mut bits = 0; diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index a67b17388198..953803c6843f 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -160,7 +160,7 @@ impl DList { } // Link two nodes together. If either of them are 'none', also sets // the head and/or tail pointers appropriately. - #[inline(always)] + #[inline] fn link(&mut self, before: DListLink, after: DListLink) { match before { Some(neighbour) => neighbour.next = after, @@ -532,7 +532,7 @@ impl BaseIter for @mut DList { return true; } - #[inline(always)] + #[inline] fn size_hint(&self) -> Option { Some(self.len()) } } diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index 1bb364f3a1c3..90ca3bc47c08 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -83,7 +83,7 @@ impl Cmplx { #[cfg(not(stage0))] // Fixed by #4228 impl Cmplx { /// Calculate |self| - #[inline(always)] + #[inline] pub fn norm(&self) -> T { self.re.hypot(&self.im) } @@ -92,7 +92,7 @@ impl Cmplx { #[cfg(not(stage0))] // Fixed by #4228 impl Cmplx { /// Calculate the principal Arg of self. - #[inline(always)] + #[inline] pub fn arg(&self) -> T { self.im.atan2(&self.re) } diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs index ebb88a134818..b2b966928e9a 100644 --- a/src/libextra/num/rational.rs +++ b/src/libextra/num/rational.rs @@ -36,19 +36,19 @@ pub type BigRational = Ratio; impl Ratio { /// Create a ratio representing the integer `t`. - #[inline(always)] + #[inline] pub fn from_integer(t: T) -> Ratio { Ratio::new_raw(t, One::one()) } /// Create a ratio without checking for `denom == 0` or reducing. - #[inline(always)] + #[inline] pub fn new_raw(numer: T, denom: T) -> Ratio { Ratio { numer: numer, denom: denom } } /// Create a new Ratio. Fails if `denom == 0`. - #[inline(always)] + #[inline] pub fn new(numer: T, denom: T) -> Ratio { if denom == Zero::zero() { fail!("denominator == 0"); @@ -206,7 +206,7 @@ impl } } - #[inline(always)] + #[inline] fn round(&self) -> Ratio { if *self < Zero::zero() { Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom) @@ -215,7 +215,7 @@ impl } } - #[inline(always)] + #[inline] fn trunc(&self) -> Ratio { Ratio::from_integer(self.numer / self.denom) } diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 96ad629ea837..b90b0983dc24 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -60,7 +60,7 @@ pub fn rc_from_const(value: T) -> Rc { } impl Rc { - #[inline(always)] + #[inline] pub fn borrow<'r>(&'r self) -> &'r T { unsafe { cast::copy_lifetime(self, &(*self.ptr).value) } } diff --git a/src/libextra/semver.rs b/src/libextra/semver.rs index 462461439e67..cb372dd920da 100644 --- a/src/libextra/semver.rs +++ b/src/libextra/semver.rs @@ -29,7 +29,7 @@ pub enum Identifier { } impl cmp::Ord for Identifier { - #[inline(always)] + #[inline] fn lt(&self, other: &Identifier) -> bool { match (self, other) { (&Numeric(a), &Numeric(b)) => a < b, @@ -38,22 +38,22 @@ impl cmp::Ord for Identifier { (&AlphaNumeric(_), _) => false } } - #[inline(always)] + #[inline] fn le(&self, other: &Identifier) -> bool { ! (other < self) } - #[inline(always)] + #[inline] fn gt(&self, other: &Identifier) -> bool { other < self } - #[inline(always)] + #[inline] fn ge(&self, other: &Identifier) -> bool { ! (self < other) } } impl ToStr for Identifier { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { match self { &Numeric(n) => n.to_str(), @@ -73,7 +73,7 @@ pub struct Version { } impl ToStr for Version { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { let s = fmt!("%u.%u.%u", self.major, self.minor, self.patch); let s = if self.pre.is_empty() { @@ -90,7 +90,7 @@ impl ToStr for Version { } impl cmp::Ord for Version { - #[inline(always)] + #[inline] fn lt(&self, other: &Version) -> bool { self.major < other.major || @@ -123,15 +123,15 @@ impl cmp::Ord for Version { self.build < other.build) } - #[inline(always)] + #[inline] fn le(&self, other: &Version) -> bool { ! (other < self) } - #[inline(always)] + #[inline] fn gt(&self, other: &Version) -> bool { other < self } - #[inline(always)] + #[inline] fn ge(&self, other: &Version) -> bool { ! (self < other) } diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index b5645d9c5017..3e81216fc3a1 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -725,7 +725,7 @@ impl MergeState { } } -#[inline(always)] +#[inline] fn copy_vec(dest: &mut [T], s1: uint, from: &[T]) { @@ -736,7 +736,7 @@ fn copy_vec(dest: &mut [T], } } -#[inline(always)] +#[inline] fn shift_vec(dest: &mut [T], s1: uint, s2: uint, diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 5930bf50ff78..f5d0b6946d33 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -363,7 +363,7 @@ impl<'self> Condvar<'self> { // Checks whether a condvar ID was out of bounds, and fails if so, or does // something else next on success. -#[inline(always)] +#[inline] #[doc(hidden)] fn check_cvar_bounds(out_of_bounds: Option, id: uint, act: &str, blk: &fn() -> U) -> U { diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index e37ce7c71ef7..f857581c17dd 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -75,13 +75,13 @@ fn lt(a: &TreeMap, } impl Ord for TreeMap { - #[inline(always)] + #[inline] fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } - #[inline(always)] + #[inline] fn le(&self, other: &TreeMap) -> bool { !lt(other, self) } - #[inline(always)] + #[inline] fn ge(&self, other: &TreeMap) -> bool { !lt(self, other) } - #[inline(always)] + #[inline] fn gt(&self, other: &TreeMap) -> bool { lt(other, self) } } @@ -145,7 +145,7 @@ impl Map for TreeMap { } /// Return a mutable reference to the value corresponding to the key - #[inline(always)] + #[inline] fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { find_mut(&mut self.root, key) } @@ -236,7 +236,7 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> { /// Advance the iterator to the next node (in order). If there are no more nodes, return `None`. - #[inline(always)] + #[inline] fn next(&mut self) -> Option<&'self T> { do self.iter.next().map |&(value, _)| { value } } @@ -251,69 +251,69 @@ pub struct TreeSet { impl BaseIter for TreeSet { /// Visit all values in order - #[inline(always)] + #[inline] fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } - #[inline(always)] + #[inline] fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TreeSet { /// Visit all values in reverse order - #[inline(always)] + #[inline] fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key_reverse(f) } } impl Eq for TreeSet { - #[inline(always)] + #[inline] fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } - #[inline(always)] + #[inline] fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } impl Ord for TreeSet { - #[inline(always)] + #[inline] fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } - #[inline(always)] + #[inline] fn le(&self, other: &TreeSet) -> bool { self.map <= other.map } - #[inline(always)] + #[inline] fn ge(&self, other: &TreeSet) -> bool { self.map >= other.map } - #[inline(always)] + #[inline] fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } } impl Container for TreeSet { /// Return the number of elements in the set - #[inline(always)] + #[inline] fn len(&const self) -> uint { self.map.len() } /// Return true if the set contains no elements - #[inline(always)] + #[inline] fn is_empty(&const self) -> bool { self.map.is_empty() } } impl Mutable for TreeSet { /// Clear the set, removing all values. - #[inline(always)] + #[inline] fn clear(&mut self) { self.map.clear() } } impl Set for TreeSet { /// Return true if the set contains a value - #[inline(always)] + #[inline] fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } /// Add a value to the set. Return true if the value was not already /// present in the set. - #[inline(always)] + #[inline] fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } /// Remove a value from the set. Return true if the value was /// present in the set. - #[inline(always)] + #[inline] fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } /// Return true if the set has no elements in common with `other`. @@ -336,7 +336,7 @@ impl Set for TreeSet { } /// Return true if the set is a subset of another - #[inline(always)] + #[inline] fn is_subset(&self, other: &TreeSet) -> bool { other.is_superset(self) } @@ -490,12 +490,12 @@ impl Set for TreeSet { impl TreeSet { /// Create an empty TreeSet - #[inline(always)] + #[inline] pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } /// Get a lazy iterator over the values in the set. /// Requires that it be frozen (immutable). - #[inline(always)] + #[inline] pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { TreeSetIterator{iter: self.map.iter()} } @@ -518,7 +518,7 @@ struct TreeNode { impl TreeNode { /// Creates a new tree node. - #[inline(always)] + #[inline] pub fn new(key: K, value: V) -> TreeNode { TreeNode{key: key, value: value, left: None, right: None, level: 1} } diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index b2fd998b73fd..12a26606f36e 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -104,7 +104,7 @@ struct WorkKey { } impl to_bytes::IterBytes for WorkKey { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f) } diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs index 315bb5d63177..07e5d9e4f25a 100644 --- a/src/librustc/back/passes.rs +++ b/src/librustc/back/passes.rs @@ -221,7 +221,7 @@ pub static analysis_passes : &'static [(&'static str, &'static str)] = &'static /** Transformation Passes */ pub static transform_passes : &'static [(&'static str, &'static str)] = &'static [ ("adce", "Aggressive Dead Code Elimination"), - ("always-inline", "Inliner for #[inline(always)] functions"), + ("always-inline", "Inliner for #[inline] functions"), ("argpromotion", "Promote 'by reference' arguments to scalars"), ("bb-vectorize", "Basic-Block Vectorization"), ("block-placement", "Profile Guided Basic Block Placement"), diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 95e26e9e42fa..d7186ad93335 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -775,17 +775,17 @@ impl BorrowckCtxt { } impl DataFlowOperator for LoanDataFlowOperator { - #[inline(always)] + #[inline] fn initial_value(&self) -> bool { false // no loans in scope by default } - #[inline(always)] + #[inline] fn join(&self, succ: uint, pred: uint) -> uint { succ | pred // loans from both preds are in scope } - #[inline(always)] + #[inline] fn walk_closures(&self) -> bool { true } diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index d19afd0f5fc9..3b1c451d0a6e 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -571,34 +571,34 @@ impl FlowedMoveData { } impl DataFlowOperator for MoveDataFlowOperator { - #[inline(always)] + #[inline] fn initial_value(&self) -> bool { false // no loans in scope by default } - #[inline(always)] + #[inline] fn join(&self, succ: uint, pred: uint) -> uint { succ | pred // moves from both preds are in scope } - #[inline(always)] + #[inline] fn walk_closures(&self) -> bool { true } } impl DataFlowOperator for AssignDataFlowOperator { - #[inline(always)] + #[inline] fn initial_value(&self) -> bool { false // no assignments in scope by default } - #[inline(always)] + #[inline] fn join(&self, succ: uint, pred: uint) -> uint { succ | pred // moves from both preds are in scope } - #[inline(always)] + #[inline] fn walk_closures(&self) -> bool { true } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 8403b1616f41..b4942fba05da 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -1016,7 +1016,7 @@ fn join_bits(oper: &O, bitwise(out_vec, in_vec, |a, b| oper.join(a, b)) } -#[inline(always)] +#[inline] fn bitwise(out_vec: &mut [uint], in_vec: &[uint], op: &fn(uint, uint) -> uint) -> bool { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 5481ed9a7fdf..0976407b0bd0 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -576,7 +576,7 @@ fn padding(size: u64) -> ValueRef { } // XXX this utility routine should be somewhere more general -#[inline(always)] +#[inline] fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a } /// Get the discriminant of a constant value. (Not currently used.) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 77bf790131c4..4fc431e0a54c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1094,62 +1094,62 @@ fn mk_t(cx: ctxt, st: sty) -> t { } } -#[inline(always)] +#[inline] pub fn mk_prim_t(primitive: &'static t_box_) -> t { unsafe { cast::transmute::<&'static t_box_, t>(primitive) } } -#[inline(always)] +#[inline] pub fn mk_nil() -> t { mk_prim_t(&primitives::TY_NIL) } -#[inline(always)] +#[inline] pub fn mk_err() -> t { mk_prim_t(&primitives::TY_ERR) } -#[inline(always)] +#[inline] pub fn mk_bot() -> t { mk_prim_t(&primitives::TY_BOT) } -#[inline(always)] +#[inline] pub fn mk_bool() -> t { mk_prim_t(&primitives::TY_BOOL) } -#[inline(always)] +#[inline] pub fn mk_int() -> t { mk_prim_t(&primitives::TY_INT) } -#[inline(always)] +#[inline] pub fn mk_i8() -> t { mk_prim_t(&primitives::TY_I8) } -#[inline(always)] +#[inline] pub fn mk_i16() -> t { mk_prim_t(&primitives::TY_I16) } -#[inline(always)] +#[inline] pub fn mk_i32() -> t { mk_prim_t(&primitives::TY_I32) } -#[inline(always)] +#[inline] pub fn mk_i64() -> t { mk_prim_t(&primitives::TY_I64) } -#[inline(always)] +#[inline] pub fn mk_float() -> t { mk_prim_t(&primitives::TY_FLOAT) } -#[inline(always)] +#[inline] pub fn mk_f32() -> t { mk_prim_t(&primitives::TY_F32) } -#[inline(always)] +#[inline] pub fn mk_f64() -> t { mk_prim_t(&primitives::TY_F64) } -#[inline(always)] +#[inline] pub fn mk_uint() -> t { mk_prim_t(&primitives::TY_UINT) } -#[inline(always)] +#[inline] pub fn mk_u8() -> t { mk_prim_t(&primitives::TY_U8) } -#[inline(always)] +#[inline] pub fn mk_u16() -> t { mk_prim_t(&primitives::TY_U16) } -#[inline(always)] +#[inline] pub fn mk_u32() -> t { mk_prim_t(&primitives::TY_U32) } -#[inline(always)] +#[inline] pub fn mk_u64() -> t { mk_prim_t(&primitives::TY_U64) } pub fn mk_mach_int(tm: ast::int_ty) -> t { @@ -1181,7 +1181,7 @@ pub fn mk_mach_float(tm: ast::float_ty) -> t { } } -#[inline(always)] +#[inline] pub fn mk_char() -> t { mk_prim_t(&primitives::TY_CHAR) } pub fn mk_estr(cx: ctxt, t: vstore) -> t { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index ea41dff99b89..12b413bc5af9 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -725,7 +725,7 @@ impl FnCtxt { ty::re_scope(self.region_lb) } - #[inline(always)] + #[inline] pub fn write_ty(&self, node_id: ast::node_id, ty: ty::t) { debug!("write_ty(%d, %s) in fcx %s", node_id, ppaux::ty_to_str(self.tcx(), ty), self.tag()); diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 56646eb4bfbd..3875847ff9bb 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -38,7 +38,7 @@ pub mod rustrt { } /// Returns the number of elements the vector can hold without reallocating -#[inline(always)] +#[inline] pub fn capacity(v: @[T]) -> uint { unsafe { let repr: **raw::VecRepr = transmute(&v); @@ -58,7 +58,7 @@ pub fn capacity(v: @[T]) -> uint { * as an argument a function that will push an element * onto the vector being constructed. */ -#[inline(always)] +#[inline] pub fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { let mut vec: @[A] = @[]; unsafe { raw::reserve(&mut vec, size); } @@ -76,7 +76,7 @@ pub fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { * as an argument a function that will push an element * onto the vector being constructed. */ -#[inline(always)] +#[inline] pub fn build(builder: &fn(push: &fn(v: A))) -> @[A] { build_sized(4, builder) } @@ -93,7 +93,7 @@ pub fn build(builder: &fn(push: &fn(v: A))) -> @[A] { * as an argument a function that will push an element * onto the vector being constructed. */ -#[inline(always)] +#[inline] pub fn build_sized_opt(size: Option, builder: &fn(push: &fn(v: A))) -> @[A] { @@ -104,7 +104,7 @@ pub fn build_sized_opt(size: Option, /// Iterates over the `rhs` vector, copying each element and appending it to the /// `lhs`. Afterwards, the `lhs` is then returned for use again. -#[inline(always)] +#[inline] pub fn append(lhs: @[T], rhs: &const [T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { for lhs.each |x| { push(copy *x); } @@ -178,7 +178,7 @@ pub mod traits { use ops::Add; impl<'self,T:Copy> Add<&'self const [T],@[T]> for @[T] { - #[inline(always)] + #[inline] fn add(&self, rhs: & &'self const [T]) -> @[T] { append(*self, (*rhs)) } @@ -208,7 +208,7 @@ pub mod raw { * modifing its buffers, so it is up to the caller to ensure that * the vector is actually the specified size. */ - #[inline(always)] + #[inline] pub unsafe fn set_len(v: @[T], new_len: uint) { let repr: **mut VecRepr = transmute(&v); (**repr).unboxed.fill = new_len * sys::size_of::(); @@ -217,7 +217,7 @@ pub mod raw { /** * Pushes a new value onto this vector. */ - #[inline(always)] + #[inline] pub unsafe fn push(v: &mut @[T], initval: T) { let repr: **VecRepr = transmute_copy(&v); let fill = (**repr).unboxed.fill; @@ -228,7 +228,7 @@ pub mod raw { } } - #[inline(always)] // really pretty please + #[inline] // really pretty please unsafe fn push_fast(v: &mut @[T], initval: T) { let repr: **mut VecRepr = ::cast::transmute(v); let fill = (**repr).unboxed.fill; diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs index 66a5bfa944f1..e6be164099bf 100644 --- a/src/libstd/bool.rs +++ b/src/libstd/bool.rs @@ -212,7 +212,7 @@ impl FromStr for bool { * ~~~ */ impl ToStr for bool { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { if *self { ~"true" } else { ~"false" } } @@ -250,24 +250,24 @@ pub fn all_values(blk: &fn(v: bool)) { * 0 * ~~~ */ -#[inline(always)] +#[inline] pub fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } } #[cfg(not(test))] impl Ord for bool { - #[inline(always)] + #[inline] fn lt(&self, other: &bool) -> bool { to_bit(*self) < to_bit(*other) } - #[inline(always)] + #[inline] fn le(&self, other: &bool) -> bool { to_bit(*self) <= to_bit(*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &bool) -> bool { to_bit(*self) > to_bit(*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &bool) -> bool { to_bit(*self) >= to_bit(*other) } } #[cfg(not(test))] impl TotalOrd for bool { - #[inline(always)] + #[inline] fn cmp(&self, other: &bool) -> Ordering { to_bit(*self).cmp(&to_bit(*other)) } } @@ -298,9 +298,9 @@ impl TotalOrd for bool { */ #[cfg(not(test))] impl Eq for bool { - #[inline(always)] + #[inline] fn eq(&self, other: &bool) -> bool { (*self) == (*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &bool) -> bool { (*self) != (*other) } } diff --git a/src/libstd/borrow.rs b/src/libstd/borrow.rs index 703011aea7f8..9e3a3a28fe8c 100644 --- a/src/libstd/borrow.rs +++ b/src/libstd/borrow.rs @@ -14,13 +14,13 @@ use prelude::*; /// Cast a region pointer - &T - to a uint. -#[inline(always)] +#[inline] pub fn to_uint(thing: &T) -> uint { thing as *T as uint } /// Determine if two borrowed pointers point to the same thing. -#[inline(always)] +#[inline] pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool { to_uint(thing) == to_uint(other) } @@ -28,11 +28,11 @@ pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool { // Equality for region pointers #[cfg(not(test))] impl<'self, T: Eq> Eq for &'self T { - #[inline(always)] + #[inline] fn eq(&self, other: & &'self T) -> bool { *(*self) == *(*other) } - #[inline(always)] + #[inline] fn ne(&self, other: & &'self T) -> bool { *(*self) != *(*other) } @@ -41,19 +41,19 @@ impl<'self, T: Eq> Eq for &'self T { // Comparison for region pointers #[cfg(not(test))] impl<'self, T: Ord> Ord for &'self T { - #[inline(always)] + #[inline] fn lt(&self, other: & &'self T) -> bool { *(*self) < *(*other) } - #[inline(always)] + #[inline] fn le(&self, other: & &'self T) -> bool { *(*self) <= *(*other) } - #[inline(always)] + #[inline] fn ge(&self, other: & &'self T) -> bool { *(*self) >= *(*other) } - #[inline(always)] + #[inline] fn gt(&self, other: & &'self T) -> bool { *(*self) > *(*other) } diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index 4d79dea6052a..900cc6009238 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -29,7 +29,7 @@ pub unsafe fn transmute_copy(src: &T) -> U { /// Casts the value at `src` to U. The two types must have the same length. #[cfg(target_word_size = "32", not(stage0))] -#[inline(always)] +#[inline] pub unsafe fn transmute_copy(src: &T) -> U { let mut dest: U = intrinsics::uninit(); let dest_ptr: *mut u8 = transmute(&mut dest); @@ -40,7 +40,7 @@ pub unsafe fn transmute_copy(src: &T) -> U { /// Casts the value at `src` to U. The two types must have the same length. #[cfg(target_word_size = "64", not(stage0))] -#[inline(always)] +#[inline] pub unsafe fn transmute_copy(src: &T) -> U { let mut dest: U = intrinsics::uninit(); let dest_ptr: *mut u8 = transmute(&mut dest); @@ -56,14 +56,14 @@ pub unsafe fn transmute_copy(src: &T) -> U { * to run any required cleanup or memory-management operations on it. This * can be used for various acts of magick. */ -#[inline(always)] +#[inline] pub unsafe fn forget(thing: T) { intrinsics::forget(thing); } /** * Force-increment the reference count on a shared box. If used * carelessly, this can leak the box. */ -#[inline(always)] +#[inline] pub unsafe fn bump_box_refcount(t: @T) { forget(t); } /** @@ -74,59 +74,59 @@ pub unsafe fn bump_box_refcount(t: @T) { forget(t); } * * assert!(transmute("L") == ~[76u8, 0u8]); */ -#[inline(always)] +#[inline] pub unsafe fn transmute(thing: L) -> G { intrinsics::transmute(thing) } /// Coerce an immutable reference to be mutable. -#[inline(always)] +#[inline] pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) } /// Coerce a mutable reference to be immutable. -#[inline(always)] +#[inline] pub unsafe fn transmute_immut<'a,T>(ptr: &'a mut T) -> &'a T { transmute(ptr) } /// Coerce a borrowed pointer to have an arbitrary associated region. -#[inline(always)] +#[inline] pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T { transmute(ptr) } /// Coerce an immutable reference to be mutable. -#[inline(always)] +#[inline] pub unsafe fn transmute_mut_unsafe(ptr: *const T) -> *mut T { transmute(ptr) } /// Coerce an immutable reference to be mutable. -#[inline(always)] +#[inline] pub unsafe fn transmute_immut_unsafe(ptr: *const T) -> *T { transmute(ptr) } /// Coerce a borrowed mutable pointer to have an arbitrary associated region. -#[inline(always)] +#[inline] pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T { transmute(ptr) } /// Transforms lifetime of the second pointer to match the first. -#[inline(always)] +#[inline] pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T { transmute_region(ptr) } /// Transforms lifetime of the second pointer to match the first. -#[inline(always)] +#[inline] pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T { transmute_mut_region(ptr) } /// Transforms lifetime of the second pointer to match the first. -#[inline(always)] +#[inline] pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T { transmute_region(ptr) } diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 7bfac2927c8d..797fd9e8c020 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -65,14 +65,14 @@ pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) } /// Indicates whether a character is in lower case, defined /// in terms of the Unicode General Category 'Ll' /// -#[inline(always)] +#[inline] pub fn is_lowercase(c: char) -> bool { general_category::Ll(c) } /// /// Indicates whether a character is in upper case, defined /// in terms of the Unicode General Category 'Lu'. /// -#[inline(always)] +#[inline] pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) } /// @@ -80,7 +80,7 @@ pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) } /// terms of the Unicode General Categories 'Zs', 'Zl', 'Zp' /// additional 'Cc'-category control codes in the range [0x09, 0x0d] /// -#[inline(always)] +#[inline] pub fn is_whitespace(c: char) -> bool { ('\x09' <= c && c <= '\x0d') || general_category::Zs(c) @@ -93,7 +93,7 @@ pub fn is_whitespace(c: char) -> bool { /// defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No' /// and the Derived Core Property 'Alphabetic'. /// -#[inline(always)] +#[inline] pub fn is_alphanumeric(c: char) -> bool { derived_property::Alphabetic(c) || general_category::Nd(c) @@ -102,7 +102,7 @@ pub fn is_alphanumeric(c: char) -> bool { } /// Indicates whether the character is numeric (Nd, Nl, or No) -#[inline(always)] +#[inline] pub fn is_digit(c: char) -> bool { general_category::Nd(c) || general_category::Nl(c) @@ -127,7 +127,7 @@ pub fn is_digit(c: char) -> bool { /// /// This just wraps `to_digit()`. /// -#[inline(always)] +#[inline] pub fn is_digit_radix(c: char, radix: uint) -> bool { match to_digit(c, radix) { Some(_) => true, @@ -310,21 +310,21 @@ impl Char for char { #[cfg(not(test))] impl Eq for char { - #[inline(always)] + #[inline] fn eq(&self, other: &char) -> bool { (*self) == (*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &char) -> bool { (*self) != (*other) } } #[cfg(not(test))] impl Ord for char { - #[inline(always)] + #[inline] fn lt(&self, other: &char) -> bool { *self < *other } - #[inline(always)] + #[inline] fn le(&self, other: &char) -> bool { *self <= *other } - #[inline(always)] + #[inline] fn gt(&self, other: &char) -> bool { *self > *other } - #[inline(always)] + #[inline] fn ge(&self, other: &char) -> bool { *self >= *other } } diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index 266dd1a35e32..5ec594cef7ee 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -34,25 +34,25 @@ pub trait Clone { impl Clone for ~T { /// Return a deep copy of the owned box. - #[inline(always)] + #[inline] fn clone(&self) -> ~T { ~(**self).clone() } } impl Clone for @T { /// Return a shallow copy of the managed box. - #[inline(always)] + #[inline] fn clone(&self) -> @T { *self } } impl Clone for @mut T { /// Return a shallow copy of the managed box. - #[inline(always)] + #[inline] fn clone(&self) -> @mut T { *self } } impl<'self, T> Clone for &'self T { /// Return a shallow copy of the borrowed pointer. - #[inline(always)] + #[inline] fn clone(&self) -> &'self T { *self } } @@ -60,7 +60,7 @@ macro_rules! clone_impl( ($t:ty) => { impl Clone for $t { /// Return a deep copy of the value. - #[inline(always)] + #[inline] fn clone(&self) -> $t { *self } } } @@ -96,7 +96,7 @@ pub trait DeepClone { impl DeepClone for ~T { /// Return a deep copy of the owned box. - #[inline(always)] + #[inline] fn deep_clone(&self) -> ~T { ~(**self).deep_clone() } } @@ -104,7 +104,7 @@ impl DeepClone for ~T { impl DeepClone for @T { /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing /// a deep clone of a potentially cyclical type. - #[inline(always)] + #[inline] fn deep_clone(&self) -> @T { @(**self).deep_clone() } } @@ -112,7 +112,7 @@ impl DeepClone for @T { impl DeepClone for @mut T { /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing /// a deep clone of a potentially cyclical type. - #[inline(always)] + #[inline] fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() } } @@ -120,7 +120,7 @@ macro_rules! deep_clone_impl( ($t:ty) => { impl DeepClone for $t { /// Return a deep copy of the value. - #[inline(always)] + #[inline] fn deep_clone(&self) -> $t { *self } } } diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index ce6a04c3688b..2c4bb46b23b8 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -45,7 +45,7 @@ pub trait TotalEq { macro_rules! totaleq_impl( ($t:ty) => { impl TotalEq for $t { - #[inline(always)] + #[inline] fn equals(&self, other: &$t) -> bool { *self == *other } } } @@ -84,27 +84,27 @@ pub trait TotalOrd: TotalEq { } impl TotalOrd for Ordering { - #[inline(always)] + #[inline] fn cmp(&self, other: &Ordering) -> Ordering { (*self as int).cmp(&(*other as int)) } } impl Ord for Ordering { - #[inline(always)] + #[inline] fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) } - #[inline(always)] + #[inline] fn le(&self, other: &Ordering) -> bool { (*self as int) <= (*other as int) } - #[inline(always)] + #[inline] fn gt(&self, other: &Ordering) -> bool { (*self as int) > (*other as int) } - #[inline(always)] + #[inline] fn ge(&self, other: &Ordering) -> bool { (*self as int) >= (*other as int) } } macro_rules! totalord_impl( ($t:ty) => { impl TotalOrd for $t { - #[inline(always)] + #[inline] fn cmp(&self, other: &$t) -> Ordering { if *self < *other { Less } else if *self > *other { Greater } @@ -146,7 +146,7 @@ Return `o1` if it is not `Equal`, otherwise `o2`. Simulates the lexical ordering on a type `(int, int)`. */ // used in deriving code in libsyntax -#[inline(always)] +#[inline] pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering { match o1 { Equal => o2, @@ -180,12 +180,12 @@ pub trait Equiv { fn equiv(&self, other: &T) -> bool; } -#[inline(always)] +#[inline] pub fn min(v1: T, v2: T) -> T { if v1 < v2 { v1 } else { v2 } } -#[inline(always)] +#[inline] pub fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index bcdd6cd0bfa6..3f30c811e516 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -625,7 +625,7 @@ mod pipesy { } impl GenericChan for Chan { - #[inline(always)] + #[inline] fn send(&self, x: T) { unsafe { let self_endp = transmute_mut(&self.endp); @@ -636,7 +636,7 @@ mod pipesy { } impl GenericSmartChan for Chan { - #[inline(always)] + #[inline] fn try_send(&self, x: T) -> bool { unsafe { let self_endp = transmute_mut(&self.endp); @@ -653,7 +653,7 @@ mod pipesy { } impl GenericPort for Port { - #[inline(always)] + #[inline] fn recv(&self) -> T { unsafe { let self_endp = transmute_mut(&self.endp); @@ -664,7 +664,7 @@ mod pipesy { } } - #[inline(always)] + #[inline] fn try_recv(&self) -> Option { unsafe { let self_endp = transmute_mut(&self.endp); @@ -681,7 +681,7 @@ mod pipesy { } impl Peekable for Port { - #[inline(always)] + #[inline] fn peek(&self) -> bool { unsafe { let self_endp = transmute_mut(&self.endp); diff --git a/src/libstd/either.rs b/src/libstd/either.rs index e0451b2c65d4..681a7fbc821f 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -33,7 +33,7 @@ pub enum Either { /// If `value` is left(T) then `f_left` is applied to its contents, if /// `value` is right(U) then `f_right` is applied to its contents, and the /// result is returned. -#[inline(always)] +#[inline] pub fn either(f_left: &fn(&T) -> V, f_right: &fn(&U) -> V, value: &Either) -> V { match *value { @@ -83,7 +83,7 @@ pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { } /// Flips between left and right of a given either -#[inline(always)] +#[inline] pub fn flip(eith: Either) -> Either { match eith { Right(r) => Left(r), @@ -95,7 +95,7 @@ pub fn flip(eith: Either) -> Either { /// /// Converts an `either` type to a `result` type, making the "right" choice /// an ok result, and the "left" choice a fail -#[inline(always)] +#[inline] pub fn to_result(eith: Either) -> Result { match eith { Right(r) => result::Ok(r), @@ -104,7 +104,7 @@ pub fn to_result(eith: Either) -> Result { } /// Checks whether the given value is a left -#[inline(always)] +#[inline] pub fn is_left(eith: &Either) -> bool { match *eith { Left(_) => true, @@ -113,7 +113,7 @@ pub fn is_left(eith: &Either) -> bool { } /// Checks whether the given value is a right -#[inline(always)] +#[inline] pub fn is_right(eith: &Either) -> bool { match *eith { Right(_) => true, @@ -122,7 +122,7 @@ pub fn is_right(eith: &Either) -> bool { } /// Retrieves the value in the left branch. Fails if the either is Right. -#[inline(always)] +#[inline] pub fn unwrap_left(eith: Either) -> T { match eith { Left(x) => x, @@ -131,7 +131,7 @@ pub fn unwrap_left(eith: Either) -> T { } /// Retrieves the value in the right branch. Fails if the either is Left. -#[inline(always)] +#[inline] pub fn unwrap_right(eith: Either) -> U { match eith { Right(x) => x, @@ -140,27 +140,27 @@ pub fn unwrap_right(eith: Either) -> U { } impl Either { - #[inline(always)] + #[inline] pub fn either(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V { either(f_left, f_right, self) } - #[inline(always)] + #[inline] pub fn flip(self) -> Either { flip(self) } - #[inline(always)] + #[inline] pub fn to_result(self) -> Result { to_result(self) } - #[inline(always)] + #[inline] pub fn is_left(&self) -> bool { is_left(self) } - #[inline(always)] + #[inline] pub fn is_right(&self) -> bool { is_right(self) } - #[inline(always)] + #[inline] pub fn unwrap_left(self) -> T { unwrap_left(self) } - #[inline(always)] + #[inline] pub fn unwrap_right(self) -> U { unwrap_right(self) } } diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index 2d33be03580c..1967a57e867f 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -64,7 +64,7 @@ pub trait HashUtil { } impl HashUtil for A { - #[inline(always)] + #[inline] fn hash(&self) -> u64 { self.hash_keyed(0,0) } } @@ -79,7 +79,7 @@ pub trait Streaming { } impl Hash for A { - #[inline(always)] + #[inline] fn hash_keyed(&self, k0: u64, k1: u64) -> u64 { let mut s = State::new(k0, k1); for self.iter_bytes(true) |bytes| { @@ -176,7 +176,7 @@ fn hash_keyed_5 State { State::new(0, 0) } @@ -194,7 +194,7 @@ struct SipState { } impl SipState { - #[inline(always)] + #[inline] fn new(key0: u64, key1: u64) -> SipState { let mut state = SipState { k0: key0, @@ -248,7 +248,7 @@ macro_rules! compress ( impl Writer for SipState { // Methods for io::writer - #[inline(always)] + #[inline] fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -315,12 +315,12 @@ impl Writer for SipState { } impl Streaming for SipState { - #[inline(always)] + #[inline] fn input(&mut self, buf: &[u8]) { self.write(buf); } - #[inline(always)] + #[inline] fn result_u64(&mut self) -> u64 { let mut v0 = self.v0; let mut v1 = self.v1; @@ -373,7 +373,7 @@ impl Streaming for SipState { s } - #[inline(always)] + #[inline] fn reset(&mut self) { self.length = 0; self.v0 = self.k0 ^ 0x736f6d6570736575; diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 85156d6996d9..d05fa63a6f9b 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -59,7 +59,7 @@ enum SearchResult { FoundEntry(uint), FoundHole(uint), TableFull } -#[inline(always)] +#[inline] fn resize_at(capacity: uint) -> uint { ((capacity as float) * 3. / 4.) as uint } @@ -85,19 +85,19 @@ fn linear_map_with_capacity_and_keys( } impl HashMap { - #[inline(always)] + #[inline] fn to_bucket(&self, h: uint) -> uint { // A good hash function with entropy spread over all of the // bits is assumed. SipHash is more than good enough. h % self.buckets.len() } - #[inline(always)] + #[inline] fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint { (idx + 1) % len_buckets } - #[inline(always)] + #[inline] fn bucket_sequence(&self, hash: uint, op: &fn(uint) -> bool) -> bool { let start_idx = self.to_bucket(hash); @@ -112,20 +112,20 @@ impl HashMap { } } - #[inline(always)] + #[inline] fn bucket_for_key(&self, k: &K) -> SearchResult { let hash = k.hash_keyed(self.k0, self.k1) as uint; self.bucket_for_key_with_hash(hash, k) } - #[inline(always)] + #[inline] fn bucket_for_key_equiv>(&self, k: &Q) -> SearchResult { let hash = k.hash_keyed(self.k0, self.k1) as uint; self.bucket_for_key_with_hash_equiv(hash, k) } - #[inline(always)] + #[inline] fn bucket_for_key_with_hash(&self, hash: uint, k: &K) @@ -141,7 +141,7 @@ impl HashMap { TableFull } - #[inline(always)] + #[inline] fn bucket_for_key_with_hash_equiv>(&self, hash: uint, k: &Q) @@ -161,7 +161,7 @@ impl HashMap { /// Expand the capacity of the array to the next power of two /// and re-insert each of the existing buckets. - #[inline(always)] + #[inline] fn expand(&mut self) { let new_capacity = self.buckets.len() * 2; self.resize(new_capacity); @@ -190,7 +190,7 @@ impl HashMap { } } - #[inline(always)] + #[inline] fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V { match self.buckets[idx] { Some(ref bkt) => &bkt.value, @@ -198,7 +198,7 @@ impl HashMap { } } - #[inline(always)] + #[inline] fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V { match self.buckets[idx] { Some(ref mut bkt) => &mut bkt.value, diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 2197feea4523..7053cbe0df5a 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -73,7 +73,7 @@ pub trait FromIter { * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f))); * ~~~ */ -#[inline(always)] +#[inline] pub fn any(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { for iter |x| { @@ -94,7 +94,7 @@ pub fn any(predicate: &fn(T) -> bool, * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); * ~~~ */ -#[inline(always)] +#[inline] pub fn all(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { // If we ever break, iter will return false, so this will only return true @@ -112,7 +112,7 @@ pub fn all(predicate: &fn(T) -> bool, * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4); * ~~~ */ -#[inline(always)] +#[inline] pub fn find(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { for iter |x| { @@ -226,7 +226,7 @@ pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&m * assert_eq!(do sum |f| { xs.each(f) }, 10); * ~~~ */ -#[inline(always)] +#[inline] pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { fold_ref(Zero::zero::(), iter, |a, x| *a = a.add(x)) } @@ -241,7 +241,7 @@ pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { * assert_eq!(do product |f| { xs.each(f) }, 24); * ~~~ */ -#[inline(always)] +#[inline] pub fn product>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { fold_ref(One::one::(), iter, |a, x| *a = a.mul(x)) } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 946cf7a72767..eefad1a03dcb 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -321,59 +321,59 @@ pub trait IteratorUtil { /// /// In the future these will be default methods instead of a utility trait. impl> IteratorUtil for T { - #[inline(always)] + #[inline] fn chain_>(self, other: U) -> ChainIterator { ChainIterator{a: self, b: other, flag: false} } - #[inline(always)] + #[inline] fn zip>(self, other: U) -> ZipIterator { ZipIterator{a: self, b: other} } // FIXME: #5898: should be called map - #[inline(always)] + #[inline] fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, T> { MapIterator{iter: self, f: f} } - #[inline(always)] + #[inline] fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, T> { FilterIterator{iter: self, predicate: predicate} } - #[inline(always)] + #[inline] fn filter_map<'r, B>(self, f: &'r fn(A) -> Option) -> FilterMapIterator<'r, A, B, T> { FilterMapIterator { iter: self, f: f } } - #[inline(always)] + #[inline] fn enumerate(self) -> EnumerateIterator { EnumerateIterator{iter: self, count: 0} } - #[inline(always)] + #[inline] fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, T> { SkipWhileIterator{iter: self, flag: false, predicate: predicate} } - #[inline(always)] + #[inline] fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> { TakeWhileIterator{iter: self, flag: false, predicate: predicate} } - #[inline(always)] + #[inline] fn skip(self, n: uint) -> SkipIterator { SkipIterator{iter: self, n: n} } // FIXME: #5898: should be called take - #[inline(always)] + #[inline] fn take_(self, n: uint) -> TakeIterator { TakeIterator{iter: self, n: n} } - #[inline(always)] + #[inline] fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option) -> ScanIterator<'r, A, B, T, St> { ScanIterator{iter: self, f: f, state: initial_state} @@ -392,13 +392,13 @@ impl> IteratorUtil for T { } } - #[inline(always)] + #[inline] fn collect>(&mut self) -> B { FromIter::from_iter::(|f| self.advance(f)) } /// Return the `n`th item yielded by an iterator. - #[inline(always)] + #[inline] fn nth(&mut self, mut n: uint) -> Option { loop { match self.next() { @@ -410,7 +410,7 @@ impl> IteratorUtil for T { } /// Return the last item yielded by an iterator. - #[inline(always)] + #[inline] fn last_(&mut self) -> Option { let mut last = None; for self.advance |x| { last = Some(x); } @@ -431,23 +431,23 @@ impl> IteratorUtil for T { } /// Count the number of items yielded by an iterator - #[inline(always)] + #[inline] fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } - #[inline(always)] + #[inline] fn all(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if !f(x) { return false; } } true } - #[inline(always)] + #[inline] fn any_(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if f(x) { return true; } } false } /// Return the first element satisfying the specified predicate - #[inline(always)] + #[inline] fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option { for self.advance |x| { if predicate(&x) { return Some(x) } @@ -484,7 +484,7 @@ pub trait AdditiveIterator { } impl + Zero, T: Iterator> AdditiveIterator for T { - #[inline(always)] + #[inline] fn sum(&mut self) -> A { self.fold(Zero::zero::(), |s, x| s + x) } } @@ -509,7 +509,7 @@ pub trait MultiplicativeIterator { } impl + One, T: Iterator> MultiplicativeIterator for T { - #[inline(always)] + #[inline] fn product(&mut self) -> A { self.fold(One::one::(), |p, x| p * x) } } @@ -538,7 +538,7 @@ pub trait OrdIterator { } impl> OrdIterator for T { - #[inline(always)] + #[inline] fn max(&mut self) -> Option { self.fold(None, |max, x| { match max { @@ -548,7 +548,7 @@ impl> OrdIterator for T { }) } - #[inline(always)] + #[inline] fn min(&mut self) -> Option { self.fold(None, |min, x| { match min { @@ -843,14 +843,14 @@ pub struct Counter { impl Counter { /// Creates a new counter with the specified start/step - #[inline(always)] + #[inline] pub fn new(start: A, step: A) -> Counter { Counter{state: start, step: step} } } impl + Clone> Iterator for Counter { - #[inline(always)] + #[inline] fn next(&mut self) -> Option { let result = self.state.clone(); self.state = self.state.add(&self.step); // FIXME: #6050 diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 37562a014fb7..07b2ac6ed01b 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -1457,11 +1457,11 @@ pub mod funcs { // These are fine to execute on the Rust stack. They must be, // in fact, because LLVM generates calls to them! #[rust_stack] - #[inline(always)] + #[inline] unsafe fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int; #[rust_stack] - #[inline(always)] + #[inline] unsafe fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void; } } diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index 7d0defea05ac..d514612b5afd 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -38,14 +38,14 @@ pub mod raw { } /// Determine if two shared boxes point to the same object -#[inline(always)] +#[inline] pub fn ptr_eq(a: @T, b: @T) -> bool { let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b)); a_ptr == b_ptr } /// Determine if two mutable shared boxes point to the same object -#[inline(always)] +#[inline] pub fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b)); a_ptr == b_ptr @@ -53,41 +53,41 @@ pub fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { #[cfg(not(test))] impl Eq for @T { - #[inline(always)] + #[inline] fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) } } #[cfg(not(test))] impl Eq for @mut T { - #[inline(always)] + #[inline] fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) } } #[cfg(not(test))] impl Ord for @T { - #[inline(always)] + #[inline] fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) } - #[inline(always)] + #[inline] fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) } } #[cfg(not(test))] impl Ord for @mut T { - #[inline(always)] + #[inline] fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) } - #[inline(always)] + #[inline] fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) } } diff --git a/src/libstd/nil.rs b/src/libstd/nil.rs index 833bd3459ceb..40f6d53ed22f 100644 --- a/src/libstd/nil.rs +++ b/src/libstd/nil.rs @@ -19,32 +19,32 @@ use prelude::*; #[cfg(not(test))] impl Eq for () { - #[inline(always)] + #[inline] fn eq(&self, _other: &()) -> bool { true } - #[inline(always)] + #[inline] fn ne(&self, _other: &()) -> bool { false } } #[cfg(not(test))] impl Ord for () { - #[inline(always)] + #[inline] fn lt(&self, _other: &()) -> bool { false } - #[inline(always)] + #[inline] fn le(&self, _other: &()) -> bool { true } - #[inline(always)] + #[inline] fn ge(&self, _other: &()) -> bool { true } - #[inline(always)] + #[inline] fn gt(&self, _other: &()) -> bool { false } } #[cfg(not(test))] impl TotalOrd for () { - #[inline(always)] + #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal } } #[cfg(not(test))] impl TotalEq for () { - #[inline(always)] + #[inline] fn equals(&self, _other: &()) -> bool { true } } diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 7f9811873003..117a474ffd7d 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -20,7 +20,7 @@ use to_str; pub use cmath::c_float_targ_consts::*; -// An inner module is required to get the #[inline(always)] attribute on the +// An inner module is required to get the #[inline] attribute on the // functions. pub use self::delegated::*; @@ -40,7 +40,7 @@ macro_rules! delegate( use unstable::intrinsics; $( - #[inline(always)] + #[inline] pub fn $name($( $arg : $arg_ty ),*) -> $rv { unsafe { $bound_name($( $arg ),*) @@ -115,45 +115,45 @@ pub static infinity: f32 = 1.0_f32/0.0_f32; pub static neg_infinity: f32 = -1.0_f32/0.0_f32; -#[inline(always)] +#[inline] pub fn add(x: f32, y: f32) -> f32 { return x + y; } -#[inline(always)] +#[inline] pub fn sub(x: f32, y: f32) -> f32 { return x - y; } -#[inline(always)] +#[inline] pub fn mul(x: f32, y: f32) -> f32 { return x * y; } -#[inline(always)] +#[inline] pub fn div(x: f32, y: f32) -> f32 { return x / y; } -#[inline(always)] +#[inline] pub fn rem(x: f32, y: f32) -> f32 { return x % y; } -#[inline(always)] +#[inline] pub fn lt(x: f32, y: f32) -> bool { return x < y; } -#[inline(always)] +#[inline] pub fn le(x: f32, y: f32) -> bool { return x <= y; } -#[inline(always)] +#[inline] pub fn eq(x: f32, y: f32) -> bool { return x == y; } -#[inline(always)] +#[inline] pub fn ne(x: f32, y: f32) -> bool { return x != y; } -#[inline(always)] +#[inline] pub fn ge(x: f32, y: f32) -> bool { return x >= y; } -#[inline(always)] +#[inline] pub fn gt(x: f32, y: f32) -> bool { return x > y; } -#[inline(always)] +#[inline] pub fn fmax(x: f32, y: f32) -> f32 { if x >= y || y.is_NaN() { x } else { y } } -#[inline(always)] +#[inline] pub fn fmin(x: f32, y: f32) -> f32 { if x <= y || y.is_NaN() { x } else { y } } @@ -212,23 +212,23 @@ impl Num for f32 {} #[cfg(not(test))] impl Eq for f32 { - #[inline(always)] + #[inline] fn eq(&self, other: &f32) -> bool { (*self) == (*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &f32) -> bool { (*self) != (*other) } } #[cfg(not(test))] impl ApproxEq for f32 { - #[inline(always)] + #[inline] fn approx_epsilon() -> f32 { 1.0e-6 } - #[inline(always)] + #[inline] fn approx_eq(&self, other: &f32) -> bool { self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) } - #[inline(always)] + #[inline] fn approx_eq_eps(&self, other: &f32, approx_epsilon: &f32) -> bool { (*self - *other).abs() < *approx_epsilon } @@ -236,32 +236,32 @@ impl ApproxEq for f32 { #[cfg(not(test))] impl Ord for f32 { - #[inline(always)] + #[inline] fn lt(&self, other: &f32) -> bool { (*self) < (*other) } - #[inline(always)] + #[inline] fn le(&self, other: &f32) -> bool { (*self) <= (*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &f32) -> bool { (*self) >= (*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &f32) -> bool { (*self) > (*other) } } impl Orderable for f32 { /// Returns `NaN` if either of the numbers are `NaN`. - #[inline(always)] + #[inline] fn min(&self, other: &f32) -> f32 { if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmin(*self, *other) } } /// Returns `NaN` if either of the numbers are `NaN`. - #[inline(always)] + #[inline] fn max(&self, other: &f32) -> f32 { if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) } } /// Returns the number constrained within the range `mn <= self <= mx`. /// If any of the numbers are `NaN` then `NaN` is returned. - #[inline(always)] + #[inline] fn clamp(&self, mn: &f32, mx: &f32) -> f32 { cond!( (self.is_NaN()) { *self } @@ -273,65 +273,65 @@ impl Orderable for f32 { } impl Zero for f32 { - #[inline(always)] + #[inline] fn zero() -> f32 { 0.0 } /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline(always)] + #[inline] fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } } impl One for f32 { - #[inline(always)] + #[inline] fn one() -> f32 { 1.0 } } #[cfg(not(test))] impl Add for f32 { - #[inline(always)] + #[inline] fn add(&self, other: &f32) -> f32 { *self + *other } } #[cfg(not(test))] impl Sub for f32 { - #[inline(always)] + #[inline] fn sub(&self, other: &f32) -> f32 { *self - *other } } #[cfg(not(test))] impl Mul for f32 { - #[inline(always)] + #[inline] fn mul(&self, other: &f32) -> f32 { *self * *other } } #[cfg(not(test))] impl Div for f32 { - #[inline(always)] + #[inline] fn div(&self, other: &f32) -> f32 { *self / *other } } #[cfg(not(test))] impl Rem for f32 { - #[inline(always)] + #[inline] fn rem(&self, other: &f32) -> f32 { *self % *other } } #[cfg(not(test))] impl Neg for f32 { - #[inline(always)] + #[inline] fn neg(&self) -> f32 { -*self } } impl Signed for f32 { /// Computes the absolute value. Returns `NaN` if the number is `NaN`. - #[inline(always)] + #[inline] fn abs(&self) -> f32 { abs(*self) } /// /// The positive difference of two numbers. Returns `0.0` if the number is less than or /// equal to `other`, otherwise the difference between`self` and `other` is returned. /// - #[inline(always)] + #[inline] fn abs_sub(&self, other: &f32) -> f32 { abs_sub(*self, *other) } /// @@ -341,35 +341,35 @@ impl Signed for f32 { /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity` /// - `NaN` if the number is NaN /// - #[inline(always)] + #[inline] fn signum(&self) -> f32 { if self.is_NaN() { NaN } else { copysign(1.0, *self) } } /// Returns `true` if the number is positive, including `+0.0` and `infinity` - #[inline(always)] + #[inline] fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity } /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity` - #[inline(always)] + #[inline] fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity } } impl Round for f32 { /// Round half-way cases toward `neg_infinity` - #[inline(always)] + #[inline] fn floor(&self) -> f32 { floor(*self) } /// Round half-way cases toward `infinity` - #[inline(always)] + #[inline] fn ceil(&self) -> f32 { ceil(*self) } /// Round half-way cases away from `0.0` - #[inline(always)] + #[inline] fn round(&self) -> f32 { round(*self) } /// The integer part of the number (rounds towards `0.0`) - #[inline(always)] + #[inline] fn trunc(&self) -> f32 { trunc(*self) } /// @@ -379,57 +379,57 @@ impl Round for f32 { /// assert!(x == trunc(x) + fract(x)) /// ~~~ /// - #[inline(always)] + #[inline] fn fract(&self) -> f32 { *self - self.trunc() } } impl Fractional for f32 { /// The reciprocal (multiplicative inverse) of the number - #[inline(always)] + #[inline] fn recip(&self) -> f32 { 1.0 / *self } } impl Algebraic for f32 { - #[inline(always)] + #[inline] fn pow(&self, n: &f32) -> f32 { pow(*self, *n) } - #[inline(always)] + #[inline] fn sqrt(&self) -> f32 { sqrt(*self) } - #[inline(always)] + #[inline] fn rsqrt(&self) -> f32 { self.sqrt().recip() } - #[inline(always)] + #[inline] fn cbrt(&self) -> f32 { cbrt(*self) } - #[inline(always)] + #[inline] fn hypot(&self, other: &f32) -> f32 { hypot(*self, *other) } } impl Trigonometric for f32 { - #[inline(always)] + #[inline] fn sin(&self) -> f32 { sin(*self) } - #[inline(always)] + #[inline] fn cos(&self) -> f32 { cos(*self) } - #[inline(always)] + #[inline] fn tan(&self) -> f32 { tan(*self) } - #[inline(always)] + #[inline] fn asin(&self) -> f32 { asin(*self) } - #[inline(always)] + #[inline] fn acos(&self) -> f32 { acos(*self) } - #[inline(always)] + #[inline] fn atan(&self) -> f32 { atan(*self) } - #[inline(always)] + #[inline] fn atan2(&self, other: &f32) -> f32 { atan2(*self, *other) } /// Simultaneously computes the sine and cosine of the number - #[inline(always)] + #[inline] fn sin_cos(&self) -> (f32, f32) { (self.sin(), self.cos()) } @@ -437,38 +437,38 @@ impl Trigonometric for f32 { impl Exponential for f32 { /// Returns the exponential of the number - #[inline(always)] + #[inline] fn exp(&self) -> f32 { exp(*self) } /// Returns 2 raised to the power of the number - #[inline(always)] + #[inline] fn exp2(&self) -> f32 { exp2(*self) } /// Returns the natural logarithm of the number - #[inline(always)] + #[inline] fn ln(&self) -> f32 { ln(*self) } /// Returns the logarithm of the number with respect to an arbitrary base - #[inline(always)] + #[inline] fn log(&self, base: &f32) -> f32 { self.ln() / base.ln() } /// Returns the base 2 logarithm of the number - #[inline(always)] + #[inline] fn log2(&self) -> f32 { log2(*self) } /// Returns the base 10 logarithm of the number - #[inline(always)] + #[inline] fn log10(&self) -> f32 { log10(*self) } } impl Hyperbolic for f32 { - #[inline(always)] + #[inline] fn sinh(&self) -> f32 { sinh(*self) } - #[inline(always)] + #[inline] fn cosh(&self) -> f32 { cosh(*self) } - #[inline(always)] + #[inline] fn tanh(&self) -> f32 { tanh(*self) } /// @@ -480,7 +480,7 @@ impl Hyperbolic for f32 { /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity` /// - `NaN` if `self` is `NaN` /// - #[inline(always)] + #[inline] fn asinh(&self) -> f32 { match *self { neg_infinity => neg_infinity, @@ -497,7 +497,7 @@ impl Hyperbolic for f32 { /// - `infinity` if `self` is `infinity` /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`) /// - #[inline(always)] + #[inline] fn acosh(&self) -> f32 { match *self { x if x < 1.0 => Float::NaN(), @@ -517,7 +517,7 @@ impl Hyperbolic for f32 { /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0` /// (including `infinity` and `neg_infinity`) /// - #[inline(always)] + #[inline] fn atanh(&self) -> f32 { 0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p() } @@ -525,129 +525,129 @@ impl Hyperbolic for f32 { impl Real for f32 { /// Archimedes' constant - #[inline(always)] + #[inline] fn pi() -> f32 { 3.14159265358979323846264338327950288 } /// 2.0 * pi - #[inline(always)] + #[inline] fn two_pi() -> f32 { 6.28318530717958647692528676655900576 } /// pi / 2.0 - #[inline(always)] + #[inline] fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 } /// pi / 3.0 - #[inline(always)] + #[inline] fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 } /// pi / 4.0 - #[inline(always)] + #[inline] fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 } /// pi / 6.0 - #[inline(always)] + #[inline] fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 } /// pi / 8.0 - #[inline(always)] + #[inline] fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 } /// 1 .0/ pi - #[inline(always)] + #[inline] fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 } /// 2.0 / pi - #[inline(always)] + #[inline] fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 } /// 2.0 / sqrt(pi) - #[inline(always)] + #[inline] fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 } /// sqrt(2.0) - #[inline(always)] + #[inline] fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 } /// 1.0 / sqrt(2.0) - #[inline(always)] + #[inline] fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 } /// Euler's number - #[inline(always)] + #[inline] fn e() -> f32 { 2.71828182845904523536028747135266250 } /// log2(e) - #[inline(always)] + #[inline] fn log2_e() -> f32 { 1.44269504088896340735992468100189214 } /// log10(e) - #[inline(always)] + #[inline] fn log10_e() -> f32 { 0.434294481903251827651128918916605082 } /// ln(2.0) - #[inline(always)] + #[inline] fn ln_2() -> f32 { 0.693147180559945309417232121458176568 } /// ln(10.0) - #[inline(always)] + #[inline] fn ln_10() -> f32 { 2.30258509299404568401799145468436421 } /// Converts to degrees, assuming the number is in radians - #[inline(always)] + #[inline] fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::()) } /// Converts to radians, assuming the number is in degrees - #[inline(always)] + #[inline] fn to_radians(&self) -> f32 { *self * (Real::pi::() / 180.0) } } impl Bounded for f32 { - #[inline(always)] + #[inline] fn min_value() -> f32 { 1.17549435e-38 } - #[inline(always)] + #[inline] fn max_value() -> f32 { 3.40282347e+38 } } impl Primitive for f32 { - #[inline(always)] + #[inline] fn bits() -> uint { 32 } - #[inline(always)] + #[inline] fn bytes() -> uint { Primitive::bits::() / 8 } } impl Float for f32 { - #[inline(always)] + #[inline] fn NaN() -> f32 { 0.0 / 0.0 } - #[inline(always)] + #[inline] fn infinity() -> f32 { 1.0 / 0.0 } - #[inline(always)] + #[inline] fn neg_infinity() -> f32 { -1.0 / 0.0 } - #[inline(always)] + #[inline] fn neg_zero() -> f32 { -0.0 } /// Returns `true` if the number is NaN - #[inline(always)] + #[inline] fn is_NaN(&self) -> bool { *self != *self } /// Returns `true` if the number is infinite - #[inline(always)] + #[inline] fn is_infinite(&self) -> bool { *self == Float::infinity() || *self == Float::neg_infinity() } /// Returns `true` if the number is neither infinite or NaN - #[inline(always)] + #[inline] fn is_finite(&self) -> bool { !(self.is_NaN() || self.is_infinite()) } /// Returns `true` if the number is neither zero, infinite, subnormal or NaN - #[inline(always)] + #[inline] fn is_normal(&self) -> bool { self.classify() == FPNormal } @@ -670,29 +670,29 @@ impl Float for f32 { } } - #[inline(always)] + #[inline] fn mantissa_digits() -> uint { 24 } - #[inline(always)] + #[inline] fn digits() -> uint { 6 } - #[inline(always)] + #[inline] fn epsilon() -> f32 { 1.19209290e-07 } - #[inline(always)] + #[inline] fn min_exp() -> int { -125 } - #[inline(always)] + #[inline] fn max_exp() -> int { 128 } - #[inline(always)] + #[inline] fn min_10_exp() -> int { -37 } - #[inline(always)] + #[inline] fn max_10_exp() -> int { 38 } /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` - #[inline(always)] + #[inline] fn ldexp(x: f32, exp: int) -> f32 { ldexp(x, exp as c_int) } @@ -703,7 +703,7 @@ impl Float for f32 { /// - `self = x * pow(2, exp)` /// - `0.5 <= abs(x) < 1.0` /// - #[inline(always)] + #[inline] fn frexp(&self) -> (f32, int) { let mut exp = 0; let x = frexp(*self, &mut exp); @@ -714,14 +714,14 @@ impl Float for f32 { /// Returns the exponential of the number, minus `1`, in a way that is accurate /// even if the number is close to zero /// - #[inline(always)] + #[inline] fn exp_m1(&self) -> f32 { exp_m1(*self) } /// /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// than if the operations were performed separately /// - #[inline(always)] + #[inline] fn ln_1p(&self) -> f32 { ln_1p(*self) } /// @@ -729,13 +729,13 @@ impl Float for f32 { /// produces a more accurate result with better performance than a separate multiplication /// operation followed by an add. /// - #[inline(always)] + #[inline] fn mul_add(&self, a: f32, b: f32) -> f32 { mul_add(*self, a, b) } /// Returns the next representable floating-point value in the direction of `other` - #[inline(always)] + #[inline] fn next_after(&self, other: f32) -> f32 { next_after(*self, other) } @@ -752,7 +752,7 @@ impl Float for f32 { /// /// * num - The float value /// -#[inline(always)] +#[inline] pub fn to_str(num: f32) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigAll); @@ -766,7 +766,7 @@ pub fn to_str(num: f32) -> ~str { /// /// * num - The float value /// -#[inline(always)] +#[inline] pub fn to_str_hex(num: f32) -> ~str { let (r, _) = strconv::to_str_common( &num, 16u, true, strconv::SignNeg, strconv::DigAll); @@ -787,7 +787,7 @@ pub fn to_str_hex(num: f32) -> ~str { /// possible misinterpretation of the result at higher bases. If those values /// are expected, use `to_str_radix_special()` instead. /// -#[inline(always)] +#[inline] pub fn to_str_radix(num: f32, rdx: uint) -> ~str { let (r, special) = strconv::to_str_common( &num, rdx, true, strconv::SignNeg, strconv::DigAll); @@ -805,7 +805,7 @@ pub fn to_str_radix(num: f32, rdx: uint) -> ~str { /// * num - The float value /// * radix - The base to use /// -#[inline(always)] +#[inline] pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { strconv::to_str_common(&num, rdx, true, strconv::SignNeg, strconv::DigAll) @@ -820,7 +820,7 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { /// * num - The float value /// * digits - The number of significant digits /// -#[inline(always)] +#[inline] pub fn to_str_exact(num: f32, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); @@ -836,7 +836,7 @@ pub fn to_str_exact(num: f32, dig: uint) -> ~str { /// * num - The float value /// * digits - The number of significant digits /// -#[inline(always)] +#[inline] pub fn to_str_digits(num: f32, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); @@ -844,12 +844,12 @@ pub fn to_str_digits(num: f32, dig: uint) -> ~str { } impl to_str::ToStr for f32 { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_str_digits(*self, 8) } } impl num::ToStrRadix for f32 { - #[inline(always)] + #[inline] fn to_str_radix(&self, rdx: uint) -> ~str { to_str_radix(*self, rdx) } @@ -882,7 +882,7 @@ impl num::ToStrRadix for f32 { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. /// -#[inline(always)] +#[inline] pub fn from_str(num: &str) -> Option { strconv::from_str_common(num, 10u, true, true, true, strconv::ExpDec, false, false) @@ -915,7 +915,7 @@ pub fn from_str(num: &str) -> Option { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `[num]`. /// -#[inline(always)] +#[inline] pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, strconv::ExpBin, false, false) @@ -940,19 +940,19 @@ pub fn from_str_hex(num: &str) -> Option { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. /// -#[inline(always)] +#[inline] pub fn from_str_radix(num: &str, rdx: uint) -> Option { strconv::from_str_common(num, rdx, true, true, false, strconv::ExpNone, false, false) } impl FromStr for f32 { - #[inline(always)] + #[inline] fn from_str(val: &str) -> Option { from_str(val) } } impl num::FromStrRadix for f32 { - #[inline(always)] + #[inline] fn from_str_radix(val: &str, rdx: uint) -> Option { from_str_radix(val, rdx) } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 6303e3045764..e13dff1e6235 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -22,7 +22,7 @@ use to_str; pub use cmath::c_double_targ_consts::*; pub use cmp::{min, max}; -// An inner module is required to get the #[inline(always)] attribute on the +// An inner module is required to get the #[inline] attribute on the // functions. pub use self::delegated::*; @@ -42,7 +42,7 @@ macro_rules! delegate( use unstable::intrinsics; $( - #[inline(always)] + #[inline] pub fn $name($( $arg : $arg_ty ),*) -> $rv { unsafe { $bound_name($( $arg ),*) @@ -141,45 +141,45 @@ pub static infinity: f64 = 1.0_f64/0.0_f64; pub static neg_infinity: f64 = -1.0_f64/0.0_f64; -#[inline(always)] +#[inline] pub fn add(x: f64, y: f64) -> f64 { return x + y; } -#[inline(always)] +#[inline] pub fn sub(x: f64, y: f64) -> f64 { return x - y; } -#[inline(always)] +#[inline] pub fn mul(x: f64, y: f64) -> f64 { return x * y; } -#[inline(always)] +#[inline] pub fn div(x: f64, y: f64) -> f64 { return x / y; } -#[inline(always)] +#[inline] pub fn rem(x: f64, y: f64) -> f64 { return x % y; } -#[inline(always)] +#[inline] pub fn lt(x: f64, y: f64) -> bool { return x < y; } -#[inline(always)] +#[inline] pub fn le(x: f64, y: f64) -> bool { return x <= y; } -#[inline(always)] +#[inline] pub fn eq(x: f64, y: f64) -> bool { return x == y; } -#[inline(always)] +#[inline] pub fn ne(x: f64, y: f64) -> bool { return x != y; } -#[inline(always)] +#[inline] pub fn ge(x: f64, y: f64) -> bool { return x >= y; } -#[inline(always)] +#[inline] pub fn gt(x: f64, y: f64) -> bool { return x > y; } -#[inline(always)] +#[inline] pub fn fmax(x: f64, y: f64) -> f64 { if x >= y || y.is_NaN() { x } else { y } } -#[inline(always)] +#[inline] pub fn fmin(x: f64, y: f64) -> f64 { if x <= y || y.is_NaN() { x } else { y } } @@ -234,23 +234,23 @@ impl Num for f64 {} #[cfg(not(test))] impl Eq for f64 { - #[inline(always)] + #[inline] fn eq(&self, other: &f64) -> bool { (*self) == (*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &f64) -> bool { (*self) != (*other) } } #[cfg(not(test))] impl ApproxEq for f64 { - #[inline(always)] + #[inline] fn approx_epsilon() -> f64 { 1.0e-6 } - #[inline(always)] + #[inline] fn approx_eq(&self, other: &f64) -> bool { self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) } - #[inline(always)] + #[inline] fn approx_eq_eps(&self, other: &f64, approx_epsilon: &f64) -> bool { (*self - *other).abs() < *approx_epsilon } @@ -258,32 +258,32 @@ impl ApproxEq for f64 { #[cfg(not(test))] impl Ord for f64 { - #[inline(always)] + #[inline] fn lt(&self, other: &f64) -> bool { (*self) < (*other) } - #[inline(always)] + #[inline] fn le(&self, other: &f64) -> bool { (*self) <= (*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &f64) -> bool { (*self) >= (*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &f64) -> bool { (*self) > (*other) } } impl Orderable for f64 { /// Returns `NaN` if either of the numbers are `NaN`. - #[inline(always)] + #[inline] fn min(&self, other: &f64) -> f64 { if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmin(*self, *other) } } /// Returns `NaN` if either of the numbers are `NaN`. - #[inline(always)] + #[inline] fn max(&self, other: &f64) -> f64 { if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) } } /// Returns the number constrained within the range `mn <= self <= mx`. /// If any of the numbers are `NaN` then `NaN` is returned. - #[inline(always)] + #[inline] fn clamp(&self, mn: &f64, mx: &f64) -> f64 { cond!( (self.is_NaN()) { *self } @@ -295,16 +295,16 @@ impl Orderable for f64 { } impl Zero for f64 { - #[inline(always)] + #[inline] fn zero() -> f64 { 0.0 } /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline(always)] + #[inline] fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } } impl One for f64 { - #[inline(always)] + #[inline] fn one() -> f64 { 1.0 } } @@ -326,7 +326,7 @@ impl Div for f64 { } #[cfg(not(test))] impl Rem for f64 { - #[inline(always)] + #[inline] fn rem(&self, other: &f64) -> f64 { *self % *other } } #[cfg(not(test))] @@ -336,14 +336,14 @@ impl Neg for f64 { impl Signed for f64 { /// Computes the absolute value. Returns `NaN` if the number is `NaN`. - #[inline(always)] + #[inline] fn abs(&self) -> f64 { abs(*self) } /// /// The positive difference of two numbers. Returns `0.0` if the number is less than or /// equal to `other`, otherwise the difference between`self` and `other` is returned. /// - #[inline(always)] + #[inline] fn abs_sub(&self, other: &f64) -> f64 { abs_sub(*self, *other) } /// @@ -353,35 +353,35 @@ impl Signed for f64 { /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity` /// - `NaN` if the number is NaN /// - #[inline(always)] + #[inline] fn signum(&self) -> f64 { if self.is_NaN() { NaN } else { copysign(1.0, *self) } } /// Returns `true` if the number is positive, including `+0.0` and `infinity` - #[inline(always)] + #[inline] fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity } /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity` - #[inline(always)] + #[inline] fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity } } impl Round for f64 { /// Round half-way cases toward `neg_infinity` - #[inline(always)] + #[inline] fn floor(&self) -> f64 { floor(*self) } /// Round half-way cases toward `infinity` - #[inline(always)] + #[inline] fn ceil(&self) -> f64 { ceil(*self) } /// Round half-way cases away from `0.0` - #[inline(always)] + #[inline] fn round(&self) -> f64 { round(*self) } /// The integer part of the number (rounds towards `0.0`) - #[inline(always)] + #[inline] fn trunc(&self) -> f64 { trunc(*self) } /// @@ -391,57 +391,57 @@ impl Round for f64 { /// assert!(x == trunc(x) + fract(x)) /// ~~~ /// - #[inline(always)] + #[inline] fn fract(&self) -> f64 { *self - self.trunc() } } impl Fractional for f64 { /// The reciprocal (multiplicative inverse) of the number - #[inline(always)] + #[inline] fn recip(&self) -> f64 { 1.0 / *self } } impl Algebraic for f64 { - #[inline(always)] + #[inline] fn pow(&self, n: &f64) -> f64 { pow(*self, *n) } - #[inline(always)] + #[inline] fn sqrt(&self) -> f64 { sqrt(*self) } - #[inline(always)] + #[inline] fn rsqrt(&self) -> f64 { self.sqrt().recip() } - #[inline(always)] + #[inline] fn cbrt(&self) -> f64 { cbrt(*self) } - #[inline(always)] + #[inline] fn hypot(&self, other: &f64) -> f64 { hypot(*self, *other) } } impl Trigonometric for f64 { - #[inline(always)] + #[inline] fn sin(&self) -> f64 { sin(*self) } - #[inline(always)] + #[inline] fn cos(&self) -> f64 { cos(*self) } - #[inline(always)] + #[inline] fn tan(&self) -> f64 { tan(*self) } - #[inline(always)] + #[inline] fn asin(&self) -> f64 { asin(*self) } - #[inline(always)] + #[inline] fn acos(&self) -> f64 { acos(*self) } - #[inline(always)] + #[inline] fn atan(&self) -> f64 { atan(*self) } - #[inline(always)] + #[inline] fn atan2(&self, other: &f64) -> f64 { atan2(*self, *other) } /// Simultaneously computes the sine and cosine of the number - #[inline(always)] + #[inline] fn sin_cos(&self) -> (f64, f64) { (self.sin(), self.cos()) } @@ -449,38 +449,38 @@ impl Trigonometric for f64 { impl Exponential for f64 { /// Returns the exponential of the number - #[inline(always)] + #[inline] fn exp(&self) -> f64 { exp(*self) } /// Returns 2 raised to the power of the number - #[inline(always)] + #[inline] fn exp2(&self) -> f64 { exp2(*self) } /// Returns the natural logarithm of the number - #[inline(always)] + #[inline] fn ln(&self) -> f64 { ln(*self) } /// Returns the logarithm of the number with respect to an arbitrary base - #[inline(always)] + #[inline] fn log(&self, base: &f64) -> f64 { self.ln() / base.ln() } /// Returns the base 2 logarithm of the number - #[inline(always)] + #[inline] fn log2(&self) -> f64 { log2(*self) } /// Returns the base 10 logarithm of the number - #[inline(always)] + #[inline] fn log10(&self) -> f64 { log10(*self) } } impl Hyperbolic for f64 { - #[inline(always)] + #[inline] fn sinh(&self) -> f64 { sinh(*self) } - #[inline(always)] + #[inline] fn cosh(&self) -> f64 { cosh(*self) } - #[inline(always)] + #[inline] fn tanh(&self) -> f64 { tanh(*self) } /// @@ -492,7 +492,7 @@ impl Hyperbolic for f64 { /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity` /// - `NaN` if `self` is `NaN` /// - #[inline(always)] + #[inline] fn asinh(&self) -> f64 { match *self { neg_infinity => neg_infinity, @@ -509,7 +509,7 @@ impl Hyperbolic for f64 { /// - `infinity` if `self` is `infinity` /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`) /// - #[inline(always)] + #[inline] fn acosh(&self) -> f64 { match *self { x if x < 1.0 => Float::NaN(), @@ -529,7 +529,7 @@ impl Hyperbolic for f64 { /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0` /// (including `infinity` and `neg_infinity`) /// - #[inline(always)] + #[inline] fn atanh(&self) -> f64 { 0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p() } @@ -537,159 +537,159 @@ impl Hyperbolic for f64 { impl Real for f64 { /// Archimedes' constant - #[inline(always)] + #[inline] fn pi() -> f64 { 3.14159265358979323846264338327950288 } /// 2.0 * pi - #[inline(always)] + #[inline] fn two_pi() -> f64 { 6.28318530717958647692528676655900576 } /// pi / 2.0 - #[inline(always)] + #[inline] fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 } /// pi / 3.0 - #[inline(always)] + #[inline] fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 } /// pi / 4.0 - #[inline(always)] + #[inline] fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 } /// pi / 6.0 - #[inline(always)] + #[inline] fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 } /// pi / 8.0 - #[inline(always)] + #[inline] fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 } /// 1.0 / pi - #[inline(always)] + #[inline] fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 } /// 2.0 / pi - #[inline(always)] + #[inline] fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 } /// 2.0 / sqrt(pi) - #[inline(always)] + #[inline] fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 } /// sqrt(2.0) - #[inline(always)] + #[inline] fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 } /// 1.0 / sqrt(2.0) - #[inline(always)] + #[inline] fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 } /// Euler's number - #[inline(always)] + #[inline] fn e() -> f64 { 2.71828182845904523536028747135266250 } /// log2(e) - #[inline(always)] + #[inline] fn log2_e() -> f64 { 1.44269504088896340735992468100189214 } /// log10(e) - #[inline(always)] + #[inline] fn log10_e() -> f64 { 0.434294481903251827651128918916605082 } /// ln(2.0) - #[inline(always)] + #[inline] fn ln_2() -> f64 { 0.693147180559945309417232121458176568 } /// ln(10.0) - #[inline(always)] + #[inline] fn ln_10() -> f64 { 2.30258509299404568401799145468436421 } /// Converts to degrees, assuming the number is in radians - #[inline(always)] + #[inline] fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::()) } /// Converts to radians, assuming the number is in degrees - #[inline(always)] + #[inline] fn to_radians(&self) -> f64 { *self * (Real::pi::() / 180.0) } } impl RealExt for f64 { - #[inline(always)] + #[inline] fn lgamma(&self) -> (int, f64) { let mut sign = 0; let result = lgamma(*self, &mut sign); (sign as int, result) } - #[inline(always)] + #[inline] fn tgamma(&self) -> f64 { tgamma(*self) } - #[inline(always)] + #[inline] fn j0(&self) -> f64 { j0(*self) } - #[inline(always)] + #[inline] fn j1(&self) -> f64 { j1(*self) } - #[inline(always)] + #[inline] fn jn(&self, n: int) -> f64 { jn(n as c_int, *self) } - #[inline(always)] + #[inline] fn y0(&self) -> f64 { y0(*self) } - #[inline(always)] + #[inline] fn y1(&self) -> f64 { y1(*self) } - #[inline(always)] + #[inline] fn yn(&self, n: int) -> f64 { yn(n as c_int, *self) } } impl Bounded for f64 { - #[inline(always)] + #[inline] fn min_value() -> f64 { 2.2250738585072014e-308 } - #[inline(always)] + #[inline] fn max_value() -> f64 { 1.7976931348623157e+308 } } impl Primitive for f64 { - #[inline(always)] + #[inline] fn bits() -> uint { 64 } - #[inline(always)] + #[inline] fn bytes() -> uint { Primitive::bits::() / 8 } } impl Float for f64 { - #[inline(always)] + #[inline] fn NaN() -> f64 { 0.0 / 0.0 } - #[inline(always)] + #[inline] fn infinity() -> f64 { 1.0 / 0.0 } - #[inline(always)] + #[inline] fn neg_infinity() -> f64 { -1.0 / 0.0 } - #[inline(always)] + #[inline] fn neg_zero() -> f64 { -0.0 } /// Returns `true` if the number is NaN - #[inline(always)] + #[inline] fn is_NaN(&self) -> bool { *self != *self } /// Returns `true` if the number is infinite - #[inline(always)] + #[inline] fn is_infinite(&self) -> bool { *self == Float::infinity() || *self == Float::neg_infinity() } /// Returns `true` if the number is neither infinite or NaN - #[inline(always)] + #[inline] fn is_finite(&self) -> bool { !(self.is_NaN() || self.is_infinite()) } /// Returns `true` if the number is neither zero, infinite, subnormal or NaN - #[inline(always)] + #[inline] fn is_normal(&self) -> bool { self.classify() == FPNormal } @@ -712,29 +712,29 @@ impl Float for f64 { } } - #[inline(always)] + #[inline] fn mantissa_digits() -> uint { 53 } - #[inline(always)] + #[inline] fn digits() -> uint { 15 } - #[inline(always)] + #[inline] fn epsilon() -> f64 { 2.2204460492503131e-16 } - #[inline(always)] + #[inline] fn min_exp() -> int { -1021 } - #[inline(always)] + #[inline] fn max_exp() -> int { 1024 } - #[inline(always)] + #[inline] fn min_10_exp() -> int { -307 } - #[inline(always)] + #[inline] fn max_10_exp() -> int { 308 } /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` - #[inline(always)] + #[inline] fn ldexp(x: f64, exp: int) -> f64 { ldexp(x, exp as c_int) } @@ -745,7 +745,7 @@ impl Float for f64 { /// - `self = x * pow(2, exp)` /// - `0.5 <= abs(x) < 1.0` /// - #[inline(always)] + #[inline] fn frexp(&self) -> (f64, int) { let mut exp = 0; let x = frexp(*self, &mut exp); @@ -756,14 +756,14 @@ impl Float for f64 { /// Returns the exponential of the number, minus `1`, in a way that is accurate /// even if the number is close to zero /// - #[inline(always)] + #[inline] fn exp_m1(&self) -> f64 { exp_m1(*self) } /// /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// than if the operations were performed separately /// - #[inline(always)] + #[inline] fn ln_1p(&self) -> f64 { ln_1p(*self) } /// @@ -771,13 +771,13 @@ impl Float for f64 { /// produces a more accurate result with better performance than a separate multiplication /// operation followed by an add. /// - #[inline(always)] + #[inline] fn mul_add(&self, a: f64, b: f64) -> f64 { mul_add(*self, a, b) } /// Returns the next representable floating-point value in the direction of `other` - #[inline(always)] + #[inline] fn next_after(&self, other: f64) -> f64 { next_after(*self, other) } @@ -794,7 +794,7 @@ impl Float for f64 { /// /// * num - The float value /// -#[inline(always)] +#[inline] pub fn to_str(num: f64) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigAll); @@ -808,7 +808,7 @@ pub fn to_str(num: f64) -> ~str { /// /// * num - The float value /// -#[inline(always)] +#[inline] pub fn to_str_hex(num: f64) -> ~str { let (r, _) = strconv::to_str_common( &num, 16u, true, strconv::SignNeg, strconv::DigAll); @@ -829,7 +829,7 @@ pub fn to_str_hex(num: f64) -> ~str { /// possible misinterpretation of the result at higher bases. If those values /// are expected, use `to_str_radix_special()` instead. /// -#[inline(always)] +#[inline] pub fn to_str_radix(num: f64, rdx: uint) -> ~str { let (r, special) = strconv::to_str_common( &num, rdx, true, strconv::SignNeg, strconv::DigAll); @@ -847,7 +847,7 @@ pub fn to_str_radix(num: f64, rdx: uint) -> ~str { /// * num - The float value /// * radix - The base to use /// -#[inline(always)] +#[inline] pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { strconv::to_str_common(&num, rdx, true, strconv::SignNeg, strconv::DigAll) @@ -862,7 +862,7 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { /// * num - The float value /// * digits - The number of significant digits /// -#[inline(always)] +#[inline] pub fn to_str_exact(num: f64, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); @@ -878,7 +878,7 @@ pub fn to_str_exact(num: f64, dig: uint) -> ~str { /// * num - The float value /// * digits - The number of significant digits /// -#[inline(always)] +#[inline] pub fn to_str_digits(num: f64, dig: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); @@ -886,12 +886,12 @@ pub fn to_str_digits(num: f64, dig: uint) -> ~str { } impl to_str::ToStr for f64 { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_str_digits(*self, 8) } } impl num::ToStrRadix for f64 { - #[inline(always)] + #[inline] fn to_str_radix(&self, rdx: uint) -> ~str { to_str_radix(*self, rdx) } @@ -924,7 +924,7 @@ impl num::ToStrRadix for f64 { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. /// -#[inline(always)] +#[inline] pub fn from_str(num: &str) -> Option { strconv::from_str_common(num, 10u, true, true, true, strconv::ExpDec, false, false) @@ -957,7 +957,7 @@ pub fn from_str(num: &str) -> Option { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `[num]`. /// -#[inline(always)] +#[inline] pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, strconv::ExpBin, false, false) @@ -982,19 +982,19 @@ pub fn from_str_hex(num: &str) -> Option { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. /// -#[inline(always)] +#[inline] pub fn from_str_radix(num: &str, rdx: uint) -> Option { strconv::from_str_common(num, rdx, true, true, false, strconv::ExpNone, false, false) } impl FromStr for f64 { - #[inline(always)] + #[inline] fn from_str(val: &str) -> Option { from_str(val) } } impl num::FromStrRadix for f64 { - #[inline(always)] + #[inline] fn from_str_radix(val: &str, rdx: uint) -> Option { from_str_radix(val, rdx) } diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs index 267a8890e826..c583aeacf162 100644 --- a/src/libstd/num/float.rs +++ b/src/libstd/num/float.rs @@ -99,7 +99,7 @@ pub mod consts { /// /// * num - The float value /// -#[inline(always)] +#[inline] pub fn to_str(num: float) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigAll); @@ -113,7 +113,7 @@ pub fn to_str(num: float) -> ~str { /// /// * num - The float value /// -#[inline(always)] +#[inline] pub fn to_str_hex(num: float) -> ~str { let (r, _) = strconv::to_str_common( &num, 16u, true, strconv::SignNeg, strconv::DigAll); @@ -134,7 +134,7 @@ pub fn to_str_hex(num: float) -> ~str { /// possible misinterpretation of the result at higher bases. If those values /// are expected, use `to_str_radix_special()` instead. /// -#[inline(always)] +#[inline] pub fn to_str_radix(num: float, radix: uint) -> ~str { let (r, special) = strconv::to_str_common( &num, radix, true, strconv::SignNeg, strconv::DigAll); @@ -152,7 +152,7 @@ pub fn to_str_radix(num: float, radix: uint) -> ~str { /// * num - The float value /// * radix - The base to use /// -#[inline(always)] +#[inline] pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { strconv::to_str_common(&num, radix, true, strconv::SignNeg, strconv::DigAll) @@ -167,7 +167,7 @@ pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { /// * num - The float value /// * digits - The number of significant digits /// -#[inline(always)] +#[inline] pub fn to_str_exact(num: float, digits: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits)); @@ -183,7 +183,7 @@ pub fn to_str_exact(num: float, digits: uint) -> ~str { /// * num - The float value /// * digits - The number of significant digits /// -#[inline(always)] +#[inline] pub fn to_str_digits(num: float, digits: uint) -> ~str { let (r, _) = strconv::to_str_common( &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits)); @@ -191,12 +191,12 @@ pub fn to_str_digits(num: float, digits: uint) -> ~str { } impl to_str::ToStr for float { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_str_digits(*self, 8) } } impl num::ToStrRadix for float { - #[inline(always)] + #[inline] fn to_str_radix(&self, radix: uint) -> ~str { to_str_radix(*self, radix) } @@ -229,7 +229,7 @@ impl num::ToStrRadix for float { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. /// -#[inline(always)] +#[inline] pub fn from_str(num: &str) -> Option { strconv::from_str_common(num, 10u, true, true, true, strconv::ExpDec, false, false) @@ -262,7 +262,7 @@ pub fn from_str(num: &str) -> Option { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `[num]`. /// -#[inline(always)] +#[inline] pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, strconv::ExpBin, false, false) @@ -287,19 +287,19 @@ pub fn from_str_hex(num: &str) -> Option { /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. /// -#[inline(always)] +#[inline] pub fn from_str_radix(num: &str, radix: uint) -> Option { strconv::from_str_common(num, radix, true, true, false, strconv::ExpNone, false, false) } impl FromStr for float { - #[inline(always)] + #[inline] fn from_str(val: &str) -> Option { from_str(val) } } impl num::FromStrRadix for float { - #[inline(always)] + #[inline] fn from_str_radix(val: &str, radix: uint) -> Option { from_str_radix(val, radix) } @@ -341,27 +341,27 @@ pub fn pow_with_uint(base: uint, pow: uint) -> float { return total; } -#[inline(always)] +#[inline] pub fn abs(x: float) -> float { f64::abs(x as f64) as float } -#[inline(always)] +#[inline] pub fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float } -#[inline(always)] +#[inline] pub fn atan(x: float) -> float { f64::atan(x as f64) as float } -#[inline(always)] +#[inline] pub fn sin(x: float) -> float { f64::sin(x as f64) as float } -#[inline(always)] +#[inline] pub fn cos(x: float) -> float { f64::cos(x as f64) as float } -#[inline(always)] +#[inline] pub fn tan(x: float) -> float { f64::tan(x as f64) as float } @@ -370,23 +370,23 @@ impl Num for float {} #[cfg(not(test))] impl Eq for float { - #[inline(always)] + #[inline] fn eq(&self, other: &float) -> bool { (*self) == (*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &float) -> bool { (*self) != (*other) } } #[cfg(not(test))] impl ApproxEq for float { - #[inline(always)] + #[inline] fn approx_epsilon() -> float { 1.0e-6 } - #[inline(always)] + #[inline] fn approx_eq(&self, other: &float) -> bool { self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) } - #[inline(always)] + #[inline] fn approx_eq_eps(&self, other: &float, approx_epsilon: &float) -> bool { (*self - *other).abs() < *approx_epsilon } @@ -394,66 +394,66 @@ impl ApproxEq for float { #[cfg(not(test))] impl Ord for float { - #[inline(always)] + #[inline] fn lt(&self, other: &float) -> bool { (*self) < (*other) } - #[inline(always)] + #[inline] fn le(&self, other: &float) -> bool { (*self) <= (*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &float) -> bool { (*self) >= (*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &float) -> bool { (*self) > (*other) } } impl Orderable for float { /// Returns `NaN` if either of the numbers are `NaN`. - #[inline(always)] + #[inline] fn min(&self, other: &float) -> float { (*self as f64).min(&(*other as f64)) as float } /// Returns `NaN` if either of the numbers are `NaN`. - #[inline(always)] + #[inline] fn max(&self, other: &float) -> float { (*self as f64).max(&(*other as f64)) as float } /// Returns the number constrained within the range `mn <= self <= mx`. /// If any of the numbers are `NaN` then `NaN` is returned. - #[inline(always)] + #[inline] fn clamp(&self, mn: &float, mx: &float) -> float { (*self as f64).clamp(&(*mn as f64), &(*mx as f64)) as float } } impl Zero for float { - #[inline(always)] + #[inline] fn zero() -> float { 0.0 } /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline(always)] + #[inline] fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } } impl One for float { - #[inline(always)] + #[inline] fn one() -> float { 1.0 } } impl Round for float { /// Round half-way cases toward `neg_infinity` - #[inline(always)] + #[inline] fn floor(&self) -> float { floor(*self as f64) as float } /// Round half-way cases toward `infinity` - #[inline(always)] + #[inline] fn ceil(&self) -> float { ceil(*self as f64) as float } /// Round half-way cases away from `0.0` - #[inline(always)] + #[inline] fn round(&self) -> float { round(*self as f64) as float } /// The integer part of the number (rounds towards `0.0`) - #[inline(always)] + #[inline] fn trunc(&self) -> float { trunc(*self as f64) as float } /// @@ -463,81 +463,81 @@ impl Round for float { /// assert!(x == trunc(x) + fract(x)) /// ~~~ /// - #[inline(always)] + #[inline] fn fract(&self) -> float { *self - self.trunc() } } impl Fractional for float { /// The reciprocal (multiplicative inverse) of the number - #[inline(always)] + #[inline] fn recip(&self) -> float { 1.0 / *self } } impl Algebraic for float { - #[inline(always)] + #[inline] fn pow(&self, n: &float) -> float { (*self as f64).pow(&(*n as f64)) as float } - #[inline(always)] + #[inline] fn sqrt(&self) -> float { (*self as f64).sqrt() as float } - #[inline(always)] + #[inline] fn rsqrt(&self) -> float { (*self as f64).rsqrt() as float } - #[inline(always)] + #[inline] fn cbrt(&self) -> float { (*self as f64).cbrt() as float } - #[inline(always)] + #[inline] fn hypot(&self, other: &float) -> float { (*self as f64).hypot(&(*other as f64)) as float } } impl Trigonometric for float { - #[inline(always)] + #[inline] fn sin(&self) -> float { (*self as f64).sin() as float } - #[inline(always)] + #[inline] fn cos(&self) -> float { (*self as f64).cos() as float } - #[inline(always)] + #[inline] fn tan(&self) -> float { (*self as f64).tan() as float } - #[inline(always)] + #[inline] fn asin(&self) -> float { (*self as f64).asin() as float } - #[inline(always)] + #[inline] fn acos(&self) -> float { (*self as f64).acos() as float } - #[inline(always)] + #[inline] fn atan(&self) -> float { (*self as f64).atan() as float } - #[inline(always)] + #[inline] fn atan2(&self, other: &float) -> float { (*self as f64).atan2(&(*other as f64)) as float } /// Simultaneously computes the sine and cosine of the number - #[inline(always)] + #[inline] fn sin_cos(&self) -> (float, float) { match (*self as f64).sin_cos() { (s, c) => (s as float, c as float) @@ -547,54 +547,54 @@ impl Trigonometric for float { impl Exponential for float { /// Returns the exponential of the number - #[inline(always)] + #[inline] fn exp(&self) -> float { (*self as f64).exp() as float } /// Returns 2 raised to the power of the number - #[inline(always)] + #[inline] fn exp2(&self) -> float { (*self as f64).exp2() as float } /// Returns the natural logarithm of the number - #[inline(always)] + #[inline] fn ln(&self) -> float { (*self as f64).ln() as float } /// Returns the logarithm of the number with respect to an arbitrary base - #[inline(always)] + #[inline] fn log(&self, base: &float) -> float { (*self as f64).log(&(*base as f64)) as float } /// Returns the base 2 logarithm of the number - #[inline(always)] + #[inline] fn log2(&self) -> float { (*self as f64).log2() as float } /// Returns the base 10 logarithm of the number - #[inline(always)] + #[inline] fn log10(&self) -> float { (*self as f64).log10() as float } } impl Hyperbolic for float { - #[inline(always)] + #[inline] fn sinh(&self) -> float { (*self as f64).sinh() as float } - #[inline(always)] + #[inline] fn cosh(&self) -> float { (*self as f64).cosh() as float } - #[inline(always)] + #[inline] fn tanh(&self) -> float { (*self as f64).tanh() as float } @@ -608,7 +608,7 @@ impl Hyperbolic for float { /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity` /// - `NaN` if `self` is `NaN` /// - #[inline(always)] + #[inline] fn asinh(&self) -> float { (*self as f64).asinh() as float } @@ -622,7 +622,7 @@ impl Hyperbolic for float { /// - `infinity` if `self` is `infinity` /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`) /// - #[inline(always)] + #[inline] fn acosh(&self) -> float { (*self as f64).acosh() as float } @@ -639,7 +639,7 @@ impl Hyperbolic for float { /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0` /// (including `infinity` and `neg_infinity`) /// - #[inline(always)] + #[inline] fn atanh(&self) -> float { (*self as f64).atanh() as float } @@ -647,157 +647,157 @@ impl Hyperbolic for float { impl Real for float { /// Archimedes' constant - #[inline(always)] + #[inline] fn pi() -> float { 3.14159265358979323846264338327950288 } /// 2.0 * pi - #[inline(always)] + #[inline] fn two_pi() -> float { 6.28318530717958647692528676655900576 } /// pi / 2.0 - #[inline(always)] + #[inline] fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 } /// pi / 3.0 - #[inline(always)] + #[inline] fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 } /// pi / 4.0 - #[inline(always)] + #[inline] fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 } /// pi / 6.0 - #[inline(always)] + #[inline] fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 } /// pi / 8.0 - #[inline(always)] + #[inline] fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 } /// 1.0 / pi - #[inline(always)] + #[inline] fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 } /// 2.0 / pi - #[inline(always)] + #[inline] fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 } /// 2 .0/ sqrt(pi) - #[inline(always)] + #[inline] fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 } /// sqrt(2.0) - #[inline(always)] + #[inline] fn sqrt2() -> float { 1.41421356237309504880168872420969808 } /// 1.0 / sqrt(2.0) - #[inline(always)] + #[inline] fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 } /// Euler's number - #[inline(always)] + #[inline] fn e() -> float { 2.71828182845904523536028747135266250 } /// log2(e) - #[inline(always)] + #[inline] fn log2_e() -> float { 1.44269504088896340735992468100189214 } /// log10(e) - #[inline(always)] + #[inline] fn log10_e() -> float { 0.434294481903251827651128918916605082 } /// ln(2.0) - #[inline(always)] + #[inline] fn ln_2() -> float { 0.693147180559945309417232121458176568 } /// ln(10.0) - #[inline(always)] + #[inline] fn ln_10() -> float { 2.30258509299404568401799145468436421 } /// Converts to degrees, assuming the number is in radians - #[inline(always)] + #[inline] fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float } /// Converts to radians, assuming the number is in degrees - #[inline(always)] + #[inline] fn to_radians(&self) -> float { (*self as f64).to_radians() as float } } impl RealExt for float { - #[inline(always)] + #[inline] fn lgamma(&self) -> (int, float) { let mut sign = 0; let result = lgamma(*self as f64, &mut sign); (sign as int, result as float) } - #[inline(always)] + #[inline] fn tgamma(&self) -> float { tgamma(*self as f64) as float } - #[inline(always)] + #[inline] fn j0(&self) -> float { j0(*self as f64) as float } - #[inline(always)] + #[inline] fn j1(&self) -> float { j1(*self as f64) as float } - #[inline(always)] + #[inline] fn jn(&self, n: int) -> float { jn(n as c_int, *self as f64) as float } - #[inline(always)] + #[inline] fn y0(&self) -> float { y0(*self as f64) as float } - #[inline(always)] + #[inline] fn y1(&self) -> float { y1(*self as f64) as float } - #[inline(always)] + #[inline] fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float } } #[cfg(not(test))] impl Add for float { - #[inline(always)] + #[inline] fn add(&self, other: &float) -> float { *self + *other } } #[cfg(not(test))] impl Sub for float { - #[inline(always)] + #[inline] fn sub(&self, other: &float) -> float { *self - *other } } #[cfg(not(test))] impl Mul for float { - #[inline(always)] + #[inline] fn mul(&self, other: &float) -> float { *self * *other } } #[cfg(not(test))] impl Div for float { - #[inline(always)] + #[inline] fn div(&self, other: &float) -> float { *self / *other } } #[cfg(not(test))] impl Rem for float { - #[inline(always)] + #[inline] fn rem(&self, other: &float) -> float { *self % *other } } #[cfg(not(test))] impl Neg for float { - #[inline(always)] + #[inline] fn neg(&self) -> float { -*self } } impl Signed for float { /// Computes the absolute value. Returns `NaN` if the number is `NaN`. - #[inline(always)] + #[inline] fn abs(&self) -> float { abs(*self) } /// /// The positive difference of two numbers. Returns `0.0` if the number is less than or /// equal to `other`, otherwise the difference between`self` and `other` is returned. /// - #[inline(always)] + #[inline] fn abs_sub(&self, other: &float) -> float { (*self as f64).abs_sub(&(*other as f64)) as float } @@ -809,93 +809,93 @@ impl Signed for float { /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity` /// - `NaN` if the number is NaN /// - #[inline(always)] + #[inline] fn signum(&self) -> float { if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float } } /// Returns `true` if the number is positive, including `+0.0` and `infinity` - #[inline(always)] + #[inline] fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity } /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity` - #[inline(always)] + #[inline] fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity } } impl Bounded for float { - #[inline(always)] + #[inline] fn min_value() -> float { Bounded::min_value::() as float } - #[inline(always)] + #[inline] fn max_value() -> float { Bounded::max_value::() as float } } impl Primitive for float { - #[inline(always)] + #[inline] fn bits() -> uint { Primitive::bits::() } - #[inline(always)] + #[inline] fn bytes() -> uint { Primitive::bytes::() } } impl Float for float { - #[inline(always)] + #[inline] fn NaN() -> float { Float::NaN::() as float } - #[inline(always)] + #[inline] fn infinity() -> float { Float::infinity::() as float } - #[inline(always)] + #[inline] fn neg_infinity() -> float { Float::neg_infinity::() as float } - #[inline(always)] + #[inline] fn neg_zero() -> float { Float::neg_zero::() as float } /// Returns `true` if the number is NaN - #[inline(always)] + #[inline] fn is_NaN(&self) -> bool { (*self as f64).is_NaN() } /// Returns `true` if the number is infinite - #[inline(always)] + #[inline] fn is_infinite(&self) -> bool { (*self as f64).is_infinite() } /// Returns `true` if the number is neither infinite or NaN - #[inline(always)] + #[inline] fn is_finite(&self) -> bool { (*self as f64).is_finite() } /// Returns `true` if the number is neither zero, infinite, subnormal or NaN - #[inline(always)] + #[inline] fn is_normal(&self) -> bool { (*self as f64).is_normal() } /// Returns the floating point category of the number. If only one property is going to /// be tested, it is generally faster to use the specific predicate instead. - #[inline(always)] + #[inline] fn classify(&self) -> FPCategory { (*self as f64).classify() } - #[inline(always)] + #[inline] fn mantissa_digits() -> uint { Float::mantissa_digits::() } - #[inline(always)] + #[inline] fn digits() -> uint { Float::digits::() } - #[inline(always)] + #[inline] fn epsilon() -> float { Float::epsilon::() as float } - #[inline(always)] + #[inline] fn min_exp() -> int { Float::min_exp::() } - #[inline(always)] + #[inline] fn max_exp() -> int { Float::max_exp::() } - #[inline(always)] + #[inline] fn min_10_exp() -> int { Float::min_10_exp::() } - #[inline(always)] + #[inline] fn max_10_exp() -> int { Float::max_10_exp::() } /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` - #[inline(always)] + #[inline] fn ldexp(x: float, exp: int) -> float { Float::ldexp(x as f64, exp) as float } @@ -906,7 +906,7 @@ impl Float for float { /// - `self = x * pow(2, exp)` /// - `0.5 <= abs(x) < 1.0` /// - #[inline(always)] + #[inline] fn frexp(&self) -> (float, int) { match (*self as f64).frexp() { (x, exp) => (x as float, exp) @@ -917,7 +917,7 @@ impl Float for float { /// Returns the exponential of the number, minus `1`, in a way that is accurate /// even if the number is close to zero /// - #[inline(always)] + #[inline] fn exp_m1(&self) -> float { (*self as f64).exp_m1() as float } @@ -926,7 +926,7 @@ impl Float for float { /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// than if the operations were performed separately /// - #[inline(always)] + #[inline] fn ln_1p(&self) -> float { (*self as f64).ln_1p() as float } @@ -936,13 +936,13 @@ impl Float for float { /// produces a more accurate result with better performance than a separate multiplication /// operation followed by an add. /// - #[inline(always)] + #[inline] fn mul_add(&self, a: float, b: float) -> float { mul_add(*self as f64, a as f64, b as f64) as float } /// Returns the next representable floating-point value in the direction of `other` - #[inline(always)] + #[inline] fn next_after(&self, other: float) -> float { next_after(*self as f64, other as f64) as float } diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs index 9977247b249b..eec20297a533 100644 --- a/src/libstd/num/i16.rs +++ b/src/libstd/num/i16.rs @@ -19,14 +19,14 @@ int_module!(i16, 16) impl BitCount for i16 { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self) } } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self) } } } diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs index 0115f306e4e0..769187cc66d6 100644 --- a/src/libstd/num/i32.rs +++ b/src/libstd/num/i32.rs @@ -19,14 +19,14 @@ int_module!(i32, 32) impl BitCount for i32 { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self) } } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self) } } } diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs index 4e280f01f272..ae0e59d16610 100644 --- a/src/libstd/num/i64.rs +++ b/src/libstd/num/i64.rs @@ -19,14 +19,14 @@ int_module!(i64, 64) impl BitCount for i64 { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self) } } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self) } } } diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs index 939965b96918..31a1f4241f58 100644 --- a/src/libstd/num/i8.rs +++ b/src/libstd/num/i8.rs @@ -19,14 +19,14 @@ int_module!(i8, 8) impl BitCount for i8 { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self) } } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self) } } } diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index 96ef7e9e3412..d3c2733b47d5 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -22,30 +22,30 @@ int_module!(int, super::bits) #[cfg(target_word_size = "32")] impl BitCount for int { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> int { (*self as i32).population_count() as int } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int } } #[cfg(target_word_size = "64")] impl BitCount for int { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> int { (*self as i64).population_count() as int } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int } } diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 74f74d11b730..74ec46ccfcd4 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -27,17 +27,17 @@ pub static min_value: $T = (-1 as $T) << (bits - 1); pub static max_value: $T = min_value - 1 as $T; /// Calculates the sum of two numbers -#[inline(always)] +#[inline] pub fn add(x: $T, y: $T) -> $T { x + y } /// Subtracts the second number from the first -#[inline(always)] +#[inline] pub fn sub(x: $T, y: $T) -> $T { x - y } /// Multiplies two numbers together -#[inline(always)] +#[inline] pub fn mul(x: $T, y: $T) -> $T { x * y } /// Divides the first argument by the second argument (using integer division) /// Divides the first argument by the second argument (using integer division) -#[inline(always)] +#[inline] pub fn div(x: $T, y: $T) -> $T { x / y } /// @@ -60,26 +60,26 @@ pub fn div(x: $T, y: $T) -> $T { x / y } /// ~~~ /// /// -#[inline(always)] +#[inline] pub fn rem(x: $T, y: $T) -> $T { x % y } /// Returns true iff `x < y` -#[inline(always)] +#[inline] pub fn lt(x: $T, y: $T) -> bool { x < y } /// Returns true iff `x <= y` -#[inline(always)] +#[inline] pub fn le(x: $T, y: $T) -> bool { x <= y } /// Returns true iff `x == y` -#[inline(always)] +#[inline] pub fn eq(x: $T, y: $T) -> bool { x == y } /// Returns true iff `x != y` -#[inline(always)] +#[inline] pub fn ne(x: $T, y: $T) -> bool { x != y } /// Returns true iff `x >= y` -#[inline(always)] +#[inline] pub fn ge(x: $T, y: $T) -> bool { x >= y } /// Returns true iff `x > y` -#[inline(always)] +#[inline] pub fn gt(x: $T, y: $T) -> bool { x > y } /// @@ -99,7 +99,7 @@ pub fn gt(x: $T, y: $T) -> bool { x > y } /// assert!(sum == 10); /// ~~~ /// -#[inline(always)] +#[inline] pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { @@ -122,62 +122,62 @@ pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { return true; } -#[inline(always)] +#[inline] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { range_step(lo, hi, 1 as $T, it) } -#[inline(always)] +#[inline] /// Iterate over the range [`hi`..`lo`) pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { range_step(hi, lo, -1 as $T, it) } /// Computes the bitwise complement -#[inline(always)] +#[inline] pub fn compl(i: $T) -> $T { -1 as $T ^ i } /// Computes the absolute value -#[inline(always)] +#[inline] pub fn abs(i: $T) -> $T { i.abs() } impl Num for $T {} #[cfg(not(test))] impl Ord for $T { - #[inline(always)] + #[inline] fn lt(&self, other: &$T) -> bool { return (*self) < (*other); } - #[inline(always)] + #[inline] fn le(&self, other: &$T) -> bool { return (*self) <= (*other); } - #[inline(always)] + #[inline] fn ge(&self, other: &$T) -> bool { return (*self) >= (*other); } - #[inline(always)] + #[inline] fn gt(&self, other: &$T) -> bool { return (*self) > (*other); } } #[cfg(not(test))] impl Eq for $T { - #[inline(always)] + #[inline] fn eq(&self, other: &$T) -> bool { return (*self) == (*other); } - #[inline(always)] + #[inline] fn ne(&self, other: &$T) -> bool { return (*self) != (*other); } } impl Orderable for $T { - #[inline(always)] + #[inline] fn min(&self, other: &$T) -> $T { if *self < *other { *self } else { *other } } - #[inline(always)] + #[inline] fn max(&self, other: &$T) -> $T { if *self > *other { *self } else { *other } } - #[inline(always)] + #[inline] fn clamp(&self, mn: &$T, mx: &$T) -> $T { if *self > *mx { *mx } else if *self < *mn { *mn } else { *self } @@ -185,33 +185,33 @@ impl Orderable for $T { } impl Zero for $T { - #[inline(always)] + #[inline] fn zero() -> $T { 0 } - #[inline(always)] + #[inline] fn is_zero(&self) -> bool { *self == 0 } } impl One for $T { - #[inline(always)] + #[inline] fn one() -> $T { 1 } } #[cfg(not(test))] impl Add<$T,$T> for $T { - #[inline(always)] + #[inline] fn add(&self, other: &$T) -> $T { *self + *other } } #[cfg(not(test))] impl Sub<$T,$T> for $T { - #[inline(always)] + #[inline] fn sub(&self, other: &$T) -> $T { *self - *other } } #[cfg(not(test))] impl Mul<$T,$T> for $T { - #[inline(always)] + #[inline] fn mul(&self, other: &$T) -> $T { *self * *other } } @@ -235,7 +235,7 @@ impl Div<$T,$T> for $T { /// assert!(-1 / -2 == 0); /// ~~~ /// - #[inline(always)] + #[inline] fn div(&self, other: &$T) -> $T { *self / *other } } @@ -262,19 +262,19 @@ impl Rem<$T,$T> for $T { /// assert!(-1 % -2 == -1); /// ~~~ /// - #[inline(always)] + #[inline] fn rem(&self, other: &$T) -> $T { *self % *other } } #[cfg(not(test))] impl Neg<$T> for $T { - #[inline(always)] + #[inline] fn neg(&self) -> $T { -*self } } impl Signed for $T { /// Computes the absolute value - #[inline(always)] + #[inline] fn abs(&self) -> $T { if self.is_negative() { -*self } else { *self } } @@ -283,7 +283,7 @@ impl Signed for $T { /// The positive difference of two numbers. Returns `0` if the number is less than or /// equal to `other`, otherwise the difference between`self` and `other` is returned. /// - #[inline(always)] + #[inline] fn abs_sub(&self, other: &$T) -> $T { if *self <= *other { 0 } else { *self - *other } } @@ -295,7 +295,7 @@ impl Signed for $T { /// - `1` if the number is positive /// - `-1` if the number is negative /// - #[inline(always)] + #[inline] fn signum(&self) -> $T { match *self { n if n > 0 => 1, @@ -305,11 +305,11 @@ impl Signed for $T { } /// Returns true if the number is positive - #[inline(always)] + #[inline] fn is_positive(&self) -> bool { *self > 0 } /// Returns true if the number is negative - #[inline(always)] + #[inline] fn is_negative(&self) -> bool { *self < 0 } } @@ -331,7 +331,7 @@ impl Integer for $T { /// assert!((-1).div_floor(-2) == 0); /// ~~~ /// - #[inline(always)] + #[inline] fn div_floor(&self, other: &$T) -> $T { // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_, // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf) @@ -363,7 +363,7 @@ impl Integer for $T { /// assert!((-1).mod_floor(-2) == -1); /// ~~~ /// - #[inline(always)] + #[inline] fn mod_floor(&self, other: &$T) -> $T { // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_, // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf) @@ -375,7 +375,7 @@ impl Integer for $T { } /// Calculates `div_floor` and `mod_floor` simultaneously - #[inline(always)] + #[inline] fn div_mod_floor(&self, other: &$T) -> ($T,$T) { // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_, // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf) @@ -387,7 +387,7 @@ impl Integer for $T { } /// Calculates `div` (`\`) and `rem` (`%`) simultaneously - #[inline(always)] + #[inline] fn div_rem(&self, other: &$T) -> ($T,$T) { (*self / *other, *self % *other) } @@ -397,7 +397,7 @@ impl Integer for $T { /// /// The result is always positive /// - #[inline(always)] + #[inline] fn gcd(&self, other: &$T) -> $T { // Use Euclid's algorithm let mut (m, n) = (*self, *other); @@ -412,21 +412,21 @@ impl Integer for $T { /// /// Calculates the Lowest Common Multiple (LCM) of the number and `other` /// - #[inline(always)] + #[inline] fn lcm(&self, other: &$T) -> $T { ((*self * *other) / self.gcd(other)).abs() // should not have to recaluculate abs } /// Returns `true` if the number can be divided by `other` without leaving a remainder - #[inline(always)] + #[inline] fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 } /// Returns `true` if the number is divisible by `2` - #[inline(always)] + #[inline] fn is_even(&self) -> bool { self.is_multiple_of(&2) } /// Returns `true` if the number is not divisible by `2` - #[inline(always)] + #[inline] fn is_odd(&self) -> bool { !self.is_even() } } @@ -434,90 +434,90 @@ impl Bitwise for $T {} #[cfg(not(test))] impl BitOr<$T,$T> for $T { - #[inline(always)] + #[inline] fn bitor(&self, other: &$T) -> $T { *self | *other } } #[cfg(not(test))] impl BitAnd<$T,$T> for $T { - #[inline(always)] + #[inline] fn bitand(&self, other: &$T) -> $T { *self & *other } } #[cfg(not(test))] impl BitXor<$T,$T> for $T { - #[inline(always)] + #[inline] fn bitxor(&self, other: &$T) -> $T { *self ^ *other } } #[cfg(not(test))] impl Shl<$T,$T> for $T { - #[inline(always)] + #[inline] fn shl(&self, other: &$T) -> $T { *self << *other } } #[cfg(not(test))] impl Shr<$T,$T> for $T { - #[inline(always)] + #[inline] fn shr(&self, other: &$T) -> $T { *self >> *other } } #[cfg(not(test))] impl Not<$T> for $T { - #[inline(always)] + #[inline] fn not(&self) -> $T { !*self } } impl Bounded for $T { - #[inline(always)] + #[inline] fn min_value() -> $T { min_value } - #[inline(always)] + #[inline] fn max_value() -> $T { max_value } } impl Int for $T {} impl Primitive for $T { - #[inline(always)] + #[inline] fn bits() -> uint { bits } - #[inline(always)] + #[inline] fn bytes() -> uint { bits / 8 } } // String conversion functions and impl str -> num /// Parse a string as a number in base 10. -#[inline(always)] +#[inline] pub fn from_str(s: &str) -> Option<$T> { strconv::from_str_common(s, 10u, true, false, false, strconv::ExpNone, false, false) } /// Parse a string as a number in the given base. -#[inline(always)] +#[inline] pub fn from_str_radix(s: &str, radix: uint) -> Option<$T> { strconv::from_str_common(s, radix, true, false, false, strconv::ExpNone, false, false) } /// Parse a byte slice as a number in the given base. -#[inline(always)] +#[inline] pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> { strconv::from_str_bytes_common(buf, radix, true, false, false, strconv::ExpNone, false, false) } impl FromStr for $T { - #[inline(always)] + #[inline] fn from_str(s: &str) -> Option<$T> { from_str(s) } } impl FromStrRadix for $T { - #[inline(always)] + #[inline] fn from_str_radix(s: &str, radix: uint) -> Option<$T> { from_str_radix(s, radix) } @@ -526,7 +526,7 @@ impl FromStrRadix for $T { // String conversion functions and impl num -> str /// Convert to a string as a byte slice in a given base. -#[inline(always)] +#[inline] pub fn to_str_bytes(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); @@ -534,7 +534,7 @@ pub fn to_str_bytes(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { } /// Convert to a string in base 10. -#[inline(always)] +#[inline] pub fn to_str(num: $T) -> ~str { let (buf, _) = strconv::to_str_common(&num, 10u, false, strconv::SignNeg, strconv::DigAll); @@ -542,7 +542,7 @@ pub fn to_str(num: $T) -> ~str { } /// Convert to a string in a given base. -#[inline(always)] +#[inline] pub fn to_str_radix(num: $T, radix: uint) -> ~str { let (buf, _) = strconv::to_str_common(&num, radix, false, strconv::SignNeg, strconv::DigAll); @@ -550,14 +550,14 @@ pub fn to_str_radix(num: $T, radix: uint) -> ~str { } impl ToStr for $T { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_str(*self) } } impl ToStrRadix for $T { - #[inline(always)] + #[inline] fn to_str_radix(&self, radix: uint) -> ~str { to_str_radix(*self, radix) } diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index e73156243689..30a18a0587bc 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -307,7 +307,7 @@ pub trait Float: Real /// assert_eq!(twenty, 20f32); /// ~~~ /// -#[inline(always)] +#[inline] pub fn cast(n: T) -> U { NumCast::from(n) } @@ -338,28 +338,28 @@ pub trait NumCast { macro_rules! impl_num_cast( ($T:ty, $conv:ident) => ( impl NumCast for $T { - #[inline(always)] + #[inline] fn from(n: N) -> $T { // `$conv` could be generated using `concat_idents!`, but that // macro seems to be broken at the moment n.$conv() } - #[inline(always)] fn to_u8(&self) -> u8 { *self as u8 } - #[inline(always)] fn to_u16(&self) -> u16 { *self as u16 } - #[inline(always)] fn to_u32(&self) -> u32 { *self as u32 } - #[inline(always)] fn to_u64(&self) -> u64 { *self as u64 } - #[inline(always)] fn to_uint(&self) -> uint { *self as uint } + #[inline] fn to_u8(&self) -> u8 { *self as u8 } + #[inline] fn to_u16(&self) -> u16 { *self as u16 } + #[inline] fn to_u32(&self) -> u32 { *self as u32 } + #[inline] fn to_u64(&self) -> u64 { *self as u64 } + #[inline] fn to_uint(&self) -> uint { *self as uint } - #[inline(always)] fn to_i8(&self) -> i8 { *self as i8 } - #[inline(always)] fn to_i16(&self) -> i16 { *self as i16 } - #[inline(always)] fn to_i32(&self) -> i32 { *self as i32 } - #[inline(always)] fn to_i64(&self) -> i64 { *self as i64 } - #[inline(always)] fn to_int(&self) -> int { *self as int } + #[inline] fn to_i8(&self) -> i8 { *self as i8 } + #[inline] fn to_i16(&self) -> i16 { *self as i16 } + #[inline] fn to_i32(&self) -> i32 { *self as i32 } + #[inline] fn to_i64(&self) -> i64 { *self as i64 } + #[inline] fn to_int(&self) -> int { *self as int } - #[inline(always)] fn to_f32(&self) -> f32 { *self as f32 } - #[inline(always)] fn to_f64(&self) -> f64 { *self as f64 } - #[inline(always)] fn to_float(&self) -> float { *self as float } + #[inline] fn to_f32(&self) -> f32 { *self as f32 } + #[inline] fn to_f64(&self) -> f64 { *self as f64 } + #[inline] fn to_float(&self) -> float { *self as float } } ) ) diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 75c4fa98a2b5..a062838aacf0 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -42,12 +42,12 @@ pub enum SignFormat { SignAll } -#[inline(always)] +#[inline] fn is_NaN(num: &T) -> bool { *num != *num } -#[inline(always)] +#[inline] fn is_inf(num: &T) -> bool { match NumStrConv::inf() { None => false, @@ -55,7 +55,7 @@ fn is_inf(num: &T) -> bool { } } -#[inline(always)] +#[inline] fn is_neg_inf(num: &T) -> bool { match NumStrConv::neg_inf() { None => false, @@ -63,7 +63,7 @@ fn is_neg_inf(num: &T) -> bool { } } -#[inline(always)] +#[inline] fn is_neg_zero>(num: &T) -> bool { let _0: T = Zero::zero(); let _1: T = One::one(); @@ -83,23 +83,23 @@ pub trait NumStrConv { macro_rules! impl_NumStrConv_Floating (($t:ty) => ( impl NumStrConv for $t { - #[inline(always)] + #[inline] fn NaN() -> Option<$t> { Some( 0.0 / 0.0) } - #[inline(always)] + #[inline] fn inf() -> Option<$t> { Some( 1.0 / 0.0) } - #[inline(always)] + #[inline] fn neg_inf() -> Option<$t> { Some(-1.0 / 0.0) } - #[inline(always)] + #[inline] fn neg_zero() -> Option<$t> { Some(-0.0 ) } - #[inline(always)] + #[inline] fn round_to_zero(&self) -> $t { ( if *self < 0.0 { f64::ceil(*self as f64) } else { f64::floor(*self as f64) } ) as $t } - #[inline(always)] + #[inline] fn fractional_part(&self) -> $t { *self - self.round_to_zero() } @@ -108,13 +108,13 @@ macro_rules! impl_NumStrConv_Floating (($t:ty) => ( macro_rules! impl_NumStrConv_Integer (($t:ty) => ( impl NumStrConv for $t { - #[inline(always)] fn NaN() -> Option<$t> { None } - #[inline(always)] fn inf() -> Option<$t> { None } - #[inline(always)] fn neg_inf() -> Option<$t> { None } - #[inline(always)] fn neg_zero() -> Option<$t> { None } + #[inline] fn NaN() -> Option<$t> { None } + #[inline] fn inf() -> Option<$t> { None } + #[inline] fn neg_inf() -> Option<$t> { None } + #[inline] fn neg_zero() -> Option<$t> { None } - #[inline(always)] fn round_to_zero(&self) -> $t { *self } - #[inline(always)] fn fractional_part(&self) -> $t { 0 } + #[inline] fn round_to_zero(&self) -> $t { *self } + #[inline] fn fractional_part(&self) -> $t { 0 } } )) @@ -381,7 +381,7 @@ pub fn to_str_bytes_common+Neg+Rem+Mul>( num: &T, radix: uint, negative_zero: bool, @@ -632,7 +632,7 @@ pub fn from_str_bytes_common+ * Parses a string as a number. This is a wrapper for * `from_str_bytes_common()`, for details see there. */ -#[inline(always)] +#[inline] pub fn from_str_common+Mul+ Sub+Neg+Add+NumStrConv>( buf: &str, radix: uint, negative: bool, fractional: bool, diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index bcb97ff5a07f..126150c0f1bf 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -95,7 +95,7 @@ pub fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { } impl iter::Times for uint { - #[inline(always)] + #[inline] /// /// A convenience form for basic iteration. Given a uint `x`, /// `for x.times { ... }` executes the given block x times. @@ -117,7 +117,7 @@ impl iter::Times for uint { } /// Returns the smallest power of 2 greater than or equal to `n` -#[inline(always)] +#[inline] pub fn next_power_of_two(n: uint) -> uint { let halfbits: uint = sys::size_of::() * 4u; let mut tmp: uint = n - 1u; diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 2bc1ca9c6733..52f620f97ce8 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -28,42 +28,42 @@ pub static min_value: $T = 0 as $T; pub static max_value: $T = 0 as $T - 1 as $T; /// Calculates the sum of two numbers -#[inline(always)] +#[inline] pub fn add(x: $T, y: $T) -> $T { x + y } /// Subtracts the second number from the first -#[inline(always)] +#[inline] pub fn sub(x: $T, y: $T) -> $T { x - y } /// Multiplies two numbers together -#[inline(always)] +#[inline] pub fn mul(x: $T, y: $T) -> $T { x * y } /// Divides the first argument by the second argument (using integer division) -#[inline(always)] +#[inline] pub fn div(x: $T, y: $T) -> $T { x / y } /// Calculates the integer remainder when x is divided by y (equivalent to the /// '%' operator) -#[inline(always)] +#[inline] pub fn rem(x: $T, y: $T) -> $T { x % y } /// Returns true iff `x < y` -#[inline(always)] +#[inline] pub fn lt(x: $T, y: $T) -> bool { x < y } /// Returns true iff `x <= y` -#[inline(always)] +#[inline] pub fn le(x: $T, y: $T) -> bool { x <= y } /// Returns true iff `x == y` -#[inline(always)] +#[inline] pub fn eq(x: $T, y: $T) -> bool { x == y } /// Returns true iff `x != y` -#[inline(always)] +#[inline] pub fn ne(x: $T, y: $T) -> bool { x != y } /// Returns true iff `x >= y` -#[inline(always)] +#[inline] pub fn ge(x: $T, y: $T) -> bool { x >= y } /// Returns true iff `x > y` -#[inline(always)] +#[inline] pub fn gt(x: $T, y: $T) -> bool { x > y } -#[inline(always)] +#[inline] /** * Iterate through a range with a given step value. * @@ -99,20 +99,20 @@ pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> return true; } -#[inline(always)] +#[inline] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { range_step(lo, hi, 1 as $T_SIGNED, it) } -#[inline(always)] +#[inline] /// Iterate over the range [`hi`..`lo`) pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { range_step(hi, lo, -1 as $T_SIGNED, it) } /// Computes the bitwise complement -#[inline(always)] +#[inline] pub fn compl(i: $T) -> $T { max_value ^ i } @@ -121,37 +121,37 @@ impl Num for $T {} #[cfg(not(test))] impl Ord for $T { - #[inline(always)] + #[inline] fn lt(&self, other: &$T) -> bool { (*self) < (*other) } - #[inline(always)] + #[inline] fn le(&self, other: &$T) -> bool { (*self) <= (*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &$T) -> bool { (*self) >= (*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &$T) -> bool { (*self) > (*other) } } #[cfg(not(test))] impl Eq for $T { - #[inline(always)] + #[inline] fn eq(&self, other: &$T) -> bool { return (*self) == (*other); } - #[inline(always)] + #[inline] fn ne(&self, other: &$T) -> bool { return (*self) != (*other); } } impl Orderable for $T { - #[inline(always)] + #[inline] fn min(&self, other: &$T) -> $T { if *self < *other { *self } else { *other } } - #[inline(always)] + #[inline] fn max(&self, other: &$T) -> $T { if *self > *other { *self } else { *other } } /// Returns the number constrained within the range `mn <= self <= mx`. - #[inline(always)] + #[inline] fn clamp(&self, mn: &$T, mx: &$T) -> $T { cond!( (*self > *mx) { *mx } @@ -162,51 +162,51 @@ impl Orderable for $T { } impl Zero for $T { - #[inline(always)] + #[inline] fn zero() -> $T { 0 } - #[inline(always)] + #[inline] fn is_zero(&self) -> bool { *self == 0 } } impl One for $T { - #[inline(always)] + #[inline] fn one() -> $T { 1 } } #[cfg(not(test))] impl Add<$T,$T> for $T { - #[inline(always)] + #[inline] fn add(&self, other: &$T) -> $T { *self + *other } } #[cfg(not(test))] impl Sub<$T,$T> for $T { - #[inline(always)] + #[inline] fn sub(&self, other: &$T) -> $T { *self - *other } } #[cfg(not(test))] impl Mul<$T,$T> for $T { - #[inline(always)] + #[inline] fn mul(&self, other: &$T) -> $T { *self * *other } } #[cfg(not(test))] impl Div<$T,$T> for $T { - #[inline(always)] + #[inline] fn div(&self, other: &$T) -> $T { *self / *other } } #[cfg(not(test))] impl Rem<$T,$T> for $T { - #[inline(always)] + #[inline] fn rem(&self, other: &$T) -> $T { *self % *other } } #[cfg(not(test))] impl Neg<$T> for $T { - #[inline(always)] + #[inline] fn neg(&self) -> $T { -*self } } @@ -214,27 +214,27 @@ impl Unsigned for $T {} impl Integer for $T { /// Calculates `div` (`\`) and `rem` (`%`) simultaneously - #[inline(always)] + #[inline] fn div_rem(&self, other: &$T) -> ($T,$T) { (*self / *other, *self % *other) } /// Unsigned integer division. Returns the same result as `div` (`/`). - #[inline(always)] + #[inline] fn div_floor(&self, other: &$T) -> $T { *self / *other } /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`). - #[inline(always)] + #[inline] fn mod_floor(&self, other: &$T) -> $T { *self / *other } /// Calculates `div_floor` and `modulo_floor` simultaneously - #[inline(always)] + #[inline] fn div_mod_floor(&self, other: &$T) -> ($T,$T) { (*self / *other, *self % *other) } /// Calculates the Greatest Common Divisor (GCD) of the number and `other` - #[inline(always)] + #[inline] fn gcd(&self, other: &$T) -> $T { // Use Euclid's algorithm let mut (m, n) = (*self, *other); @@ -247,21 +247,21 @@ impl Integer for $T { } /// Calculates the Lowest Common Multiple (LCM) of the number and `other` - #[inline(always)] + #[inline] fn lcm(&self, other: &$T) -> $T { (*self * *other) / self.gcd(other) } /// Returns `true` if the number can be divided by `other` without leaving a remainder - #[inline(always)] + #[inline] fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 } /// Returns `true` if the number is divisible by `2` - #[inline(always)] + #[inline] fn is_even(&self) -> bool { self.is_multiple_of(&2) } /// Returns `true` if the number is not divisible by `2` - #[inline(always)] + #[inline] fn is_odd(&self) -> bool { !self.is_even() } } @@ -269,45 +269,45 @@ impl Bitwise for $T {} #[cfg(not(test))] impl BitOr<$T,$T> for $T { - #[inline(always)] + #[inline] fn bitor(&self, other: &$T) -> $T { *self | *other } } #[cfg(not(test))] impl BitAnd<$T,$T> for $T { - #[inline(always)] + #[inline] fn bitand(&self, other: &$T) -> $T { *self & *other } } #[cfg(not(test))] impl BitXor<$T,$T> for $T { - #[inline(always)] + #[inline] fn bitxor(&self, other: &$T) -> $T { *self ^ *other } } #[cfg(not(test))] impl Shl<$T,$T> for $T { - #[inline(always)] + #[inline] fn shl(&self, other: &$T) -> $T { *self << *other } } #[cfg(not(test))] impl Shr<$T,$T> for $T { - #[inline(always)] + #[inline] fn shr(&self, other: &$T) -> $T { *self >> *other } } #[cfg(not(test))] impl Not<$T> for $T { - #[inline(always)] + #[inline] fn not(&self) -> $T { !*self } } impl Bounded for $T { - #[inline(always)] + #[inline] fn min_value() -> $T { min_value } - #[inline(always)] + #[inline] fn max_value() -> $T { max_value } } @@ -316,35 +316,35 @@ impl Int for $T {} // String conversion functions and impl str -> num /// Parse a string as a number in base 10. -#[inline(always)] +#[inline] pub fn from_str(s: &str) -> Option<$T> { strconv::from_str_common(s, 10u, false, false, false, strconv::ExpNone, false, false) } /// Parse a string as a number in the given base. -#[inline(always)] +#[inline] pub fn from_str_radix(s: &str, radix: uint) -> Option<$T> { strconv::from_str_common(s, radix, false, false, false, strconv::ExpNone, false, false) } /// Parse a byte slice as a number in the given base. -#[inline(always)] +#[inline] pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> { strconv::from_str_bytes_common(buf, radix, false, false, false, strconv::ExpNone, false, false) } impl FromStr for $T { - #[inline(always)] + #[inline] fn from_str(s: &str) -> Option<$T> { from_str(s) } } impl FromStrRadix for $T { - #[inline(always)] + #[inline] fn from_str_radix(s: &str, radix: uint) -> Option<$T> { from_str_radix(s, radix) } @@ -353,7 +353,7 @@ impl FromStrRadix for $T { // String conversion functions and impl num -> str /// Convert to a string as a byte slice in a given base. -#[inline(always)] +#[inline] pub fn to_str_bytes(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); @@ -361,7 +361,7 @@ pub fn to_str_bytes(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { } /// Convert to a string in base 10. -#[inline(always)] +#[inline] pub fn to_str(num: $T) -> ~str { let (buf, _) = strconv::to_str_common(&num, 10u, false, strconv::SignNeg, strconv::DigAll); @@ -369,7 +369,7 @@ pub fn to_str(num: $T) -> ~str { } /// Convert to a string in a given base. -#[inline(always)] +#[inline] pub fn to_str_radix(num: $T, radix: uint) -> ~str { let (buf, _) = strconv::to_str_common(&num, radix, false, strconv::SignNeg, strconv::DigAll); @@ -377,42 +377,42 @@ pub fn to_str_radix(num: $T, radix: uint) -> ~str { } impl ToStr for $T { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_str(*self) } } impl ToStrRadix for $T { - #[inline(always)] + #[inline] fn to_str_radix(&self, radix: uint) -> ~str { to_str_radix(*self, radix) } } impl Primitive for $T { - #[inline(always)] + #[inline] fn bits() -> uint { bits } - #[inline(always)] + #[inline] fn bytes() -> uint { bits / 8 } } impl BitCount for $T { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. - #[inline(always)] + #[inline] fn population_count(&self) -> $T { (*self as $T_SIGNED).population_count() as $T } /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic. - #[inline(always)] + #[inline] fn leading_zeros(&self) -> $T { (*self as $T_SIGNED).leading_zeros() as $T } /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic. - #[inline(always)] + #[inline] fn trailing_zeros(&self) -> $T { (*self as $T_SIGNED).trailing_zeros() as $T } diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index 96bcf4e91074..d0e1cfd15f48 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -73,7 +73,7 @@ pub trait Buildable { fn build_sized(size: uint, builder: &fn(push: &fn(A))) -> Self; } -#[inline(always)] +#[inline] pub fn _eachi>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool { let mut i = 0; for this.each |a| { @@ -89,7 +89,7 @@ pub fn eachi>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool { _eachi(this, blk) } -#[inline(always)] +#[inline] pub fn all>(this: &IA, blk: &fn(&A) -> bool) -> bool { for this.each |a| { if !blk(a) { @@ -99,7 +99,7 @@ pub fn all>(this: &IA, blk: &fn(&A) -> bool) -> bool { return true; } -#[inline(always)] +#[inline] pub fn any>(this: &IA, blk: &fn(&A) -> bool) -> bool { for this.each |a| { if blk(a) { @@ -109,7 +109,7 @@ pub fn any>(this: &IA, blk: &fn(&A) -> bool) -> bool { return false; } -#[inline(always)] +#[inline] pub fn filter_to_vec>(this: &IA, prd: &fn(&A) -> bool) -> ~[A] { @@ -120,7 +120,7 @@ pub fn filter_to_vec>(this: &IA, } } -#[inline(always)] +#[inline] pub fn map_to_vec>(this: &IA, op: &fn(&A) -> B) -> ~[B] { do vec::build_sized_opt(this.size_hint()) |push| { for this.each |a| { @@ -129,7 +129,7 @@ pub fn map_to_vec>(this: &IA, op: &fn(&A) -> B) -> ~[B] { } } -#[inline(always)] +#[inline] pub fn flat_map_to_vec,IB:BaseIter>(this: &IA, op: &fn(&A) -> IB) -> ~[B] { @@ -142,7 +142,7 @@ pub fn flat_map_to_vec,IB:BaseIter>(this: &IA, } } -#[inline(always)] +#[inline] pub fn foldl>(this: &IA, b0: B, blk: &fn(&B, &A) -> B) -> B { let mut b = b0; @@ -152,12 +152,12 @@ pub fn foldl>(this: &IA, b0: B, blk: &fn(&B, &A) -> B) b } -#[inline(always)] +#[inline] pub fn to_vec>(this: &IA) -> ~[A] { map_to_vec(this, |&x| x) } -#[inline(always)] +#[inline] pub fn contains>(this: &IA, x: &A) -> bool { for this.each |a| { if *a == *x { return true; } @@ -165,7 +165,7 @@ pub fn contains>(this: &IA, x: &A) -> bool { return false; } -#[inline(always)] +#[inline] pub fn count>(this: &IA, x: &A) -> uint { do foldl(this, 0) |count, value| { if *value == *x { @@ -176,7 +176,7 @@ pub fn count>(this: &IA, x: &A) -> uint { } } -#[inline(always)] +#[inline] pub fn position>(this: &IA, f: &fn(&A) -> bool) -> Option { let mut i = 0; @@ -187,7 +187,7 @@ pub fn position>(this: &IA, f: &fn(&A) -> bool) return None; } -#[inline(always)] +#[inline] pub fn find>(this: &IA, f: &fn(&A) -> bool) -> Option { for this.each |i| { @@ -208,7 +208,7 @@ pub fn find>(this: &IA, f: &fn(&A) -> bool) * as an argument a function that will push an element * onto the sequence being constructed. */ -#[inline(always)] +#[inline] pub fn build>(builder: &fn(push: &fn(A))) -> B { Buildable::build_sized(4, builder) } @@ -226,7 +226,7 @@ pub fn build>(builder: &fn(push: &fn(A))) -> B { * as an argument a function that will push an element * onto the sequence being constructed. */ -#[inline(always)] +#[inline] pub fn build_sized_opt>(size: Option, builder: &fn(push: &fn(A))) -> B { Buildable::build_sized(size.get_or_default(4), builder) @@ -236,7 +236,7 @@ pub fn build_sized_opt>(size: Option, /// Applies a function to each element of an iterable and returns the results /// in a sequence built via `BU`. See also `map_to_vec`. -#[inline(always)] +#[inline] pub fn map,U,BU: Buildable>(v: &IT, f: &fn(&T) -> U) -> BU { do build_sized_opt(v.size_hint()) |push| { @@ -252,7 +252,7 @@ pub fn map,U,BU: Buildable>(v: &IT, f: &fn(&T) -> U) * Creates a generic sequence of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -#[inline(always)] +#[inline] pub fn from_fn>(n_elts: uint, op: InitOp) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0u; @@ -266,7 +266,7 @@ pub fn from_fn>(n_elts: uint, op: InitOp) -> BT { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value `t`. */ -#[inline(always)] +#[inline] pub fn from_elem>(n_elts: uint, t: T) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0; @@ -275,7 +275,7 @@ pub fn from_elem>(n_elts: uint, t: T) -> BT { } /// Appends two generic sequences. -#[inline(always)] +#[inline] pub fn append,BT:Buildable>(lhs: &IT, rhs: &IT) -> BT { let size_opt = lhs.size_hint().chain_ref( @@ -288,7 +288,7 @@ pub fn append,BT:Buildable>(lhs: &IT, rhs: &IT) /// Copies a generic sequence, possibly converting it to a different /// type of sequence. -#[inline(always)] +#[inline] pub fn copy_seq,BT:Buildable>(v: &IT) -> BT { do build_sized_opt(v.size_hint()) |push| { for v.each |x| { push(copy *x); } diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 30394cb21afd..7dc6b7fe4b16 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -89,7 +89,7 @@ impl Ord for Option { } impl> Add, Option> for Option { - #[inline(always)] + #[inline] fn add(&self, other: &Option) -> Option { match (&*self, &*other) { (&None, &None) => None, @@ -126,12 +126,12 @@ impl Option { } /// Returns true if the option contains some value - #[inline(always)] + #[inline] pub fn is_some(&const self) -> bool { !self.is_none() } /// Update an optional value by optionally running its content through a /// function that returns an option. - #[inline(always)] + #[inline] pub fn chain(self, f: &fn(t: T) -> Option) -> Option { match self { Some(t) => f(t), @@ -140,7 +140,7 @@ impl Option { } /// Returns the leftmost Some() value, or None if both are None. - #[inline(always)] + #[inline] pub fn or(self, optb: Option) -> Option { match self { Some(opta) => Some(opta), @@ -150,7 +150,7 @@ impl Option { /// Update an optional value by optionally running its content by reference /// through a function that returns an option. - #[inline(always)] + #[inline] pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option) -> Option { match *self { @@ -160,27 +160,27 @@ impl Option { } /// Maps a `some` value from one type to another by reference - #[inline(always)] + #[inline] pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option { match *self { Some(ref x) => Some(f(x)), None => None } } /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. - #[inline(always)] + #[inline] pub fn map_consume(self, f: &fn(v: T) -> U) -> Option { match self { None => None, Some(v) => Some(f(v)) } } /// Applies a function to the contained value or returns a default - #[inline(always)] + #[inline] pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U { match *self { None => def, Some(ref t) => f(t) } } /// As `map_default`, but consumes the option and gives `f` /// ownership to avoid copying. - #[inline(always)] + #[inline] pub fn map_consume_default(self, def: U, f: &fn(v: T) -> U) -> U { match self { None => def, Some(v) => f(v) } } @@ -215,7 +215,7 @@ impl Option { Instead, prefer to use pattern matching and handle the `None` case explicitly. */ - #[inline(always)] + #[inline] pub fn get_ref<'a>(&'a self) -> &'a T { match *self { Some(ref x) => x, @@ -237,7 +237,7 @@ impl Option { Instead, prefer to use pattern matching and handle the `None` case explicitly. */ - #[inline(always)] + #[inline] pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T { match *self { Some(ref mut x) => x, @@ -245,7 +245,7 @@ impl Option { } } - #[inline(always)] + #[inline] pub fn unwrap(self) -> T { /*! Moves a value out of an option type and returns it. @@ -277,7 +277,7 @@ impl Option { * * Fails if the value equals `None`. */ - #[inline(always)] + #[inline] pub fn swap_unwrap(&mut self) -> T { if self.is_none() { fail!("option::swap_unwrap none") } util::replace(self, None).unwrap() @@ -291,7 +291,7 @@ impl Option { * * Fails if the value equals `none` */ - #[inline(always)] + #[inline] pub fn expect(self, reason: &str) -> T { match self { Some(val) => val, @@ -315,7 +315,7 @@ impl Option { Instead, prefer to use pattern matching and handle the `None` case explicitly. */ - #[inline(always)] + #[inline] pub fn get(self) -> T { match self { Some(x) => return x, @@ -324,13 +324,13 @@ impl Option { } /// Returns the contained value or a default - #[inline(always)] + #[inline] pub fn get_or_default(self, def: T) -> T { match self { Some(x) => x, None => def } } /// Applies a function zero or more times until the result is none. - #[inline(always)] + #[inline] pub fn while_some(self, blk: &fn(v: T) -> Option) { let mut opt = self; while opt.is_some() { @@ -341,7 +341,7 @@ impl Option { impl Option { /// Returns the contained value or zero (for this type) - #[inline(always)] + #[inline] pub fn get_or_zero(self) -> T { match self { Some(x) => x, diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs index 3262fb4afdcf..e7a6e38fdb08 100644 --- a/src/libstd/owned.rs +++ b/src/libstd/owned.rs @@ -14,20 +14,20 @@ #[cfg(not(test))] impl Eq for ~T { - #[inline(always)] + #[inline] fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) } - #[inline(always)] + #[inline] fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) } } #[cfg(not(test))] impl Ord for ~T { - #[inline(always)] + #[inline] fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) } - #[inline(always)] + #[inline] fn le(&self, other: &~T) -> bool { *(*self) <= *(*other) } - #[inline(always)] + #[inline] fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) } - #[inline(always)] + #[inline] fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) } } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9c4e8f083584..9c51526aa7f6 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -904,7 +904,7 @@ pub mod windows { use libc; use option::{None, Option, Some}; - #[inline(always)] + #[inline] pub fn is_sep(u: char) -> bool { u == '/' || u == '\\' } diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index cd5a3182f6b8..b505602702b4 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -19,31 +19,31 @@ use unstable::intrinsics; use uint; /// Calculate the offset from a pointer -#[inline(always)] +#[inline] pub fn offset(ptr: *T, count: uint) -> *T { (ptr as uint + count * sys::size_of::()) as *T } /// Calculate the offset from a const pointer -#[inline(always)] +#[inline] pub fn const_offset(ptr: *const T, count: uint) -> *const T { (ptr as uint + count * sys::size_of::()) as *T } /// Calculate the offset from a mut pointer -#[inline(always)] +#[inline] pub fn mut_offset(ptr: *mut T, count: uint) -> *mut T { (ptr as uint + count * sys::size_of::()) as *mut T } /// Return the offset of the first null pointer in `buf`. -#[inline(always)] +#[inline] pub unsafe fn buf_len(buf: **T) -> uint { position(buf, |i| *i == null()) } /// Return the first offset `i` such that `f(buf[i]) == true`. -#[inline(always)] +#[inline] pub unsafe fn position(buf: *T, f: &fn(&T) -> bool) -> uint { let mut i = 0; loop { @@ -53,19 +53,19 @@ pub unsafe fn position(buf: *T, f: &fn(&T) -> bool) -> uint { } /// Create an unsafe null pointer -#[inline(always)] +#[inline] pub fn null() -> *T { 0 as *T } /// Create an unsafe mutable null pointer -#[inline(always)] +#[inline] pub fn mut_null() -> *mut T { 0 as *mut T } /// Returns true if the pointer is equal to the null pointer. -#[inline(always)] +#[inline] pub fn is_null(ptr: *const T) -> bool { ptr == null() } /// Returns true if the pointer is not equal to the null pointer. -#[inline(always)] +#[inline] pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } /** @@ -74,7 +74,7 @@ pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "32", stage0)] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove32; @@ -88,7 +88,7 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "32", not(stage0))] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove32; @@ -101,7 +101,7 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "64", stage0)] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove64; @@ -115,7 +115,7 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "64", not(stage0))] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove64; @@ -128,7 +128,7 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may *not* overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "32", stage0)] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove32; @@ -142,7 +142,7 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may *not* overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "32", not(stage0))] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memcpy32; @@ -155,7 +155,7 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may *not* overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "64", stage0)] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove64; @@ -169,7 +169,7 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u * Copies `count` elements (not bytes) from `src` to `dst`. The source * and destination may *not* overlap. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "64", not(stage0))] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memcpy64; @@ -180,7 +180,7 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u * Invokes memset on the specified pointer, setting `count * size_of::()` * bytes of memory starting at `dst` to `c`. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "32", not(stage0))] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { use unstable::intrinsics::memset32; @@ -191,7 +191,7 @@ pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { * Invokes memset on the specified pointer, setting `count * size_of::()` * bytes of memory starting at `dst` to `c`. */ -#[inline(always)] +#[inline] #[cfg(target_word_size = "64", not(stage0))] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { use unstable::intrinsics::memset64; @@ -222,26 +222,26 @@ pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { * Replace the value at a mutable location with a new one, returning the old * value, without deinitialising or copying either one. */ -#[inline(always)] +#[inline] pub unsafe fn replace_ptr(dest: *mut T, mut src: T) -> T { swap_ptr(dest, &mut src); src } /// Transform a region pointer - &T - to an unsafe pointer - *T. -#[inline(always)] +#[inline] pub fn to_unsafe_ptr(thing: &T) -> *T { thing as *T } /// Transform a const region pointer - &const T - to a const unsafe pointer - *const T. -#[inline(always)] +#[inline] pub fn to_const_unsafe_ptr(thing: &const T) -> *const T { thing as *const T } /// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T. -#[inline(always)] +#[inline] pub fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { thing as *mut T } @@ -297,11 +297,11 @@ pub trait RawPtr { /// Extension methods for immutable pointers impl RawPtr for *T { /// Returns true if the pointer is equal to the null pointer. - #[inline(always)] + #[inline] fn is_null(&const self) -> bool { is_null(*self) } /// Returns true if the pointer is not equal to the null pointer. - #[inline(always)] + #[inline] fn is_not_null(&const self) -> bool { is_not_null(*self) } /// @@ -314,7 +314,7 @@ impl RawPtr for *T { /// that this is still an unsafe operation because the returned value could /// be pointing to invalid memory. /// - #[inline(always)] + #[inline] unsafe fn to_option(&const self) -> Option<&T> { if self.is_null() { None } else { Some(cast::transmute(*self)) @@ -322,18 +322,18 @@ impl RawPtr for *T { } /// Calculates the offset from a pointer. - #[inline(always)] + #[inline] fn offset(&self, count: uint) -> *T { offset(*self, count) } } /// Extension methods for mutable pointers impl RawPtr for *mut T { /// Returns true if the pointer is equal to the null pointer. - #[inline(always)] + #[inline] fn is_null(&const self) -> bool { is_null(*self) } /// Returns true if the pointer is not equal to the null pointer. - #[inline(always)] + #[inline] fn is_not_null(&const self) -> bool { is_not_null(*self) } /// @@ -346,7 +346,7 @@ impl RawPtr for *mut T { /// that this is still an unsafe operation because the returned value could /// be pointing to invalid memory. /// - #[inline(always)] + #[inline] unsafe fn to_option(&const self) -> Option<&T> { if self.is_null() { None } else { Some(cast::transmute(*self)) @@ -354,37 +354,37 @@ impl RawPtr for *mut T { } /// Calculates the offset from a mutable pointer. - #[inline(always)] + #[inline] fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) } } // Equality for pointers #[cfg(not(test))] impl Eq for *const T { - #[inline(always)] + #[inline] fn eq(&self, other: &*const T) -> bool { (*self as uint) == (*other as uint) } - #[inline(always)] + #[inline] fn ne(&self, other: &*const T) -> bool { !self.eq(other) } } // Comparison for pointers #[cfg(not(test))] impl Ord for *const T { - #[inline(always)] + #[inline] fn lt(&self, other: &*const T) -> bool { (*self as uint) < (*other as uint) } - #[inline(always)] + #[inline] fn le(&self, other: &*const T) -> bool { (*self as uint) <= (*other as uint) } - #[inline(always)] + #[inline] fn ge(&self, other: &*const T) -> bool { (*self as uint) >= (*other as uint) } - #[inline(always)] + #[inline] fn gt(&self, other: &*const T) -> bool { (*self as uint) > (*other as uint) } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 2d73ed0c6a1c..739e3dfedc7f 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -451,7 +451,7 @@ pub trait RngUtil { /// Extension methods for random number generators impl RngUtil for R { /// Return a random value for a Rand type - #[inline(always)] + #[inline] fn gen(&mut self) -> T { Rand::rand(self) } @@ -762,7 +762,7 @@ impl IsaacRng { } impl Rng for IsaacRng { - #[inline(always)] + #[inline] fn next(&mut self) -> u32 { if self.cnt == 0 { // make some more numbers @@ -862,7 +862,7 @@ pub fn task_rng() -> @@mut IsaacRng { // Allow direct chaining with `task_rng` impl Rng for @@mut R { - #[inline(always)] + #[inline] fn next(&mut self) -> u32 { match *self { @@ref mut r => r.next() diff --git a/src/libstd/rand/distributions.rs b/src/libstd/rand/distributions.rs index f08d967cbe02..6f4f1a34977e 100644 --- a/src/libstd/rand/distributions.rs +++ b/src/libstd/rand/distributions.rs @@ -26,7 +26,7 @@ use rand::{Rng,Rand}; mod ziggurat_tables; // inlining should mean there is no performance penalty for this -#[inline(always)] +#[inline] fn ziggurat(rng: &mut R, center_u: bool, X: ziggurat_tables::ZigTable, @@ -77,11 +77,11 @@ pub struct StandardNormal(f64); impl Rand for StandardNormal { fn rand(rng: &mut R) -> StandardNormal { - #[inline(always)] + #[inline] fn pdf(x: f64) -> f64 { f64::exp((-x*x/2.0) as f64) as f64 } - #[inline(always)] + #[inline] fn zero_case(rng: &mut R, u: f64) -> f64 { // compute a random number in the tail by hand @@ -131,11 +131,11 @@ pub struct Exp1(f64); impl Rand for Exp1 { #[inline] fn rand(rng: &mut R) -> Exp1 { - #[inline(always)] + #[inline] fn pdf(x: f64) -> f64 { f64::exp(-x) } - #[inline(always)] + #[inline] fn zero_case(rng: &mut R, _u: f64) -> f64 { ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen()) } diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 1eb3d3a0daaa..d276abf0c8b3 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -35,7 +35,7 @@ pub trait MovePtr { } /// Helper function for alignment calculation. -#[inline(always)] +#[inline] pub fn align(size: uint, align: uint) -> uint { ((size + align) - 1u) & !(align - 1u) } @@ -49,26 +49,26 @@ pub fn MovePtrAdaptor(v: V) -> MovePtrAdaptor { } impl MovePtrAdaptor { - #[inline(always)] + #[inline] pub fn bump(&self, sz: uint) { do self.inner.move_ptr() |p| { ((p as uint) + sz) as *c_void }; } - #[inline(always)] + #[inline] pub fn align(&self, a: uint) { do self.inner.move_ptr() |p| { align(p as uint, a) as *c_void }; } - #[inline(always)] + #[inline] pub fn align_to(&self) { self.align(sys::min_align_of::()); } - #[inline(always)] + #[inline] pub fn bump_past(&self) { self.bump(sys::size_of::()); } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index b7ff1acea139..ab3f83d34d59 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -164,7 +164,7 @@ pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor { } impl MovePtr for ReprVisitor { - #[inline(always)] + #[inline] fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) { *self.ptr = adjustment(*self.ptr); } @@ -179,7 +179,7 @@ impl MovePtr for ReprVisitor { impl ReprVisitor { // Various helpers for the TyVisitor impl - #[inline(always)] + #[inline] pub fn get(&self, f: &fn(&T)) -> bool { unsafe { f(transmute::<*c_void,&T>(*self.ptr)); @@ -187,12 +187,12 @@ impl ReprVisitor { true } - #[inline(always)] + #[inline] pub fn visit_inner(&self, inner: *TyDesc) -> bool { self.visit_ptr_inner(*self.ptr, inner) } - #[inline(always)] + #[inline] pub fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool { unsafe { let u = ReprVisitor(ptr, self.writer); @@ -202,7 +202,7 @@ impl ReprVisitor { } } - #[inline(always)] + #[inline] pub fn write(&self) -> bool { do self.get |v:&T| { v.write_repr(self.writer); diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 24751b66925e..6cef5c33de06 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -38,7 +38,7 @@ pub enum Result { * * If the result is an error */ -#[inline(always)] +#[inline] pub fn get(res: &Result) -> T { match *res { Ok(ref t) => copy *t, @@ -54,7 +54,7 @@ pub fn get(res: &Result) -> T { * * If the result is an error */ -#[inline(always)] +#[inline] pub fn get_ref<'a, T, U>(res: &'a Result) -> &'a T { match *res { Ok(ref t) => t, @@ -70,7 +70,7 @@ pub fn get_ref<'a, T, U>(res: &'a Result) -> &'a T { * * If the result is not an error */ -#[inline(always)] +#[inline] pub fn get_err(res: &Result) -> U { match *res { Err(ref u) => copy *u, @@ -79,7 +79,7 @@ pub fn get_err(res: &Result) -> U { } /// Returns true if the result is `ok` -#[inline(always)] +#[inline] pub fn is_ok(res: &Result) -> bool { match *res { Ok(_) => true, @@ -88,7 +88,7 @@ pub fn is_ok(res: &Result) -> bool { } /// Returns true if the result is `err` -#[inline(always)] +#[inline] pub fn is_err(res: &Result) -> bool { !is_ok(res) } @@ -99,7 +99,7 @@ pub fn is_err(res: &Result) -> bool { * `ok` result variants are converted to `either::right` variants, `err` * result variants are converted to `either::left`. */ -#[inline(always)] +#[inline] pub fn to_either(res: &Result) -> Either { match *res { @@ -122,7 +122,7 @@ pub fn to_either(res: &Result) * ok(parse_bytes(buf)) * } */ -#[inline(always)] +#[inline] pub fn chain(res: Result, op: &fn(T) -> Result) -> Result { match res { @@ -139,7 +139,7 @@ pub fn chain(res: Result, op: &fn(T) * immediately returned. This function can be used to pass through a * successful result while handling an error. */ -#[inline(always)] +#[inline] pub fn chain_err( res: Result, op: &fn(t: V) -> Result) @@ -164,7 +164,7 @@ pub fn chain_err( * print_buf(buf) * } */ -#[inline(always)] +#[inline] pub fn iter(res: &Result, f: &fn(&T)) { match *res { Ok(ref t) => f(t), @@ -180,7 +180,7 @@ pub fn iter(res: &Result, f: &fn(&T)) { * This function can be used to pass through a successful result while * handling an error. */ -#[inline(always)] +#[inline] pub fn iter_err(res: &Result, f: &fn(&E)) { match *res { Ok(_) => (), @@ -202,7 +202,7 @@ pub fn iter_err(res: &Result, f: &fn(&E)) { * parse_bytes(buf) * } */ -#[inline(always)] +#[inline] pub fn map(res: &Result, op: &fn(&T) -> U) -> Result { match *res { @@ -219,7 +219,7 @@ pub fn map(res: &Result, op: &fn(&T) -> U) * is immediately returned. This function can be used to pass through a * successful result while handling an error. */ -#[inline(always)] +#[inline] pub fn map_err(res: &Result, op: &fn(&E) -> F) -> Result { match *res { @@ -229,53 +229,53 @@ pub fn map_err(res: &Result, op: &fn(&E) -> F) } impl Result { - #[inline(always)] + #[inline] pub fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) } - #[inline(always)] + #[inline] pub fn is_ok(&self) -> bool { is_ok(self) } - #[inline(always)] + #[inline] pub fn is_err(&self) -> bool { is_err(self) } - #[inline(always)] + #[inline] pub fn iter(&self, f: &fn(&T)) { iter(self, f) } - #[inline(always)] + #[inline] pub fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) } - #[inline(always)] + #[inline] pub fn unwrap(self) -> T { unwrap(self) } - #[inline(always)] + #[inline] pub fn unwrap_err(self) -> E { unwrap_err(self) } - #[inline(always)] + #[inline] pub fn chain(self, op: &fn(T) -> Result) -> Result { chain(self, op) } - #[inline(always)] + #[inline] pub fn chain_err(self, op: &fn(E) -> Result) -> Result { chain_err(self, op) } } impl Result { - #[inline(always)] + #[inline] pub fn get(&self) -> T { get(self) } - #[inline(always)] + #[inline] pub fn map_err(&self, op: &fn(&E) -> F) -> Result { map_err(self, op) } } impl Result { - #[inline(always)] + #[inline] pub fn get_err(&self) -> E { get_err(self) } - #[inline(always)] + #[inline] pub fn map(&self, op: &fn(&T) -> U) -> Result { map(self, op) } @@ -298,7 +298,7 @@ impl Result { * assert!(incd == ~[2u, 3u, 4u]); * } */ -#[inline(always)] +#[inline] pub fn map_vec( ts: &[T], op: &fn(&T) -> Result) -> Result<~[V],U> { @@ -312,7 +312,7 @@ pub fn map_vec( return Ok(vs); } -#[inline(always)] +#[inline] #[allow(missing_doc)] pub fn map_opt( o_t: &Option, op: &fn(&T) -> Result) -> Result,U> { @@ -335,7 +335,7 @@ pub fn map_opt( * used in 'careful' code contexts where it is both appropriate and easy * to accommodate an error like the vectors being of different lengths. */ -#[inline(always)] +#[inline] pub fn map_vec2(ss: &[S], ts: &[T], op: &fn(&S,&T) -> Result) -> Result<~[V],U> { @@ -358,7 +358,7 @@ pub fn map_vec2(ss: &[S], ts: &[T], * error. This could be implemented using `map_zip()` but it is more efficient * on its own as no result vector is built. */ -#[inline(always)] +#[inline] pub fn iter_vec2(ss: &[S], ts: &[T], op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> { @@ -376,7 +376,7 @@ pub fn iter_vec2(ss: &[S], ts: &[T], } /// Unwraps a result, assuming it is an `ok(T)` -#[inline(always)] +#[inline] pub fn unwrap(res: Result) -> T { match res { Ok(t) => t, @@ -385,7 +385,7 @@ pub fn unwrap(res: Result) -> T { } /// Unwraps a result, assuming it is an `err(U)` -#[inline(always)] +#[inline] pub fn unwrap_err(res: Result) -> U { match res { Err(u) => u, diff --git a/src/libstd/rt/context.rs b/src/libstd/rt/context.rs index d5ca8473ceea..09ba869549fd 100644 --- a/src/libstd/rt/context.rs +++ b/src/libstd/rt/context.rs @@ -207,7 +207,7 @@ fn align_down(sp: *mut uint) -> *mut uint { } // XXX: ptr::offset is positive ints only -#[inline(always)] +#[inline] pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { use core::sys::size_of; (ptr as int + count * (size_of::() as int)) as *mut T diff --git a/src/libstd/str.rs b/src/libstd/str.rs index d8aab1a8dcc5..04f5247782b0 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -106,21 +106,21 @@ pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str { } /// Copy a slice into a new unique str -#[inline(always)] +#[inline] pub fn to_owned(s: &str) -> ~str { unsafe { raw::slice_bytes_owned(s, 0, s.len()) } } impl ToStr for ~str { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_owned(*self) } } impl<'self> ToStr for &'self str { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_owned(*self) } } impl ToStr for @str { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { to_owned(*self) } } @@ -241,26 +241,26 @@ pub trait CharEq { fn only_ascii(&self) -> bool; } impl CharEq for char { - #[inline(always)] + #[inline] fn matches(&self, c: char) -> bool { *self == c } fn only_ascii(&self) -> bool { (*self as uint) < 128 } } impl<'self> CharEq for &'self fn(char) -> bool { - #[inline(always)] + #[inline] fn matches(&self, c: char) -> bool { (*self)(c) } fn only_ascii(&self) -> bool { false } } impl CharEq for extern "Rust" fn(char) -> bool { - #[inline(always)] + #[inline] fn matches(&self, c: char) -> bool { (*self)(c) } fn only_ascii(&self) -> bool { false } } impl<'self, C: CharEq> CharEq for &'self [C] { - #[inline(always)] + #[inline] fn matches(&self, c: char) -> bool { self.iter().any_(|m| m.matches(c)) } @@ -705,7 +705,7 @@ impl<'self> StrUtil for &'self str { /** * Deprecated. Use the `as_c_str` method on strings instead. */ -#[inline(always)] +#[inline] pub fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { s.as_c_str(f) } @@ -718,7 +718,7 @@ pub fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { * indexable area for a null byte, as is the case in slices pointing * to full strings, or suffixes of them. */ -#[inline(always)] +#[inline] pub fn as_buf(s: &str, f: &fn(*u8, uint) -> T) -> T { unsafe { let v : *(*u8,uint) = transmute(&s); @@ -915,7 +915,7 @@ pub mod traits { use super::{Str, eq_slice}; impl<'self> Add<&'self str,~str> for &'self str { - #[inline(always)] + #[inline] fn add(&self, rhs: & &'self str) -> ~str { let mut ret = self.to_owned(); ret.push_str(*rhs); @@ -949,98 +949,98 @@ pub mod traits { } impl<'self> Eq for &'self str { - #[inline(always)] + #[inline] fn eq(&self, other: & &'self str) -> bool { eq_slice((*self), (*other)) } - #[inline(always)] + #[inline] fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) } } impl Eq for ~str { - #[inline(always)] + #[inline] fn eq(&self, other: &~str) -> bool { eq_slice((*self), (*other)) } - #[inline(always)] + #[inline] fn ne(&self, other: &~str) -> bool { !(*self).eq(other) } } impl Eq for @str { - #[inline(always)] + #[inline] fn eq(&self, other: &@str) -> bool { eq_slice((*self), (*other)) } - #[inline(always)] + #[inline] fn ne(&self, other: &@str) -> bool { !(*self).eq(other) } } impl<'self> TotalEq for &'self str { - #[inline(always)] + #[inline] fn equals(&self, other: & &'self str) -> bool { eq_slice((*self), (*other)) } } impl TotalEq for ~str { - #[inline(always)] + #[inline] fn equals(&self, other: &~str) -> bool { eq_slice((*self), (*other)) } } impl TotalEq for @str { - #[inline(always)] + #[inline] fn equals(&self, other: &@str) -> bool { eq_slice((*self), (*other)) } } impl<'self> Ord for &'self str { - #[inline(always)] + #[inline] fn lt(&self, other: & &'self str) -> bool { self.cmp(other) == Less } - #[inline(always)] + #[inline] fn le(&self, other: & &'self str) -> bool { self.cmp(other) != Greater } - #[inline(always)] + #[inline] fn ge(&self, other: & &'self str) -> bool { self.cmp(other) != Less } - #[inline(always)] + #[inline] fn gt(&self, other: & &'self str) -> bool { self.cmp(other) == Greater } } impl Ord for ~str { - #[inline(always)] + #[inline] fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less } - #[inline(always)] + #[inline] fn le(&self, other: &~str) -> bool { self.cmp(other) != Greater } - #[inline(always)] + #[inline] fn ge(&self, other: &~str) -> bool { self.cmp(other) != Less } - #[inline(always)] + #[inline] fn gt(&self, other: &~str) -> bool { self.cmp(other) == Greater } } impl Ord for @str { - #[inline(always)] + #[inline] fn lt(&self, other: &@str) -> bool { self.cmp(other) == Less } - #[inline(always)] + #[inline] fn le(&self, other: &@str) -> bool { self.cmp(other) != Greater } - #[inline(always)] + #[inline] fn ge(&self, other: &@str) -> bool { self.cmp(other) != Less } - #[inline(always)] + #[inline] fn gt(&self, other: &@str) -> bool { self.cmp(other) == Greater } } impl<'self, S: Str> Equiv for &'self str { - #[inline(always)] + #[inline] fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } } impl<'self, S: Str> Equiv for @str { - #[inline(always)] + #[inline] fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } } impl<'self, S: Str> Equiv for ~str { - #[inline(always)] + #[inline] fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } } } @@ -1055,17 +1055,17 @@ pub trait Str { } impl<'self> Str for &'self str { - #[inline(always)] + #[inline] fn as_slice<'a>(&'a self) -> &'a str { *self } } impl<'self> Str for ~str { - #[inline(always)] + #[inline] fn as_slice<'a>(&'a self) -> &'a str { let s: &'a str = *self; s } } impl<'self> Str for @str { - #[inline(always)] + #[inline] fn as_slice<'a>(&'a self) -> &'a str { let s: &'a str = *self; s } @@ -1311,7 +1311,7 @@ impl<'self> StrSlice<'self> for &'self str { #[inline] fn is_alphanumeric(&self) -> bool { self.iter().all(char::is_alphanumeric) } /// Returns the size in bytes not counting the null terminator - #[inline(always)] + #[inline] fn len(&self) -> uint { do as_buf(*self) |_p, n| { n - 1u } } @@ -1854,7 +1854,7 @@ impl<'self> StrSlice<'self> for &'self str { * assert!(string.subslice_offset(lines[2]) == 4); // &"c" * ~~~ */ - #[inline(always)] + #[inline] fn subslice_offset(&self, inner: &str) -> uint { do as_buf(*self) |a, a_len| { do as_buf(inner) |b, b_len| { @@ -1925,7 +1925,7 @@ pub trait OwnedStr { impl OwnedStr for ~str { /// Appends a string slice to the back of a string, without overallocating - #[inline(always)] + #[inline] fn push_str_no_overallocate(&mut self, rhs: &str) { unsafe { let llen = self.len(); @@ -2078,7 +2078,7 @@ impl OwnedStr for ~str { * * s - A string * * n - The number of bytes to reserve space for */ - #[inline(always)] + #[inline] pub fn reserve(&mut self, n: uint) { unsafe { let v: *mut ~[u8] = cast::transmute(self); @@ -2106,7 +2106,7 @@ impl OwnedStr for ~str { * * s - A string * * n - The number of bytes to reserve space for */ - #[inline(always)] + #[inline] fn reserve_at_least(&mut self, n: uint) { self.reserve(uint::next_power_of_two(n + 1u) - 1u) } @@ -2131,7 +2131,7 @@ impl OwnedStr for ~str { } impl Clone for ~str { - #[inline(always)] + #[inline] fn clone(&self) -> ~str { to_owned(*self) } diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs index 635510b3a78f..c71765f911af 100644 --- a/src/libstd/str/ascii.rs +++ b/src/libstd/str/ascii.rs @@ -25,19 +25,19 @@ pub struct Ascii { priv chr: u8 } impl Ascii { /// Converts a ascii character into a `u8`. - #[inline(always)] + #[inline] pub fn to_byte(self) -> u8 { self.chr } /// Converts a ascii character into a `char`. - #[inline(always)] + #[inline] pub fn to_char(self) -> char { self.chr as char } /// Convert to lowercase. - #[inline(always)] + #[inline] pub fn to_lower(self) -> Ascii { if self.chr >= 65 && self.chr <= 90 { Ascii{chr: self.chr | 0x20 } @@ -47,7 +47,7 @@ impl Ascii { } /// Convert to uppercase. - #[inline(always)] + #[inline] pub fn to_upper(self) -> Ascii { if self.chr >= 97 && self.chr <= 122 { Ascii{chr: self.chr & !0x20 } @@ -57,14 +57,14 @@ impl Ascii { } /// Compares two ascii characters of equality, ignoring case. - #[inline(always)] + #[inline] pub fn eq_ignore_case(self, other: Ascii) -> bool { self.to_lower().chr == other.to_lower().chr } } impl ToStr for Ascii { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { str::from_bytes(['\'' as u8, self.chr, '\'' as u8]) } } @@ -81,18 +81,18 @@ pub trait AsciiCast { } impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] { - #[inline(always)] + #[inline] fn to_ascii(&self) -> &'self[Ascii] { assert!(self.is_ascii()); unsafe {self.to_ascii_nocheck()} } - #[inline(always)] + #[inline] unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] { cast::transmute(*self) } - #[inline(always)] + #[inline] fn is_ascii(&self) -> bool { for self.each |b| { if !b.is_ascii() { return false; } @@ -102,55 +102,55 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] { } impl<'self> AsciiCast<&'self[Ascii]> for &'self str { - #[inline(always)] + #[inline] fn to_ascii(&self) -> &'self[Ascii] { assert!(self.is_ascii()); unsafe {self.to_ascii_nocheck()} } - #[inline(always)] + #[inline] unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] { let (p,len): (*u8, uint) = cast::transmute(*self); cast::transmute((p, len - 1)) } - #[inline(always)] + #[inline] fn is_ascii(&self) -> bool { self.bytes_iter().all(|b| b.is_ascii()) } } impl AsciiCast for u8 { - #[inline(always)] + #[inline] fn to_ascii(&self) -> Ascii { assert!(self.is_ascii()); unsafe {self.to_ascii_nocheck()} } - #[inline(always)] + #[inline] unsafe fn to_ascii_nocheck(&self) -> Ascii { Ascii{ chr: *self } } - #[inline(always)] + #[inline] fn is_ascii(&self) -> bool { *self & 128 == 0u8 } } impl AsciiCast for char { - #[inline(always)] + #[inline] fn to_ascii(&self) -> Ascii { assert!(self.is_ascii()); unsafe {self.to_ascii_nocheck()} } - #[inline(always)] + #[inline] unsafe fn to_ascii_nocheck(&self) -> Ascii { Ascii{ chr: *self as u8 } } - #[inline(always)] + #[inline] fn is_ascii(&self) -> bool { *self - ('\x7F' & *self) == '\x00' } @@ -167,26 +167,26 @@ pub trait OwnedAsciiCast { } impl OwnedAsciiCast for ~[u8] { - #[inline(always)] + #[inline] fn into_ascii(self) -> ~[Ascii] { assert!(self.is_ascii()); unsafe {self.into_ascii_nocheck()} } - #[inline(always)] + #[inline] unsafe fn into_ascii_nocheck(self) -> ~[Ascii] { cast::transmute(self) } } impl OwnedAsciiCast for ~str { - #[inline(always)] + #[inline] fn into_ascii(self) -> ~[Ascii] { assert!(self.is_ascii()); unsafe {self.into_ascii_nocheck()} } - #[inline(always)] + #[inline] unsafe fn into_ascii_nocheck(self) -> ~[Ascii] { let mut r: ~[Ascii] = cast::transmute(self); r.pop(); @@ -210,31 +210,31 @@ pub trait AsciiStr { } impl<'self> AsciiStr for &'self [Ascii] { - #[inline(always)] + #[inline] fn to_str_ascii(&self) -> ~str { let mut cpy = self.to_owned(); cpy.push(0u8.to_ascii()); unsafe {cast::transmute(cpy)} } - #[inline(always)] + #[inline] fn to_lower(&self) -> ~[Ascii] { self.map(|a| a.to_lower()) } - #[inline(always)] + #[inline] fn to_upper(&self) -> ~[Ascii] { self.map(|a| a.to_upper()) } - #[inline(always)] + #[inline] fn eq_ignore_case(self, other: &[Ascii]) -> bool { do self.iter().zip(other.iter()).all |(&a, &b)| { a.eq_ignore_case(b) } } } impl ToStrConsume for ~[Ascii] { - #[inline(always)] + #[inline] fn into_str(self) -> ~str { let mut cpy = self; cpy.push(0u8.to_ascii()); @@ -243,7 +243,7 @@ impl ToStrConsume for ~[Ascii] { } impl IterBytes for Ascii { - #[inline(always)] + #[inline] fn iter_bytes(&self, _lsb0: bool, f: &fn(buf: &[u8]) -> bool) -> bool { f([self.to_byte()]) } diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 87e13e494aa4..79ea60cc2240 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -57,25 +57,25 @@ pub mod rustrt { * Useful for calling certain function in the Rust runtime or otherwise * performing dark magick. */ -#[inline(always)] +#[inline] pub fn get_type_desc() -> *TypeDesc { unsafe { intrinsics::get_tydesc::() as *TypeDesc } } /// Returns a pointer to a type descriptor. -#[inline(always)] +#[inline] pub fn get_type_desc_val(_val: &T) -> *TypeDesc { get_type_desc::() } /// Returns the size of a type -#[inline(always)] +#[inline] pub fn size_of() -> uint { unsafe { intrinsics::size_of::() } } /// Returns the size of the type that `_val` points to -#[inline(always)] +#[inline] pub fn size_of_val(_val: &T) -> uint { size_of::() } @@ -85,14 +85,14 @@ pub fn size_of_val(_val: &T) -> uint { * * Useful for building structures containing variable-length arrays. */ -#[inline(always)] +#[inline] pub fn nonzero_size_of() -> uint { let s = size_of::(); if s == 0 { 1 } else { s } } /// Returns the size of the type of the value that `_val` points to -#[inline(always)] +#[inline] pub fn nonzero_size_of_val(_val: &T) -> uint { nonzero_size_of::() } @@ -104,33 +104,33 @@ pub fn nonzero_size_of_val(_val: &T) -> uint { * This is the alignment used for struct fields. It may be smaller * than the preferred alignment. */ -#[inline(always)] +#[inline] pub fn min_align_of() -> uint { unsafe { intrinsics::min_align_of::() } } /// Returns the ABI-required minimum alignment of the type of the value that /// `_val` points to -#[inline(always)] +#[inline] pub fn min_align_of_val(_val: &T) -> uint { min_align_of::() } /// Returns the preferred alignment of a type -#[inline(always)] +#[inline] pub fn pref_align_of() -> uint { unsafe { intrinsics::pref_align_of::() } } /// Returns the preferred alignment of the type of the value that /// `_val` points to -#[inline(always)] +#[inline] pub fn pref_align_of_val(_val: &T) -> uint { pref_align_of::() } /// Returns the refcount of a shared box (as just before calling this) -#[inline(always)] +#[inline] pub fn refcount(t: @T) -> uint { unsafe { let ref_ptr: *uint = cast::transmute_copy(&t); diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index fa1790d79cb7..16bb2fab7ba7 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -157,14 +157,14 @@ struct AncestorNode { struct AncestorList(Option>); // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. -#[inline(always)] +#[inline] fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { unsafe { x.with(blk) } } -#[inline(always)] +#[inline] fn access_ancestors(x: &Exclusive, blk: &fn(x: &mut AncestorNode) -> U) -> U { unsafe { diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 6d7820ffea5f..822aab0a0271 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -49,7 +49,7 @@ pub trait IterBytes { } impl IterBytes for bool { - #[inline(always)] + #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { f([ *self as u8 @@ -58,7 +58,7 @@ impl IterBytes for bool { } impl IterBytes for u8 { - #[inline(always)] + #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { f([ *self @@ -67,7 +67,7 @@ impl IterBytes for u8 { } impl IterBytes for u16 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { if lsb0 { f([ @@ -84,7 +84,7 @@ impl IterBytes for u16 { } impl IterBytes for u32 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { if lsb0 { f([ @@ -105,7 +105,7 @@ impl IterBytes for u32 { } impl IterBytes for u64 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { if lsb0 { f([ @@ -134,35 +134,35 @@ impl IterBytes for u64 { } impl IterBytes for i8 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u8).iter_bytes(lsb0, f) } } impl IterBytes for i16 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u16).iter_bytes(lsb0, f) } } impl IterBytes for i32 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u32).iter_bytes(lsb0, f) } } impl IterBytes for i64 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u64).iter_bytes(lsb0, f) } } impl IterBytes for char { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u32).iter_bytes(lsb0, f) } @@ -170,7 +170,7 @@ impl IterBytes for char { #[cfg(target_word_size = "32")] impl IterBytes for uint { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u32).iter_bytes(lsb0, f) } @@ -178,28 +178,28 @@ impl IterBytes for uint { #[cfg(target_word_size = "64")] impl IterBytes for uint { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as u64).iter_bytes(lsb0, f) } } impl IterBytes for int { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as uint).iter_bytes(lsb0, f) } } impl IterBytes for float { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as f64).iter_bytes(lsb0, f) } } impl IterBytes for f32 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { let i: u32 = unsafe { // 0.0 == -0.0 so they should also have the same hashcode @@ -210,7 +210,7 @@ impl IterBytes for f32 { } impl IterBytes for f64 { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { let i: u64 = unsafe { // 0.0 == -0.0 so they should also have the same hashcode @@ -221,14 +221,14 @@ impl IterBytes for f64 { } impl<'self,A:IterBytes> IterBytes for &'self [A] { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { self.each(|elt| elt.iter_bytes(lsb0, |b| f(b))) } } impl IterBytes for (A,B) { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { (ref a, ref b) => { a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) } @@ -237,7 +237,7 @@ impl IterBytes for (A,B) { } impl IterBytes for (A,B,C) { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { (ref a, ref b, ref c) => { @@ -253,28 +253,28 @@ fn borrow<'x,A>(a: &'x [A]) -> &'x [A] { } impl IterBytes for ~[A] { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { borrow(*self).iter_bytes(lsb0, f) } } impl IterBytes for @[A] { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { borrow(*self).iter_bytes(lsb0, f) } } impl<'self> IterBytes for &'self str { - #[inline(always)] + #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { f(self.as_bytes()) } } impl IterBytes for ~str { - #[inline(always)] + #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { // this should possibly include the null terminator, but that // breaks .find_equiv on hashmaps. @@ -283,7 +283,7 @@ impl IterBytes for ~str { } impl IterBytes for @str { - #[inline(always)] + #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { // this should possibly include the null terminator, but that // breaks .find_equiv on hashmaps. @@ -292,7 +292,7 @@ impl IterBytes for @str { } impl IterBytes for Option { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { Some(ref a) => 0u8.iter_bytes(lsb0, f) && a.iter_bytes(lsb0, f), @@ -302,21 +302,21 @@ impl IterBytes for Option { } impl<'self,A:IterBytes> IterBytes for &'self A { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (**self).iter_bytes(lsb0, f) } } impl IterBytes for @A { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (**self).iter_bytes(lsb0, f) } } impl IterBytes for ~A { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (**self).iter_bytes(lsb0, f) } @@ -325,7 +325,7 @@ impl IterBytes for ~A { // NB: raw-pointer IterBytes does _not_ dereference // to the target; it just gives you the pointer-bytes. impl IterBytes for *const A { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as uint).iter_bytes(lsb0, f) } diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index 46e50b6f76e0..3e782e728fe3 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -35,12 +35,12 @@ pub trait ToStrConsume { } impl ToStr for () { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { ~"()" } } impl ToStr for (A,) { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { match *self { (ref a,) => { @@ -51,7 +51,7 @@ impl ToStr for (A,) { } impl ToStr for HashMap { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"{", true); for self.each |key, value| { @@ -71,7 +71,7 @@ impl ToStr for HashMap { } impl ToStr for HashSet { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"{", true); for self.each |element| { @@ -89,7 +89,7 @@ impl ToStr for HashSet { } impl ToStr for (A, B) { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { // FIXME(#4653): this causes an llvm assertion //let &(ref a, ref b) = self; @@ -102,7 +102,7 @@ impl ToStr for (A, B) { } impl ToStr for (A, B, C) { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { // FIXME(#4653): this causes an llvm assertion //let &(ref a, ref b, ref c) = self; @@ -119,7 +119,7 @@ impl ToStr for (A, B, C) { } impl<'self,A:ToStr> ToStr for &'self [A] { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"[", true); for self.each |elt| { @@ -137,7 +137,7 @@ impl<'self,A:ToStr> ToStr for &'self [A] { } impl ToStr for ~[A] { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"[", true); for self.each |elt| { @@ -155,7 +155,7 @@ impl ToStr for ~[A] { } impl ToStr for @[A] { - #[inline(always)] + #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"[", true); for self.each |elt| { diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 4bd3946f885f..aaeaa489834f 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -34,17 +34,17 @@ pub struct TrieMap { impl Container for TrieMap { /// Return the number of elements in the map - #[inline(always)] + #[inline] fn len(&const self) -> uint { self.length } /// Return true if the map contains no elements - #[inline(always)] + #[inline] fn is_empty(&const self) -> bool { self.len() == 0 } } impl Mutable for TrieMap { /// Clear the map, removing all values. - #[inline(always)] + #[inline] fn clear(&mut self) { self.root = TrieNode::new(); self.length = 0; @@ -53,37 +53,37 @@ impl Mutable for TrieMap { impl Map for TrieMap { /// Return true if the map contains a value for the specified key - #[inline(always)] + #[inline] fn contains_key(&self, key: &uint) -> bool { self.find(key).is_some() } /// Visit all key-value pairs in order - #[inline(always)] + #[inline] fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { self.root.each(f) } /// Visit all keys in order - #[inline(always)] + #[inline] fn each_key(&self, f: &fn(&uint) -> bool) -> bool { self.each(|k, _| f(k)) } /// Visit all values in order - #[inline(always)] + #[inline] fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { self.each(|_, v| f(v)) } /// Iterate over the map and mutate the contained values - #[inline(always)] + #[inline] fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { self.root.mutate_values(f) } /// Return a reference to the value corresponding to the key - #[inline(hint)] + #[inline] fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { let mut node: &'a TrieNode = &self.root; let mut idx = 0; @@ -104,7 +104,7 @@ impl Map for TrieMap { } /// Return a mutable reference to the value corresponding to the key - #[inline(always)] + #[inline] fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> { find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) } @@ -112,14 +112,14 @@ impl Map for TrieMap { /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. - #[inline(always)] + #[inline] fn insert(&mut self, key: uint, value: T) -> bool { self.swap(key, value).is_none() } /// Remove a key-value pair from the map. Return true if the key /// was present in the map, otherwise false. - #[inline(always)] + #[inline] fn remove(&mut self, key: &uint) -> bool { self.pop(key).is_some() } @@ -147,25 +147,25 @@ impl Map for TrieMap { impl TrieMap { /// Create an empty TrieMap - #[inline(always)] + #[inline] pub fn new() -> TrieMap { TrieMap{root: TrieNode::new(), length: 0} } /// Visit all key-value pairs in reverse order - #[inline(always)] + #[inline] pub fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { self.root.each_reverse(f) } /// Visit all keys in reverse order - #[inline(always)] + #[inline] pub fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool { self.each_reverse(|k, _| f(k)) } /// Visit all values in reverse order - #[inline(always)] + #[inline] pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool { self.each_reverse(|_, v| f(v)) } @@ -178,15 +178,15 @@ pub struct TrieSet { impl BaseIter for TrieSet { /// Visit all values in order - #[inline(always)] + #[inline] fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } - #[inline(always)] + #[inline] fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TrieSet { /// Visit all values in reverse order - #[inline(always)] + #[inline] fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key_reverse(f) } @@ -194,43 +194,43 @@ impl ReverseIter for TrieSet { impl Container for TrieSet { /// Return the number of elements in the set - #[inline(always)] + #[inline] fn len(&const self) -> uint { self.map.len() } /// Return true if the set contains no elements - #[inline(always)] + #[inline] fn is_empty(&const self) -> bool { self.map.is_empty() } } impl Mutable for TrieSet { /// Clear the set, removing all values. - #[inline(always)] + #[inline] fn clear(&mut self) { self.map.clear() } } impl TrieSet { /// Create an empty TrieSet - #[inline(always)] + #[inline] pub fn new() -> TrieSet { TrieSet{map: TrieMap::new()} } /// Return true if the set contains a value - #[inline(always)] + #[inline] pub fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) } /// Add a value to the set. Return true if the value was not already /// present in the set. - #[inline(always)] + #[inline] pub fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) } /// Remove a value from the set. Return true if the value was /// present in the set. - #[inline(always)] + #[inline] pub fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) } @@ -242,7 +242,7 @@ struct TrieNode { } impl TrieNode { - #[inline(always)] + #[inline] fn new() -> TrieNode { // FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy TrieNode{count: 0, @@ -291,7 +291,7 @@ impl TrieNode { } // if this was done via a trait, the key could be generic -#[inline(always)] +#[inline] fn chunk(n: uint, idx: uint) -> uint { let sh = uint::bits - (SHIFT * (idx + 1)); (n >> sh) & MASK diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index c120883be5a0..fefd55c35415 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -29,7 +29,7 @@ pub trait CopyableTuple { impl CopyableTuple for (T, U) { /// Return the first element of self - #[inline(always)] + #[inline] fn first(&self) -> T { match *self { (ref t, _) => copy *t, @@ -37,7 +37,7 @@ impl CopyableTuple for (T, U) { } /// Return the second element of self - #[inline(always)] + #[inline] fn second(&self) -> U { match *self { (_, ref u) => copy *u, @@ -45,7 +45,7 @@ impl CopyableTuple for (T, U) { } /// Return the results of swapping the two elements of self - #[inline(always)] + #[inline] fn swap(&self) -> (U, T) { match copy *self { (t, u) => (u, t), @@ -63,13 +63,13 @@ pub trait ImmutableTuple { } impl ImmutableTuple for (T, U) { - #[inline(always)] + #[inline] fn first_ref<'a>(&'a self) -> &'a T { match *self { (ref t, _) => t, } } - #[inline(always)] + #[inline] fn second_ref<'a>(&'a self) -> &'a U { match *self { (_, ref u) => u, @@ -83,7 +83,7 @@ pub trait ExtendedTupleOps { } impl<'self,A:Copy,B:Copy> ExtendedTupleOps for (&'self [A], &'self [B]) { - #[inline(always)] + #[inline] fn zip(&self) -> ~[(A, B)] { match *self { (ref a, ref b) => { @@ -92,7 +92,7 @@ impl<'self,A:Copy,B:Copy> ExtendedTupleOps for (&'self [A], &'self [B]) { } } - #[inline(always)] + #[inline] fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] { match *self { (ref a, ref b) => { @@ -103,7 +103,7 @@ impl<'self,A:Copy,B:Copy> ExtendedTupleOps for (&'self [A], &'self [B]) { } impl ExtendedTupleOps for (~[A], ~[B]) { - #[inline(always)] + #[inline] fn zip(&self) -> ~[(A, B)] { match *self { (ref a, ref b) => { @@ -112,7 +112,7 @@ impl ExtendedTupleOps for (~[A], ~[B]) { } } - #[inline(always)] + #[inline] fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] { match *self { (ref a, ref b) => { @@ -144,7 +144,7 @@ macro_rules! tuple_impls { impl<$($T:Clone),+> $cloneable_trait<$($T),+> for ($($T),+) { $( - #[inline(always)] + #[inline] fn $get_fn(&self) -> $T { self.$get_ref_fn().clone() } @@ -157,7 +157,7 @@ macro_rules! tuple_impls { impl<$($T),+> $immutable_trait<$($T),+> for ($($T),+) { $( - #[inline(always)] + #[inline] fn $get_ref_fn<'a>(&'a self) -> &'a $T { match *self { $get_pattern => $ret } } @@ -172,11 +172,11 @@ macro_rules! tuple_impls { #[cfg(not(test))] impl<$($T:Eq),+> Eq for ($($T),+) { - #[inline(always)] + #[inline] fn eq(&self, other: &($($T),+)) -> bool { $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+ } - #[inline(always)] + #[inline] fn ne(&self, other: &($($T),+)) -> bool { !(*self == *other) } @@ -184,7 +184,7 @@ macro_rules! tuple_impls { #[cfg(not(test))] impl<$($T:TotalEq),+> TotalEq for ($($T),+) { - #[inline(always)] + #[inline] fn equals(&self, other: &($($T),+)) -> bool { $(self.$get_ref_fn().equals(other.$get_ref_fn()))&&+ } @@ -192,15 +192,15 @@ macro_rules! tuple_impls { #[cfg(not(test))] impl<$($T:Ord),+> Ord for ($($T),+) { - #[inline(always)] + #[inline] fn lt(&self, other: &($($T),+)) -> bool { lexical_lt!($(self.$get_ref_fn(), other.$get_ref_fn()),+) } - #[inline(always)] + #[inline] fn le(&self, other: &($($T),+)) -> bool { !(*other).lt(&(*self)) } - #[inline(always)] + #[inline] fn ge(&self, other: &($($T),+)) -> bool { !(*self).lt(other) } - #[inline(always)] + #[inline] fn gt(&self, other: &($($T),+)) -> bool { (*other).lt(&(*self)) } } diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs index aa70897ad486..6e7a7e2b129c 100644 --- a/src/libstd/unstable/atomics.rs +++ b/src/libstd/unstable/atomics.rs @@ -82,7 +82,7 @@ impl AtomicFlag { /** * Clears the atomic flag */ - #[inline(always)] + #[inline] pub fn clear(&mut self, order: Ordering) { unsafe {atomic_store(&mut self.v, 0, order)} } @@ -91,7 +91,7 @@ impl AtomicFlag { * Sets the flag if it was previously unset, returns the previous value of the * flag. */ - #[inline(always)] + #[inline] pub fn test_and_set(&mut self, order: Ordering) -> bool { unsafe {atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0} } @@ -102,26 +102,26 @@ impl AtomicBool { AtomicBool { v: if v { 1 } else { 0 } } } - #[inline(always)] + #[inline] pub fn load(&self, order: Ordering) -> bool { unsafe { atomic_load(&self.v, order) > 0 } } - #[inline(always)] + #[inline] pub fn store(&mut self, val: bool, order: Ordering) { let val = if val { 1 } else { 0 }; unsafe { atomic_store(&mut self.v, val, order); } } - #[inline(always)] + #[inline] pub fn swap(&mut self, val: bool, order: Ordering) -> bool { let val = if val { 1 } else { 0 }; unsafe { atomic_swap(&mut self.v, val, order) > 0} } - #[inline(always)] + #[inline] pub fn compare_and_swap(&mut self, old: bool, new: bool, order: Ordering) -> bool { let old = if old { 1 } else { 0 }; let new = if new { 1 } else { 0 }; @@ -135,34 +135,34 @@ impl AtomicInt { AtomicInt { v:v } } - #[inline(always)] + #[inline] pub fn load(&self, order: Ordering) -> int { unsafe { atomic_load(&self.v, order) } } - #[inline(always)] + #[inline] pub fn store(&mut self, val: int, order: Ordering) { unsafe { atomic_store(&mut self.v, val, order); } } - #[inline(always)] + #[inline] pub fn swap(&mut self, val: int, order: Ordering) -> int { unsafe { atomic_swap(&mut self.v, val, order) } } - #[inline(always)] + #[inline] pub fn compare_and_swap(&mut self, old: int, new: int, order: Ordering) -> int { unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) } } /// Returns the old value (like __sync_fetch_and_add). - #[inline(always)] + #[inline] pub fn fetch_add(&mut self, val: int, order: Ordering) -> int { unsafe { atomic_add(&mut self.v, val, order) } } /// Returns the old value (like __sync_fetch_and_sub). - #[inline(always)] + #[inline] pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int { unsafe { atomic_sub(&mut self.v, val, order) } } @@ -173,34 +173,34 @@ impl AtomicUint { AtomicUint { v:v } } - #[inline(always)] + #[inline] pub fn load(&self, order: Ordering) -> uint { unsafe { atomic_load(&self.v, order) } } - #[inline(always)] + #[inline] pub fn store(&mut self, val: uint, order: Ordering) { unsafe { atomic_store(&mut self.v, val, order); } } - #[inline(always)] + #[inline] pub fn swap(&mut self, val: uint, order: Ordering) -> uint { unsafe { atomic_swap(&mut self.v, val, order) } } - #[inline(always)] + #[inline] pub fn compare_and_swap(&mut self, old: uint, new: uint, order: Ordering) -> uint { unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) } } /// Returns the old value (like __sync_fetch_and_add). - #[inline(always)] + #[inline] pub fn fetch_add(&mut self, val: uint, order: Ordering) -> uint { unsafe { atomic_add(&mut self.v, val, order) } } /// Returns the old value (like __sync_fetch_and_sub).. - #[inline(always)] + #[inline] pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint { unsafe { atomic_sub(&mut self.v, val, order) } } @@ -211,22 +211,22 @@ impl AtomicPtr { AtomicPtr { p:p } } - #[inline(always)] + #[inline] pub fn load(&self, order: Ordering) -> *mut T { unsafe { atomic_load(&self.p, order) } } - #[inline(always)] + #[inline] pub fn store(&mut self, ptr: *mut T, order: Ordering) { unsafe { atomic_store(&mut self.p, ptr, order); } } - #[inline(always)] + #[inline] pub fn swap(&mut self, ptr: *mut T, order: Ordering) -> *mut T { unsafe { atomic_swap(&mut self.p, ptr, order) } } - #[inline(always)] + #[inline] pub fn compare_and_swap(&mut self, old: *mut T, new: *mut T, order: Ordering) -> *mut T { unsafe { atomic_compare_and_swap(&mut self.p, old, new, order) } } @@ -249,7 +249,7 @@ impl AtomicOption { } } - #[inline(always)] + #[inline] pub fn swap(&mut self, val: ~T, order: Ordering) -> Option<~T> { unsafe { let val = cast::transmute(val); @@ -265,7 +265,7 @@ impl AtomicOption { } } - #[inline(always)] + #[inline] pub fn take(&mut self, order: Ordering) -> Option<~T> { unsafe { self.swap(cast::transmute(0), order) @@ -286,7 +286,7 @@ impl Drop for AtomicOption { } } -#[inline(always)] +#[inline] pub unsafe fn atomic_store(dst: &mut T, val: T, order:Ordering) { let dst = cast::transmute(dst); let val = cast::transmute(val); @@ -297,7 +297,7 @@ pub unsafe fn atomic_store(dst: &mut T, val: T, order:Ordering) { } } -#[inline(always)] +#[inline] pub unsafe fn atomic_load(dst: &T, order:Ordering) -> T { let dst = cast::transmute(dst); @@ -307,7 +307,7 @@ pub unsafe fn atomic_load(dst: &T, order:Ordering) -> T { }) } -#[inline(always)] +#[inline] pub unsafe fn atomic_swap(dst: &mut T, val: T, order: Ordering) -> T { let dst = cast::transmute(dst); let val = cast::transmute(val); @@ -320,7 +320,7 @@ pub unsafe fn atomic_swap(dst: &mut T, val: T, order: Ordering) -> T { } /// Returns the old value (like __sync_fetch_and_add). -#[inline(always)] +#[inline] pub unsafe fn atomic_add(dst: &mut T, val: T, order: Ordering) -> T { let dst = cast::transmute(dst); let val = cast::transmute(val); @@ -333,7 +333,7 @@ pub unsafe fn atomic_add(dst: &mut T, val: T, order: Ordering) -> T { } /// Returns the old value (like __sync_fetch_and_sub). -#[inline(always)] +#[inline] pub unsafe fn atomic_sub(dst: &mut T, val: T, order: Ordering) -> T { let dst = cast::transmute(dst); let val = cast::transmute(val); @@ -345,7 +345,7 @@ pub unsafe fn atomic_sub(dst: &mut T, val: T, order: Ordering) -> T { }) } -#[inline(always)] +#[inline] pub unsafe fn atomic_compare_and_swap(dst:&mut T, old:T, new:T, order: Ordering) -> T { let dst = cast::transmute(dst); let old = cast::transmute(old); diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs index 7d9ce585d7c5..d466488ce5e5 100644 --- a/src/libstd/unstable/extfmt.rs +++ b/src/libstd/unstable/extfmt.rs @@ -673,7 +673,7 @@ pub mod rt { } buf.push_str(s); } - #[inline(always)] + #[inline] pub fn have_flag(flags: u32, f: u32) -> bool { flags & f != 0 } diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index e75cf2c01c67..505cfa2fcd90 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -152,7 +152,7 @@ unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) { // FIXME #4942: Make these signatures agree with exchange_alloc's signatures #[lang="exchange_malloc"] -#[inline(always)] +#[inline] pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { transmute(global_heap::malloc(transmute(td), transmute(size))) } @@ -232,7 +232,7 @@ impl DebugPrints for io::fd_t { // inside a landing pad may corrupt the state of the exception handler. If a // problem occurs, call exit instead. #[lang="exchange_free"] -#[inline(always)] +#[inline] pub unsafe fn exchange_free(ptr: *c_char) { global_heap::free(transmute(ptr)) } @@ -271,7 +271,7 @@ pub unsafe fn local_free(ptr: *c_char) { } #[lang="borrow_as_imm"] -#[inline(always)] +#[inline] pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint { let a: *mut BoxRepr = transmute(a); let old_ref_count = (*a).header.ref_count; @@ -289,7 +289,7 @@ pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint { } #[lang="borrow_as_mut"] -#[inline(always)] +#[inline] pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint { let a: *mut BoxRepr = transmute(a); let old_ref_count = (*a).header.ref_count; @@ -346,7 +346,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint, } #[lang="return_to_mut"] -#[inline(always)] +#[inline] pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint, file: *c_char, line: size_t) { // Sometimes the box is null, if it is conditionally frozen. @@ -365,7 +365,7 @@ pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint, } #[lang="check_not_borrowed"] -#[inline(always)] +#[inline] pub unsafe fn check_not_borrowed(a: *u8, file: *c_char, line: size_t) { @@ -378,7 +378,7 @@ pub unsafe fn check_not_borrowed(a: *u8, } #[lang="strdup_uniq"] -#[inline(always)] +#[inline] pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { str::raw::from_buf_len(ptr, len) } diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index f0b178c66701..79aa22fabea8 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -40,7 +40,7 @@ impl UnsafeAtomicRcBox { } } - #[inline(always)] + #[inline] pub unsafe fn get(&self) -> *mut T { let mut data: ~AtomicRcBoxData = cast::transmute(self.data); @@ -50,7 +50,7 @@ impl UnsafeAtomicRcBox { return r; } - #[inline(always)] + #[inline] pub unsafe fn get_immut(&self) -> *T { let mut data: ~AtomicRcBoxData = cast::transmute(self.data); @@ -118,7 +118,7 @@ fn LittleLock() -> LittleLock { } impl LittleLock { - #[inline(always)] + #[inline] pub unsafe fn lock(&self, f: &fn() -> T) -> T { do atomically { rust_lock_little_lock(self.l); @@ -169,7 +169,7 @@ impl Exclusive { // Currently, scheduling operations (i.e., yielding, receiving on a pipe, // accessing the provided condition variable) are prohibited while inside // the exclusive. Supporting that is a work in progress. - #[inline(always)] + #[inline] pub unsafe fn with(&self, f: &fn(x: &mut T) -> U) -> U { let rec = self.x.get(); do (*rec).lock.lock { @@ -183,7 +183,7 @@ impl Exclusive { } } - #[inline(always)] + #[inline] pub unsafe fn with_imm(&self, f: &fn(x: &T) -> U) -> U { do self.with |x| { f(cast::transmute_immut(x)) diff --git a/src/libstd/util.rs b/src/libstd/util.rs index 61c284f580c0..2a5d44c9ce26 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -16,11 +16,11 @@ use prelude::*; use unstable::intrinsics; /// The identity function. -#[inline(always)] +#[inline] pub fn id(x: T) -> T { x } /// Ignores a value. -#[inline(always)] +#[inline] pub fn ignore(_x: T) { } /// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the @@ -30,7 +30,7 @@ pub fn ignore(_x: T) { } /// an obvious borrowck hazard. Typically passing in `&mut T` will /// cause borrow check errors because it freezes whatever location /// that `&mut T` is stored in (either statically or dynamically). -#[inline(always)] +#[inline] pub fn with( ptr: @mut T, value: T, @@ -46,7 +46,7 @@ pub fn with( * Swap the values at two mutable locations of the same type, without * deinitialising or copying either one. */ -#[inline(always)] +#[inline] pub fn swap(x: &mut T, y: &mut T) { unsafe { // Give ourselves some scratch space to work with @@ -68,7 +68,7 @@ pub fn swap(x: &mut T, y: &mut T) { * Replace the value at a mutable location with a new one, returning the old * value, without deinitialising or copying either one. */ -#[inline(always)] +#[inline] pub fn replace(dest: &mut T, mut src: T) -> T { swap(dest, &mut src); src diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index e6d7ae0151a6..0af69815cf23 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -111,7 +111,7 @@ pub fn reserve_at_least(v: &mut ~[T], n: uint) { } /// Returns the number of elements the vector can hold without reallocating -#[inline(always)] +#[inline] pub fn capacity(v: &const ~[T]) -> uint { unsafe { let repr: **raw::VecRepr = transmute(v); @@ -189,7 +189,7 @@ pub fn with_capacity(capacity: uint) -> ~[T] { * as an argument a function that will push an element * onto the vector being constructed. */ -#[inline(always)] +#[inline] pub fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] { let mut vec = with_capacity(size); builder(|x| vec.push(x)); @@ -206,7 +206,7 @@ pub fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] { * as an argument a function that will push an element * onto the vector being constructed. */ -#[inline(always)] +#[inline] pub fn build(builder: &fn(push: &fn(v: A))) -> ~[A] { build_sized(4, builder) } @@ -223,7 +223,7 @@ pub fn build(builder: &fn(push: &fn(v: A))) -> ~[A] { * as an argument a function that will push an element * onto the vector being constructed. */ -#[inline(always)] +#[inline] pub fn build_sized_opt(size: Option, builder: &fn(push: &fn(v: A))) -> ~[A] { @@ -271,7 +271,7 @@ pub fn last_opt<'r,T>(v: &'r [T]) -> Option<&'r T> { } /// Return a slice that points into another slice. -#[inline(always)] +#[inline] pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] { assert!(start <= end); assert!(end <= v.len()); @@ -284,7 +284,7 @@ pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] { } /// Return a slice that points into another slice. -#[inline(always)] +#[inline] pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint) -> &'r mut [T] { assert!(start <= end); @@ -298,7 +298,7 @@ pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint) } /// Return a slice that points into another slice. -#[inline(always)] +#[inline] pub fn const_slice<'r,T>(v: &'r const [T], start: uint, end: uint) -> &'r const [T] { assert!(start <= end); @@ -633,7 +633,7 @@ pub fn swap_remove(v: &mut ~[T], index: uint) -> T { } /// Append an element to a vector -#[inline(always)] +#[inline] pub fn push(v: &mut ~[T], initval: T) { unsafe { let repr: **raw::VecRepr = transmute(&mut *v); @@ -648,7 +648,7 @@ pub fn push(v: &mut ~[T], initval: T) { } // This doesn't bother to make sure we have space. -#[inline(always)] // really pretty please +#[inline] // really pretty please unsafe fn push_fast(v: &mut ~[T], initval: T) { let repr: **mut raw::VecRepr = transmute(v); let fill = (**repr).unboxed.fill; @@ -675,7 +675,7 @@ fn push_slow(v: &mut ~[T], initval: T) { /// vec::push_all(&mut a, [2, 3, 4]); /// assert!(a == ~[1, 2, 3, 4]); /// ~~~ -#[inline(always)] +#[inline] pub fn push_all(v: &mut ~[T], rhs: &const [T]) { let new_len = v.len() + rhs.len(); reserve(&mut *v, new_len); @@ -696,7 +696,7 @@ pub fn push_all(v: &mut ~[T], rhs: &const [T]) { /// vec::push_all_move(&mut a, ~[~2, ~3, ~4]); /// assert!(a == ~[~1, ~2, ~3, ~4]); /// ~~~ -#[inline(always)] +#[inline] pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { let new_len = v.len() + rhs.len(); reserve(&mut *v, new_len); @@ -767,7 +767,7 @@ pub fn dedup(v: &mut ~[T]) { /// Iterates over the `rhs` vector, copying each element and appending it to the /// `lhs`. Afterwards, the `lhs` is then returned for use again. -#[inline(always)] +#[inline] pub fn append(lhs: ~[T], rhs: &const [T]) -> ~[T] { let mut v = lhs; v.push_all(rhs); @@ -776,7 +776,7 @@ pub fn append(lhs: ~[T], rhs: &const [T]) -> ~[T] { /// Appends one element to the vector provided. The vector itself is then /// returned for use again. -#[inline(always)] +#[inline] pub fn append_one(lhs: ~[T], x: T) -> ~[T] { let mut v = lhs; v.push(x); @@ -1295,7 +1295,7 @@ pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { * * a - The index of the first element * * b - The index of the second element */ -#[inline(always)] +#[inline] pub fn swap(v: &mut [T], a: uint, b: uint) { unsafe { // Can't take two mutable loans from one vector, so instead just cast @@ -1403,7 +1403,7 @@ pub fn reversed(v: &const [T]) -> ~[T] { * } * ~~~ */ -#[inline(always)] +#[inline] pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { // ^^^^ // NB---this CANNOT be &const [T]! The reason @@ -1429,7 +1429,7 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. -#[inline(always)] +#[inline] pub fn each_const(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool { let mut i = 0; let n = v.len(); @@ -1447,7 +1447,7 @@ pub fn each_const(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool { * * Return true to continue, false to break. */ -#[inline(always)] +#[inline] pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { let mut i = 0; for each(v) |p| { @@ -1540,7 +1540,7 @@ pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool { * Allows for unsafe manipulation of vector contents, which is useful for * foreign interop. */ -#[inline(always)] +#[inline] pub fn as_imm_buf(s: &[T], /* NB---this CANNOT be const, see below */ f: &fn(*T, uint) -> U) -> U { @@ -1559,7 +1559,7 @@ pub fn as_imm_buf(s: &[T], } /// Similar to `as_imm_buf` but passing a `*const T` -#[inline(always)] +#[inline] pub fn as_const_buf(s: &const [T], f: &fn(*const T, uint) -> U) -> U { unsafe { let v : *(*const T,uint) = transmute(&s); @@ -1569,7 +1569,7 @@ pub fn as_const_buf(s: &const [T], f: &fn(*const T, uint) -> U) -> U { } /// Similar to `as_imm_buf` but passing a `*mut T` -#[inline(always)] +#[inline] pub fn as_mut_buf(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { unsafe { let v : *(*mut T,uint) = transmute(&s); @@ -1612,49 +1612,49 @@ fn equals(a: &[T], b: &[T]) -> bool { #[cfg(not(test))] impl<'self,T:Eq> Eq for &'self [T] { - #[inline(always)] + #[inline] fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) } - #[inline(always)] + #[inline] fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } } #[cfg(not(test))] impl Eq for ~[T] { - #[inline(always)] + #[inline] fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) } - #[inline(always)] + #[inline] fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } } #[cfg(not(test))] impl Eq for @[T] { - #[inline(always)] + #[inline] fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) } - #[inline(always)] + #[inline] fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } } #[cfg(not(test))] impl<'self,T:TotalEq> TotalEq for &'self [T] { - #[inline(always)] + #[inline] fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) } } #[cfg(not(test))] impl TotalEq for ~[T] { - #[inline(always)] + #[inline] fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) } } #[cfg(not(test))] impl TotalEq for @[T] { - #[inline(always)] + #[inline] fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) } } #[cfg(not(test))] impl<'self,T:Eq> Equiv<~[T]> for &'self [T] { - #[inline(always)] + #[inline] fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } } @@ -1676,19 +1676,19 @@ fn cmp(a: &[T], b: &[T]) -> Ordering { #[cfg(not(test))] impl<'self,T:TotalOrd> TotalOrd for &'self [T] { - #[inline(always)] + #[inline] fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } } #[cfg(not(test))] impl TotalOrd for ~[T] { - #[inline(always)] + #[inline] fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } } #[cfg(not(test))] impl TotalOrd for @[T] { - #[inline(always)] + #[inline] fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } } @@ -1713,37 +1713,37 @@ fn gt(a: &[T], b: &[T]) -> bool { lt(b, a) } #[cfg(not(test))] impl<'self,T:Ord> Ord for &'self [T] { - #[inline(always)] + #[inline] fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } - #[inline(always)] + #[inline] fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) } - #[inline(always)] + #[inline] fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) } - #[inline(always)] + #[inline] fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } } #[cfg(not(test))] impl Ord for ~[T] { - #[inline(always)] + #[inline] fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } - #[inline(always)] + #[inline] fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) } - #[inline(always)] + #[inline] fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) } - #[inline(always)] + #[inline] fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } } #[cfg(not(test))] impl Ord for @[T] { - #[inline(always)] + #[inline] fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } - #[inline(always)] + #[inline] fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) } - #[inline(always)] + #[inline] fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) } - #[inline(always)] + #[inline] fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } } @@ -1754,7 +1754,7 @@ pub mod traits { use vec::append; impl<'self,T:Copy> Add<&'self const [T],~[T]> for ~[T] { - #[inline(always)] + #[inline] fn add(&self, rhs: & &'self const [T]) -> ~[T] { append(copy *self, (*rhs)) } @@ -1958,7 +1958,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { /// Returns a pointer to the element at the given index, without doing /// bounds checking. - #[inline(always)] + #[inline] unsafe fn unsafe_ref(&self, index: uint) -> *T { let (ptr, _): (*T, uint) = transmute(*self); ptr.offset(index) @@ -2029,7 +2029,7 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { } /// Returns the element at the given index, without doing bounds checking. - #[inline(always)] + #[inline] unsafe fn unsafe_get(&self, index: uint) -> T { copy *self.unsafe_ref(index) } @@ -2210,14 +2210,14 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } } - #[inline(always)] + #[inline] unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T { let pair_ptr: &(*mut T, uint) = transmute(self); let (ptr, _) = *pair_ptr; ptr.offset(index) } - #[inline(always)] + #[inline] unsafe fn unsafe_set(&self, index: uint, val: T) { *self.unsafe_mut_ref(index) = val; } @@ -2278,7 +2278,7 @@ pub mod raw { * modifing its buffers, so it is up to the caller to ensure that * the vector is actually the specified size. */ - #[inline(always)] + #[inline] pub unsafe fn set_len(v: &mut ~[T], new_len: uint) { let repr: **mut VecRepr = transmute(v); (**repr).unboxed.fill = new_len * sys::nonzero_size_of::(); @@ -2293,7 +2293,7 @@ pub mod raw { * Modifying the vector may cause its buffer to be reallocated, which * would also make any pointers to it invalid. */ - #[inline(always)] + #[inline] pub fn to_ptr(v: &[T]) -> *T { unsafe { let repr: **SliceRepr = transmute(&v); @@ -2302,7 +2302,7 @@ pub mod raw { } /** see `to_ptr()` */ - #[inline(always)] + #[inline] pub fn to_const_ptr(v: &const [T]) -> *const T { unsafe { let repr: **SliceRepr = transmute(&v); @@ -2311,7 +2311,7 @@ pub mod raw { } /** see `to_ptr()` */ - #[inline(always)] + #[inline] pub fn to_mut_ptr(v: &mut [T]) -> *mut T { unsafe { let repr: **SliceRepr = transmute(&v); @@ -2323,7 +2323,7 @@ pub mod raw { * Form a slice from a pointer and length (as a number of units, * not bytes). */ - #[inline(always)] + #[inline] pub unsafe fn buf_as_slice(p: *T, len: uint, f: &fn(v: &[T]) -> U) -> U { @@ -2336,7 +2336,7 @@ pub mod raw { * Form a slice from a pointer and length (as a number of units, * not bytes). */ - #[inline(always)] + #[inline] pub unsafe fn mut_buf_as_slice(p: *mut T, len: uint, f: &fn(v: &mut [T]) -> U) -> U { @@ -2348,7 +2348,7 @@ pub mod raw { /** * Unchecked vector indexing. */ - #[inline(always)] + #[inline] pub unsafe fn get(v: &const [T], i: uint) -> T { as_const_buf(v, |p, _len| copy *ptr::const_offset(p, i)) } @@ -2358,7 +2358,7 @@ pub mod raw { * old value and hence is only suitable when the vector * is newly allocated. */ - #[inline(always)] + #[inline] pub unsafe fn init_elem(v: &mut [T], i: uint, val: T) { let mut box = Some(val); do as_mut_buf(v) |p, _len| { @@ -2377,7 +2377,7 @@ pub mod raw { * * elts - The number of elements in the buffer */ // Was in raw, but needs to be called by net_tcp::on_tcp_read_cb - #[inline(always)] + #[inline] pub unsafe fn from_buf_raw(ptr: *T, elts: uint) -> ~[T] { let mut dst = with_capacity(elts); set_len(&mut dst, elts); @@ -2391,7 +2391,7 @@ pub mod raw { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ - #[inline(always)] + #[inline] pub unsafe fn copy_memory(dst: &mut [T], src: &const [T], count: uint) { assert!(dst.len() >= count); @@ -2457,7 +2457,7 @@ pub mod bytes { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ - #[inline(always)] + #[inline] pub fn copy_memory(dst: &mut [u8], src: &const [u8], count: uint) { // Bound checks are done at vec::raw::copy_memory. unsafe { vec::raw::copy_memory(dst, src, count) } @@ -2468,31 +2468,31 @@ pub mod bytes { // ITERATION TRAIT METHODS impl<'self,A> old_iter::BaseIter for &'self [A] { - #[inline(always)] + #[inline] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { each(*self, blk) } - #[inline(always)] + #[inline] fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl old_iter::BaseIter for ~[A] { - #[inline(always)] + #[inline] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { each(*self, blk) } - #[inline(always)] + #[inline] fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl old_iter::BaseIter for @[A] { - #[inline(always)] + #[inline] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { each(*self, blk) } - #[inline(always)] + #[inline] fn size_hint(&self) -> Option { Some(self.len()) } } @@ -2710,7 +2710,7 @@ pub struct VecMutRevIterator<'self, T> { iterator!{impl VecMutRevIterator -> &'self mut T, -1} impl FromIter for ~[T]{ - #[inline(always)] + #[inline] pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { let mut v = ~[]; for iter |x| { v.push(x) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e3182916723b..1758433aa737 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -95,7 +95,7 @@ impl Decodable for ident { } impl to_bytes::IterBytes for ident { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { self.name.iter_bytes(lsb0, f) } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 07913946578f..a4ded8fea8c4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -198,7 +198,7 @@ pub fn is_call_expr(e: @expr) -> bool { // This makes def_id hashable impl to_bytes::IterBytes for def_id { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { self.crate.iter_bytes(lsb0, f) && self.node.iter_bytes(lsb0, f) } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a184d9593908..e096711262fb 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -312,7 +312,7 @@ pub enum inline_attr { /// True if something like #[inline] is found in the list of attrs. pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr { - // FIXME (#2809)---validate the usage of #[inline] and #[inline(always)] + // FIXME (#2809)---validate the usage of #[inline] and #[inline] do attrs.iter().fold(ia_none) |ia,attr| { match attr.node.value.node { ast::meta_word(s) if "inline" == s => ia_hint, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 49b3d3ec861a..22ce305b8575 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -1052,7 +1052,7 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1), self_2.method(__arg_1_2, __arg_2_2)]) ~~~ */ -#[inline(always)] +#[inline] pub fn cs_same_method(f: &fn(@ExtCtxt, span, ~[@expr]) -> @expr, enum_nonmatch_f: EnumNonMatchFunc, cx: @ExtCtxt, span: span, @@ -1083,7 +1083,7 @@ Fold together the results of calling the derived method on all the fields. `use_foldl` controls whether this is done left-to-right (`true`) or right-to-left (`false`). */ -#[inline(always)] +#[inline] pub fn cs_same_method_fold(use_foldl: bool, f: &fn(@ExtCtxt, span, @expr, @expr) -> @expr, base: @expr, @@ -1111,7 +1111,7 @@ pub fn cs_same_method_fold(use_foldl: bool, Use a given binop to combine the result of calling the derived method on all the fields. */ -#[inline(always)] +#[inline] pub fn cs_binop(binop: ast::binop, base: @expr, enum_nonmatch_f: EnumNonMatchFunc, cx: @ExtCtxt, span: span, @@ -1130,7 +1130,7 @@ pub fn cs_binop(binop: ast::binop, base: @expr, } /// cs_binop with binop == or -#[inline(always)] +#[inline] pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, cx: @ExtCtxt, span: span, substructure: &Substructure) -> @expr { @@ -1139,7 +1139,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, cx, span, substructure) } /// cs_binop with binop == and -#[inline(always)] +#[inline] pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc, cx: @ExtCtxt, span: span, substructure: &Substructure) -> @expr { diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 67e712f0596c..81f540fd69f2 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -103,7 +103,7 @@ impl OptVec { } } - #[inline(always)] + #[inline] fn mapi_to_vec(&self, op: &fn(uint, &T) -> B) -> ~[B] { let mut index = 0; old_iter::map_to_vec(self, |a| { @@ -145,31 +145,31 @@ impl BaseIter for OptVec { } impl old_iter::ExtendedIter for OptVec { - #[inline(always)] + #[inline] fn eachi(&self, blk: &fn(v: uint, v: &A) -> bool) -> bool { old_iter::eachi(self, blk) } - #[inline(always)] + #[inline] fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } - #[inline(always)] + #[inline] fn any(&self, blk: &fn(&A) -> bool) -> bool { old_iter::any(self, blk) } - #[inline(always)] + #[inline] fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { old_iter::foldl(self, b0, blk) } - #[inline(always)] + #[inline] fn position(&self, f: &fn(&A) -> bool) -> Option { old_iter::position(self, f) } - #[inline(always)] + #[inline] fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { old_iter::map_to_vec(self, op) } - #[inline(always)] + #[inline] fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { old_iter::flat_map_to_vec(self, op) @@ -178,20 +178,20 @@ impl old_iter::ExtendedIter for OptVec { } impl old_iter::EqIter for OptVec { - #[inline(always)] + #[inline] fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } - #[inline(always)] + #[inline] fn count(&self, x: &A) -> uint { old_iter::count(self, x) } } impl old_iter::CopyableIter for OptVec { - #[inline(always)] + #[inline] fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { old_iter::filter_to_vec(self, pred) } - #[inline(always)] + #[inline] fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } - #[inline(always)] + #[inline] fn find(&self, f: &fn(&A) -> bool) -> Option { old_iter::find(self, f) } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index cc7b7fab07e8..bb315bf29339 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -68,7 +68,7 @@ pub enum ObsoleteSyntax { } impl to_bytes::IterBytes for ObsoleteSyntax { - #[inline(always)] + #[inline] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { (*self as uint).iter_bytes(lsb0, f) } From 2e41689501dd3fd207b26d5ce347d0cd9f84d59e Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 18 Jun 2013 14:48:15 -0700 Subject: [PATCH 63/96] xfail std::num::complex::test_norm on x86, r=burningtree. --- src/libextra/num/complex.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index 90ca3bc47c08..b75537b8b3ef 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -222,6 +222,8 @@ mod test { } #[test] + #[ignore(cfg(target_arch = "x86"))] + // FIXME #7158: (maybe?) currently failing on x86. fn test_norm() { fn test(c: Complex, ns: float) { assert_eq!(c.norm_sqr(), ns); From 04b1dbabf567f530c20e44d5e97967dae3aabd17 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 18 Jun 2013 16:43:49 -0700 Subject: [PATCH 64/96] rusti: disable tests on 32bit mac. r=burningtree. --- src/librusti/rusti.rc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 0af6ed724e1d..a67915fbc851 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -537,6 +537,9 @@ mod tests { } #[test] + // FIXME: #7220 rusti on 32bit mac doesn't work. + #[cfg(not(and(target_word_size=32, + target_os="mac")))] fn run_all() { // FIXME(#7071): // By default, unit tests are run in parallel. Rusti, on the other hand, @@ -648,6 +651,9 @@ mod tests { } #[test] + // FIXME: #7220 rusti on 32bit mac doesn't work. + #[cfg(not(and(target_word_size=32, + target_os="mac")))] fn exit_quits() { let mut r = repl(); assert!(r.running); From 7f55fc33f08a7ec5df0d06b4b0543bc864e60640 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 18 Jun 2013 19:52:05 -0700 Subject: [PATCH 65/96] std: Work around some failing 'run' tests when valgrinding. #7224 Under valgrind on 64->32 cross compiles the dynamic linker is emitting some error messages on stderr, which interferes with the tests that are checking stderr. --- src/libstd/run.rs | 30 +++++++++++++++++++++++++----- src/rt/rust_builtin.cpp | 6 ++++++ src/rt/rustrt.def.in | 1 + 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/libstd/run.rs b/src/libstd/run.rs index b204cf6cfb04..7a96bf35218b 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -915,7 +915,7 @@ priv fn waitpid(pid: pid_t) -> int { #[cfg(test)] mod tests { use io; - use libc::{c_int}; + use libc::{c_int, uintptr_t}; use option::{Option, None, Some}; use os; use path::Path; @@ -958,7 +958,10 @@ mod tests { assert_eq!(status, 0); assert_eq!(output_str.trim().to_owned(), ~"hello"); - assert_eq!(error, ~[]); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } } #[test] @@ -1043,7 +1046,10 @@ mod tests { assert_eq!(status, 0); assert_eq!(output_str.trim().to_owned(), ~"hello"); - assert_eq!(error, ~[]); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } } #[test] @@ -1057,14 +1063,20 @@ mod tests { assert_eq!(status, 0); assert_eq!(output_str.trim().to_owned(), ~"hello"); - assert_eq!(error, ~[]); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } let run::ProcessOutput {status, output, error} = prog.finish_with_output(); assert_eq!(status, 0); assert_eq!(output, ~[]); - assert_eq!(error, ~[]); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } } #[test] @@ -1169,4 +1181,12 @@ mod tests { assert!(output.contains("RUN_TEST_NEW_ENV=123")); } + + fn running_on_valgrind() -> bool { + unsafe { rust_running_on_valgrind() != 0 } + } + + extern { + fn rust_running_on_valgrind() -> uintptr_t; + } } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 5e7357c9b7b2..3bd5e09e0073 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -17,6 +17,7 @@ #include "sync/timer.h" #include "sync/rust_thread.h" #include "rust_abi.h" +#include "vg/valgrind.h" #include @@ -930,6 +931,11 @@ rust_begin_unwind(uintptr_t token) { #endif } +extern "C" CDECL uintptr_t +rust_running_on_valgrind() { + return RUNNING_ON_VALGRIND; +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index e3e522aa7cee..ba7ada04a275 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -239,3 +239,4 @@ rust_valgrind_stack_deregister rust_take_env_lock rust_drop_env_lock rust_update_log_settings +rust_running_on_valgrind \ No newline at end of file From fb2765eebd33fbc0218c51313b629a079a09d9fc Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 18 Jun 2013 22:17:58 -0700 Subject: [PATCH 66/96] rusti: Disable tests on macos harder --- src/librusti/rusti.rc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index a67915fbc851..c618623a2cb7 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -538,8 +538,8 @@ mod tests { #[test] // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(and(target_word_size=32, - target_os="mac")))] + #[cfg(not(target_word_size="32", + target_os="macos"))] fn run_all() { // FIXME(#7071): // By default, unit tests are run in parallel. Rusti, on the other hand, @@ -652,8 +652,8 @@ mod tests { #[test] // FIXME: #7220 rusti on 32bit mac doesn't work. - #[cfg(not(and(target_word_size=32, - target_os="mac")))] + #[cfg(not(target_word_size="32", + target_os="macos"))] fn exit_quits() { let mut r = repl(); assert!(r.running); From 1120f8c1e57b7b30134d670dd1dfc18c6444c15f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 10 Jun 2013 17:46:49 -0700 Subject: [PATCH 67/96] std::rt: Work around a dynamic borrowck bug --- src/libstd/rt/io/extensions.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index a5e68bcdac4c..55861f127bb4 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -750,8 +750,6 @@ mod test { #[should_fail] #[ignore(cfg(windows))] fn push_bytes_fail_reset_len() { - use unstable::finally::Finally; - // push_bytes unsafely sets the vector length. This is testing that // upon failure the length is reset correctly. let mut reader = MockReader::new(); @@ -773,7 +771,8 @@ mod test { reader.push_bytes(&mut *buf, 4); }).finally { // NB: Using rtassert here to trigger abort on failure since this is a should_fail test - rtassert!(*buf == ~[8, 9, 10]); + // FIXME: #7049 This fails because buf is still borrowed + //rtassert!(*buf == ~[8, 9, 10]); } } From 915aaa7f67671186348b1b6c10d765a3d9ab6e37 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 19 Jun 2013 00:39:10 -0700 Subject: [PATCH 68/96] std::rt: Set the process exit code --- src/libstd/rt/mod.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 581e3addff0f..899fa171b727 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -74,6 +74,8 @@ use rt::task::Task; use rt::thread::Thread; use rt::work_queue::WorkQueue; use rt::uv::uvio::UvEventLoop; +use unstable::atomics::{AtomicInt, SeqCst}; +use unstable::sync::UnsafeAtomicRcBox; use vec::{OwnedVector, MutableVector}; /// The global (exchange) heap. @@ -174,10 +176,10 @@ pub mod util; pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int { init(crate_map); - run(main); + let exit_code = run(main); cleanup(); - return 0; + return exit_code; } /// One-time runtime initialization. Currently all this does is set up logging @@ -190,7 +192,9 @@ pub fn cleanup() { global_heap::cleanup(); } -pub fn run(main: ~fn()) { +pub fn run(main: ~fn()) -> int { + static DEFAULT_ERROR_CODE: int = 101; + let nthreads = match os::getenv("RUST_THREADS") { Some(nstr) => FromStr::from_str(nstr).get(), None => unsafe { @@ -216,10 +220,13 @@ pub fn run(main: ~fn()) { scheds.push(sched); } + let exit_code = UnsafeAtomicRcBox::new(AtomicInt::new(0)); + let exit_code_clone = exit_code.clone(); + let main_cell = Cell::new(main); let handles = Cell::new(handles); let mut new_task = ~Task::new_root(); - let on_exit: ~fn(bool) = |exit_status| { + let on_exit: ~fn(bool) = |exit_success| { let mut handles = handles.take(); // Tell schedulers to exit @@ -227,7 +234,10 @@ pub fn run(main: ~fn()) { handle.send(Shutdown); } - rtassert!(exit_status); + unsafe { + let exit_code = if exit_success { 0 } else { DEFAULT_ERROR_CODE }; + (*exit_code_clone.get()).store(exit_code, SeqCst); + } }; new_task.on_exit = Some(on_exit); let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool, @@ -249,6 +259,10 @@ pub fn run(main: ~fn()) { // Wait for schedulers let _threads = threads; + + unsafe { + (*exit_code.get()).load(SeqCst) + } } /// Possible contexts in which Rust code may be executing. From 5722c953e5180ae3e086b4354f65ee8b5fb8d868 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 19 Jun 2013 00:49:05 -0700 Subject: [PATCH 69/96] std::rt: Correct the numbers of default cores --- src/libstd/rt/mod.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 899fa171b727..58da7549b3f2 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -197,12 +197,7 @@ pub fn run(main: ~fn()) -> int { let nthreads = match os::getenv("RUST_THREADS") { Some(nstr) => FromStr::from_str(nstr).get(), - None => unsafe { - // Using more threads than cores in test code - // to force the OS to preempt them frequently. - // Assuming that this help stress test concurrent types. - util::num_cpus() * 2 - } + None => unsafe { util::num_cpus() } }; let sleepers = SleeperList::new(); From e1555f9b5628af2b6c6ed344cad621399cb7684d Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 19 Jun 2013 01:08:47 -0700 Subject: [PATCH 70/96] std::rt: Document and cleanup the run function --- src/libstd/rt/mod.rs | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 58da7549b3f2..dd4c71eca745 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -63,11 +63,11 @@ use cell::Cell; use clone::Clone; use container::Container; use from_str::FromStr; +use iter::Times; use iterator::IteratorUtil; use option::{Some, None}; use os; use ptr::RawPtr; -use uint; use rt::sched::{Scheduler, Coroutine, Shutdown}; use rt::sleeper_list::SleeperList; use rt::task::Task; @@ -150,7 +150,7 @@ pub mod local_ptr; /// Bindings to pthread/windows thread-local storage. pub mod thread_local_storage; -/// A concurrent data structure with which parent tasks wait on child tasks. +/// For waiting on child tasks. pub mod join_latch; pub mod metrics; @@ -188,11 +188,18 @@ pub fn init(crate_map: *u8) { logging::init(crate_map); } +/// One-time runtime cleanup. pub fn cleanup() { global_heap::cleanup(); } +/// Execute the main function in a scheduler. +/// +/// Configures the runtime according to the environment, by default +/// using a task scheduler with the same number of threads as cores. +/// Returns a process exit code. pub fn run(main: ~fn()) -> int { + static DEFAULT_ERROR_CODE: int = 101; let nthreads = match os::getenv("RUST_THREADS") { @@ -200,31 +207,39 @@ pub fn run(main: ~fn()) -> int { None => unsafe { util::num_cpus() } }; + // The shared list of sleeping schedulers. Schedulers wake each other + // occassionally to do new work. let sleepers = SleeperList::new(); + // The shared work queue. Temporary until work stealing is implemented. let work_queue = WorkQueue::new(); - let mut handles = ~[]; + // The schedulers. let mut scheds = ~[]; + // Handles to the schedulers. When the main task ends these will be + // sent the Shutdown message to terminate the schedulers. + let mut handles = ~[]; - for uint::range(0, nthreads) |_| { + for nthreads.times { + // Every scheduler is driven by an I/O event loop. let loop_ = ~UvEventLoop::new(); let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone()); let handle = sched.make_handle(); - handles.push(handle); scheds.push(sched); + handles.push(handle); } + // Create a shared cell for transmitting the process exit + // code from the main task to this function. let exit_code = UnsafeAtomicRcBox::new(AtomicInt::new(0)); let exit_code_clone = exit_code.clone(); - let main_cell = Cell::new(main); + // When the main task exits, after all the tasks in the main + // task tree, shut down the schedulers and set the exit code. let handles = Cell::new(handles); - let mut new_task = ~Task::new_root(); let on_exit: ~fn(bool) = |exit_success| { let mut handles = handles.take(); - // Tell schedulers to exit for handles.mut_iter().advance |handle| { handle.send(Shutdown); } @@ -234,13 +249,17 @@ pub fn run(main: ~fn()) -> int { (*exit_code_clone.get()).store(exit_code, SeqCst); } }; + + // Create and enqueue the main task. + let main_cell = Cell::new(main); + let mut new_task = ~Task::new_root(); new_task.on_exit = Some(on_exit); let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool, new_task, main_cell.take()); scheds[0].enqueue_task(main_task); + // Run each scheduler in a thread. let mut threads = ~[]; - while !scheds.is_empty() { let sched = scheds.pop(); let sched_cell = Cell::new(sched); @@ -253,8 +272,9 @@ pub fn run(main: ~fn()) -> int { } // Wait for schedulers - let _threads = threads; + { let _threads = threads; } + // Return the exit code unsafe { (*exit_code.get()).load(SeqCst) } From b7a69198992fceb7b2c6affb5e0a7ed862ebc090 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 19 Jun 2013 15:18:25 -0700 Subject: [PATCH 71/96] rustc: Dispose of LLVM passes in test cases --- src/librustc/back/passes.rs | 15 ++++++++++++--- src/librustc/lib/llvm.rs | 3 +++ src/rustllvm/PassWrapper.cpp | 5 +++++ src/rustllvm/rustllvm.def.in | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs index 07e5d9e4f25a..987c76dccb42 100644 --- a/src/librustc/back/passes.rs +++ b/src/librustc/back/passes.rs @@ -299,18 +299,27 @@ fn passes_exist() { let mut failed = ~[]; unsafe { llvm::LLVMInitializePasses(); } for analysis_passes.each() |&(name,_)| { - if !create_pass(name).is_some() { + let pass = create_pass(name); + if !pass.is_some() { failed.push(name); + } else { + unsafe { llvm::LLVMDestroyPass(pass.get()) } } } for transform_passes.each() |&(name,_)| { - if !create_pass(name).is_some() { + let pass = create_pass(name); + if !pass.is_some() { failed.push(name); + } else { + unsafe { llvm::LLVMDestroyPass(pass.get()) } } } for utility_passes.each() |&(name,_)| { - if !create_pass(name).is_some() { + let pass = create_pass(name); + if !pass.is_some() { failed.push(name); + } else { + unsafe { llvm::LLVMDestroyPass(pass.get()) } } } diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 835dd55711b5..2b2c1e27cbc3 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1684,6 +1684,9 @@ pub mod llvm { #[fast_ffi] pub unsafe fn LLVMCreatePass(PassName:*c_char) -> PassRef; + #[fast_ffi] + pub unsafe fn LLVMDestroyPass(P: PassRef); + /** Adds a verification pass. */ #[fast_ffi] pub unsafe fn LLVMAddVerifierPass(PM: PassManagerRef); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 53b291ff470d..32b6df4e1dd5 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -63,3 +63,8 @@ extern "C" LLVMPassRef LLVMCreatePass(const char * PassName) { return (LLVMPassRef)0; } } + +extern "C" void LLVMDestroyPass(LLVMPassRef PassRef) { + Pass *p = unwrap(PassRef); + delete p; +} diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 2a3f7de9bf5a..d5f03ac604b7 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -588,6 +588,7 @@ LLVMInlineAsm LLVMInitializePasses LLVMAddPass LLVMCreatePass +LLVMDestroyPass LLVMDIBuilderCreate LLVMDIBuilderDispose LLVMDIBuilderFinalize From 5086c0850ebdd8407901d108f312ab141e4a4a18 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 19 Jun 2013 16:08:07 -0700 Subject: [PATCH 72/96] std::rt: Update GC metadata in init --- src/libstd/rt/mod.rs | 5 +++++ src/rt/rust_gc_metadata.cpp | 5 +++++ src/rt/rustrt.def.in | 1 + 3 files changed, 11 insertions(+) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index dd4c71eca745..a80fb15bad79 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -186,6 +186,11 @@ pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int { /// based on the RUST_LOG environment variable. pub fn init(crate_map: *u8) { logging::init(crate_map); + unsafe { rust_update_gc_metadata(crate_map) } + + extern { + fn rust_update_gc_metadata(crate_map: *u8); + } } /// One-time runtime cleanup. diff --git a/src/rt/rust_gc_metadata.cpp b/src/rt/rust_gc_metadata.cpp index fbf0575b31dc..e37856255a7d 100644 --- a/src/rt/rust_gc_metadata.cpp +++ b/src/rt/rust_gc_metadata.cpp @@ -79,6 +79,11 @@ rust_gc_metadata() { return (void *)global_safe_points; } +extern "C" CDECL void +rust_update_gc_metadata(const void* map) { + update_gc_metadata(map); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 9b49583519ec..c93d29f6148c 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -178,6 +178,7 @@ rust_call_tydesc_glue tdefl_compress_mem_to_heap tinfl_decompress_mem_to_heap rust_gc_metadata +rust_update_gc_metadata rust_uv_ip4_port rust_uv_ip6_port rust_uv_tcp_getpeername From 391bb0b4e7131cd7d30e03deea3eb9756a7c8954 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 19 Jun 2013 18:37:50 -0700 Subject: [PATCH 73/96] std: Make newsched failures log correctly --- src/libstd/sys.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index e49ad3485420..f2591996e3a9 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -180,10 +180,13 @@ impl FailWithCause for &'static str { // FIXME #4427: Temporary until rt::rt_fail_ goes away pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { + use cell::Cell; use option::Option; + use either::Left; use rt::{context, OldTaskContext, TaskContext}; use rt::task::{Task, Unwinder}; use rt::local::Local; + use rt::logging::Logger; let context = context(); match context { @@ -200,12 +203,18 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { let msg = str::raw::from_c_str(msg); let file = str::raw::from_c_str(file); - let outmsg = fmt!("%s at line %i of file %s", msg, line as int, file); + let outmsg = fmt!("task failed: '%s' at line %i of file %s", + msg, line as int, file); // XXX: Logging doesn't work correctly in non-task context because it // invokes the local heap if context == TaskContext { - error!(outmsg); + // XXX: Logging doesn't work here - the check to call the log + // function never passes - so calling the log function directly. + let outmsg = Cell::new(outmsg); + do Local::borrow:: |task| { + task.logger.log(Left(outmsg.take())); + } } else { rtdebug!("%s", outmsg); } From 73c1839579a6b5f302f5497189d69c9a61760a6c Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 19 Jun 2013 21:12:40 -0400 Subject: [PATCH 74/96] libsyntax: Remove `drop` as a keyword. --- src/libsyntax/parse/token.rs | 237 +++++++++++++++++++++++++++++------ 1 file changed, 202 insertions(+), 35 deletions(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index e7bc67340f01..fc6f07288f27 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -400,7 +400,9 @@ impl ident_interner { } } + // return a fresh interner, preloaded with special identifiers. +#[cfg(stage0)] fn mk_fresh_ident_interner() -> @ident_interner { // the indices here must correspond to the numbers in // special_idents. @@ -486,6 +488,92 @@ fn mk_fresh_ident_interner() -> @ident_interner { } } +// return a fresh interner, preloaded with special identifiers. +#[cfg(not(stage0))] +fn mk_fresh_ident_interner() -> @ident_interner { + // the indices here must correspond to the numbers in + // special_idents. + let init_vec = ~[ + "_", // 0 + "anon", // 1 + "", // 2 + "unary", // 3 + "!", // 4 + "[]", // 5 + "unary-", // 6 + "__extensions__", // 7 + "self", // 8 + "item", // 9 + "block", // 10 + "stmt", // 11 + "pat", // 12 + "expr", // 13 + "ty", // 14 + "ident", // 15 + "path", // 16 + "tt", // 17 + "matchers", // 18 + "str", // 19 + "TyVisitor", // 20 + "arg", // 21 + "descrim", // 22 + "__rust_abi", // 23 + "__rust_stack_shim", // 24 + "TyDesc", // 25 + "main", // 26 + "", // 27 + "blk", // 28 + "static", // 29 + "intrinsic", // 30 + "__foreign_mod__", // 31 + "__field__", // 32 + "C", // 33 + "Self", // 34 + + "as", // 35 + "break", // 36 + "const", // 37 + "copy", // 38 + "do", // 39 + "else", // 40 + "enum", // 41 + "extern", // 42 + "false", // 43 + "fn", // 44 + "for", // 45 + "if", // 46 + "impl", // 47 + "let", // 48 + "__log", // 49 + "loop", // 50 + "match", // 51 + "mod", // 52 + "mut", // 53 + "once", // 54 + "priv", // 55 + "pub", // 56 + "pure", // 57 + "ref", // 58 + "return", // 59 + "static", // 29 -- also a special ident + "self", // 8 -- also a special ident + "struct", // 60 + "super", // 61 + "true", // 62 + "trait", // 63 + "type", // 64 + "unsafe", // 65 + "use", // 66 + "while", // 67 + + "be", // 68 + ]; + + @ident_interner { + interner: interner::StrInterner::prefill(init_vec) + } +} + // if an interner exists in TLS, return it. Otherwise, prepare a // fresh one. pub fn get_ident_interner() -> @ident_interner { @@ -612,44 +700,86 @@ pub mod keywords { } impl Keyword { + #[cfg(stage0)] pub fn to_ident(&self) -> ident { match *self { As => ident { name: 35, ctxt: 0 }, - Break => ident { name: 36, ctxt: 0 }, - Const => ident { name: 37, ctxt: 0 }, - Copy => ident { name: 38, ctxt: 0 }, - Do => ident { name: 39, ctxt: 0 }, - Else => ident { name: 41, ctxt: 0 }, - Enum => ident { name: 42, ctxt: 0 }, - Extern => ident { name: 43, ctxt: 0 }, - False => ident { name: 44, ctxt: 0 }, - Fn => ident { name: 45, ctxt: 0 }, - For => ident { name: 46, ctxt: 0 }, - If => ident { name: 47, ctxt: 0 }, - Impl => ident { name: 48, ctxt: 0 }, - Let => ident { name: 49, ctxt: 0 }, - __Log => ident { name: 50, ctxt: 0 }, - Loop => ident { name: 51, ctxt: 0 }, - Match => ident { name: 52, ctxt: 0 }, - Mod => ident { name: 53, ctxt: 0 }, - Mut => ident { name: 54, ctxt: 0 }, - Once => ident { name: 55, ctxt: 0 }, - Priv => ident { name: 56, ctxt: 0 }, - Pub => ident { name: 57, ctxt: 0 }, - Pure => ident { name: 58, ctxt: 0 }, - Ref => ident { name: 59, ctxt: 0 }, - Return => ident { name: 60, ctxt: 0 }, - Static => ident { name: 29, ctxt: 0 }, - Self => ident { name: 8, ctxt: 0 }, - Struct => ident { name: 61, ctxt: 0 }, - Super => ident { name: 62, ctxt: 0 }, - True => ident { name: 63, ctxt: 0 }, - Trait => ident { name: 64, ctxt: 0 }, - Type => ident { name: 65, ctxt: 0 }, - Unsafe => ident { name: 66, ctxt: 0 }, - Use => ident { name: 67, ctxt: 0 }, - While => ident { name: 68, ctxt: 0 }, - Be => ident { name: 69, ctxt: 0 }, + Break => ident { name: 36, ctxt: 0 }, + Const => ident { name: 37, ctxt: 0 }, + Copy => ident { name: 38, ctxt: 0 }, + Do => ident { name: 39, ctxt: 0 }, + Else => ident { name: 41, ctxt: 0 }, + Enum => ident { name: 42, ctxt: 0 }, + Extern => ident { name: 43, ctxt: 0 }, + False => ident { name: 44, ctxt: 0 }, + Fn => ident { name: 45, ctxt: 0 }, + For => ident { name: 46, ctxt: 0 }, + If => ident { name: 47, ctxt: 0 }, + Impl => ident { name: 48, ctxt: 0 }, + Let => ident { name: 49, ctxt: 0 }, + __Log => ident { name: 50, ctxt: 0 }, + Loop => ident { name: 51, ctxt: 0 }, + Match => ident { name: 52, ctxt: 0 }, + Mod => ident { name: 53, ctxt: 0 }, + Mut => ident { name: 54, ctxt: 0 }, + Once => ident { name: 55, ctxt: 0 }, + Priv => ident { name: 56, ctxt: 0 }, + Pub => ident { name: 57, ctxt: 0 }, + Pure => ident { name: 58, ctxt: 0 }, + Ref => ident { name: 59, ctxt: 0 }, + Return => ident { name: 60, ctxt: 0 }, + Static => ident { name: 29, ctxt: 0 }, + Self => ident { name: 8, ctxt: 0 }, + Struct => ident { name: 61, ctxt: 0 }, + Super => ident { name: 62, ctxt: 0 }, + True => ident { name: 63, ctxt: 0 }, + Trait => ident { name: 64, ctxt: 0 }, + Type => ident { name: 65, ctxt: 0 }, + Unsafe => ident { name: 66, ctxt: 0 }, + Use => ident { name: 67, ctxt: 0 }, + While => ident { name: 68, ctxt: 0 }, + Be => ident { name: 69, ctxt: 0 }, + } + } + #[cfg(not(stage0))] + pub fn to_ident(&self) -> ident { + match *self { + As => ident { name: 35, ctxt: 0 }, + Break => ident { name: 36, ctxt: 0 }, + Const => ident { name: 37, ctxt: 0 }, + Copy => ident { name: 38, ctxt: 0 }, + Do => ident { name: 39, ctxt: 0 }, + Else => ident { name: 40, ctxt: 0 }, + Enum => ident { name: 41, ctxt: 0 }, + Extern => ident { name: 42, ctxt: 0 }, + False => ident { name: 43, ctxt: 0 }, + Fn => ident { name: 44, ctxt: 0 }, + For => ident { name: 45, ctxt: 0 }, + If => ident { name: 46, ctxt: 0 }, + Impl => ident { name: 47, ctxt: 0 }, + Let => ident { name: 48, ctxt: 0 }, + __Log => ident { name: 49, ctxt: 0 }, + Loop => ident { name: 50, ctxt: 0 }, + Match => ident { name: 51, ctxt: 0 }, + Mod => ident { name: 52, ctxt: 0 }, + Mut => ident { name: 53, ctxt: 0 }, + Once => ident { name: 54, ctxt: 0 }, + Priv => ident { name: 55, ctxt: 0 }, + Pub => ident { name: 56, ctxt: 0 }, + Pure => ident { name: 57, ctxt: 0 }, + Ref => ident { name: 58, ctxt: 0 }, + Return => ident { name: 59, ctxt: 0 }, + Static => ident { name: 29, ctxt: 0 }, + Self => ident { name: 8, ctxt: 0 }, + Struct => ident { name: 60, ctxt: 0 }, + Super => ident { name: 61, ctxt: 0 }, + True => ident { name: 62, ctxt: 0 }, + Trait => ident { name: 63, ctxt: 0 }, + Type => ident { name: 64, ctxt: 0 }, + Unsafe => ident { name: 65, ctxt: 0 }, + Use => ident { name: 66, ctxt: 0 }, + While => ident { name: 67, ctxt: 0 }, + Be => ident { name: 68, ctxt: 0 }, } } } @@ -662,6 +792,7 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool { } } +#[cfg(stage0)] pub fn is_any_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { @@ -672,6 +803,18 @@ pub fn is_any_keyword(tok: &Token) -> bool { } } +#[cfg(not(stage0))] +pub fn is_any_keyword(tok: &Token) -> bool { + match *tok { + token::IDENT(sid, false) => match sid.name { + 8 | 29 | 35 .. 68 => true, + _ => false, + }, + _ => false + } +} + +#[cfg(stage0)] pub fn is_strict_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { @@ -682,6 +825,18 @@ pub fn is_strict_keyword(tok: &Token) -> bool { } } +#[cfg(not(stage0))] +pub fn is_strict_keyword(tok: &Token) -> bool { + match *tok { + token::IDENT(sid, false) => match sid.name { + 8 | 29 | 35 .. 67 => true, + _ => false, + }, + _ => false, + } +} + +#[cfg(stage0)] pub fn is_reserved_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { @@ -692,6 +847,18 @@ pub fn is_reserved_keyword(tok: &Token) -> bool { } } +#[cfg(not(stage0))] +pub fn is_reserved_keyword(tok: &Token) -> bool { + match *tok { + token::IDENT(sid, false) => match sid.name { + 68 => true, + _ => false, + }, + _ => false, + } +} + + #[cfg(test)] mod test { use super::*; From 433c86554c22845509ac4bfaed0edfb1909d8ad3 Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 15:10:08 +1200 Subject: [PATCH 75/96] Fix update snapshot script for rename --- src/etc/snapshot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 123987d4b1ea..3eda5a97eb6d 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -26,29 +26,29 @@ download_unpack_base = os.path.join(download_dir_base, "unpack") snapshot_files = { "linux": ["bin/rustc", - "lib/libcore-*.so", "lib/libstd-*.so", + "lib/libextra-*.so", "lib/librustc-*.so", "lib/libsyntax-*.so", "lib/librustrt.so", "lib/librustllvm.so"], "macos": ["bin/rustc", - "lib/libcore-*.dylib", "lib/libstd-*.dylib", + "lib/libcore-*.dylib", "lib/librustc-*.dylib", "lib/libsyntax-*.dylib", "lib/librustrt.dylib", "lib/librustllvm.dylib"], "winnt": ["bin/rustc.exe", - "bin/core-*.dll", "bin/std-*.dll", + "bin/extra-*.dll", "bin/rustc-*.dll", "bin/syntax-*.dll", "bin/rustrt.dll", "bin/rustllvm.dll"], "freebsd": ["bin/rustc", - "lib/libcore-*.so", "lib/libstd-*.so", + "lib/libextra-*.so", "lib/librustc-*.so", "lib/libsyntax-*.so", "lib/librustrt.so", From 82ba030a4fd6a330f83755ae87442e725f103d4e Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 18:07:06 +1200 Subject: [PATCH 76/96] Ignore rustpkg tests --- src/librustpkg/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 6ec14e2aecf6..8b9158732696 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -309,7 +309,7 @@ fn frob_source_file(workspace: &Path, pkgid: &PkgId) { } } -#[test] +#[test] #[ignore] //FIXME(#7249) fn test_all() { // FIXME(#7071): these tests use rustc, so they can't be run in parallel // until this issue is resolved From 7375e94289622663ba9976e2702a4008cd0aad1a Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 20:47:22 +1200 Subject: [PATCH 77/96] core -> extra for mac --- src/etc/snapshot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 3eda5a97eb6d..608dbdcca5d2 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -34,7 +34,7 @@ snapshot_files = { "lib/librustllvm.so"], "macos": ["bin/rustc", "lib/libstd-*.dylib", - "lib/libcore-*.dylib", + "lib/libextra-*.dylib", "lib/librustc-*.dylib", "lib/libsyntax-*.dylib", "lib/librustrt.dylib", From f5036c24df72f4c9fefe1d011708dfdad9d31c67 Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 22:03:05 +1200 Subject: [PATCH 78/96] xfail box-related debug-info tests r=snapshot --- src/test/debug-info/box.rs | 4 ++-- src/test/debug-info/vec.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs index 3e5483ad75b3..ef2a98d92fbc 100644 --- a/src/test/debug-info/box.rs +++ b/src/test/debug-info/box.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 +// xfail // compile-flags:-Z extra-debug-info // debugger:set print pretty off @@ -32,4 +32,4 @@ fn main() { _zzz(); } -fn _zzz() {()} \ No newline at end of file +fn _zzz() {()} diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index c87849ac4b6d..8a8c57202800 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 +// xfail // compile-flags:-Z extra-debug-info // debugger:set print pretty off @@ -32,4 +32,4 @@ fn main() { _zzz(); } -fn _zzz() {()} \ No newline at end of file +fn _zzz() {()} From 3acdbfd2c843ff2be79652df34a2a1959d18685d Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 22:43:21 +1200 Subject: [PATCH 79/96] ignore inherited environment test under valgrind r=snapshot --- src/libstd/run.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 7a96bf35218b..060de3f4d5d5 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -1160,6 +1160,7 @@ mod tests { #[test] fn test_inherit_env() { + if running_on_valgrind() { return; } let mut prog = run_env(None); let output = str::from_bytes(prog.finish_with_output().output); From 6759ce4fd2083595193c93c3fd72383d24a73a5e Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 21 Jun 2013 00:23:42 +1200 Subject: [PATCH 80/96] _Actually_ xfail debuginfo tests --- src/test/debug-info/box.rs | 2 +- src/test/debug-info/vec.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs index ef2a98d92fbc..4a3a65a90550 100644 --- a/src/test/debug-info/box.rs +++ b/src/test/debug-info/box.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail +// xfail-test // compile-flags:-Z extra-debug-info // debugger:set print pretty off diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index 8a8c57202800..f198a53729eb 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail +// xfail-test // compile-flags:-Z extra-debug-info // debugger:set print pretty off From 3bc4d1a1206ad5f4bb31475e17fc18ecf855ed8e Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 17:15:50 +1200 Subject: [PATCH 81/96] Remove all #[cfg(stage0)]-protected code New snapshot means this can all go. Also removes places that have comments that say they are workarounds for stage0 errors. --- src/libextra/num/complex.rs | 2 - src/libextra/std.rc | 6 - src/libextra/time.rs | 2 +- src/librustc/back/rpath.rs | 13 -- src/librustc/driver/driver.rs | 19 --- src/librustc/middle/liveness.rs | 6 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/typeck/check/vtable.rs | 9 +- src/librustc/middle/typeck/coherence.rs | 8 +- src/librustc/rustc.rc | 8 - src/libstd/cast.rs | 17 +-- src/libstd/core.rc | 4 - src/libstd/io.rs | 4 +- src/libstd/ptr.rs | 69 +-------- src/libstd/unstable/intrinsics.rs | 13 -- src/libsyntax/parse/token.rs | 166 --------------------- src/libsyntax/syntax.rc | 9 -- src/rt/rust_builtin.cpp | 11 -- src/rt/rust_task.cpp | 8 - src/rt/rust_type.h | 8 - 20 files changed, 15 insertions(+), 369 deletions(-) diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index b75537b8b3ef..c626260043ee 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -80,7 +80,6 @@ impl Cmplx { } } -#[cfg(not(stage0))] // Fixed by #4228 impl Cmplx { /// Calculate |self| #[inline] @@ -89,7 +88,6 @@ impl Cmplx { } } -#[cfg(not(stage0))] // Fixed by #4228 impl Cmplx { /// Calculate the principal Arg of self. #[inline] diff --git a/src/libextra/std.rc b/src/libextra/std.rc index 96c53266c6f1..d4c85ef51362 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -32,16 +32,10 @@ Rust extras are part of the standard Rust distribution. #[deny(non_camel_case_types)]; #[deny(missing_doc)]; -// NOTE: remove these two attributes after the next snapshot -#[no_core]; // for stage0 -#[allow(unrecognized_lint)]; // otherwise stage0 is seriously ugly - #[no_std]; extern mod core(name = "std", vers = "0.7-pre"); -#[cfg(stage0)] -use core::{str, unstable}; use core::str::{StrSlice, OwnedStr}; pub use core::os; diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 50592d5f7309..005238a564e8 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -275,7 +275,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { let mut i = 0u; let len = strs.len(); while i < len { - match strs[i] { // can't use let due to stage0 bugs + match strs[i] { // can't use let due to let-pattern bugs (ref needle, value) => { if match_str(ss, pos, *needle) { return Some((value, pos + needle.len())); diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index ed70f41f3ec8..fd22a7e79c6e 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -174,19 +174,6 @@ pub fn get_absolute_rpath(lib: &Path) -> Path { os::make_absolute(lib).dir_path() } -#[cfg(stage0)] -pub fn get_install_prefix_rpath(target_triple: &str) -> Path { - let install_prefix = env!("CFG_PREFIX"); - - if install_prefix.is_empty() { - fail!("rustc compiled without CFG_PREFIX environment variable"); - } - - let tlib = filesearch::relative_target_lib_path(target_triple); - os::make_absolute(&Path(install_prefix).push_rel(&tlib)) -} - -#[cfg(not(stage0))] pub fn get_install_prefix_rpath(target_triple: &str) -> Path { let install_prefix = env!("CFG_PREFIX"); diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index cc1eb3736526..43b3397094b5 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -521,25 +521,6 @@ pub fn build_target_config(sopts: @session::options, return target_cfg; } -#[cfg(stage0)] -pub fn host_triple() -> ~str { - // Get the host triple out of the build environment. This ensures that our - // idea of the host triple is the same as for the set of libraries we've - // actually built. We can't just take LLVM's host triple because they - // normalize all ix86 architectures to i386. - // - // Instead of grabbing the host triple (for the current host), we grab (at - // compile time) the target triple that this rustc is built with and - // calling that (at runtime) the host triple. - let ht = env!("CFG_COMPILER_TRIPLE"); - return if ht != ~"" { - ht - } else { - fail!("rustc built without CFG_COMPILER_TRIPLE") - }; -} - -#[cfg(not(stage0))] pub fn host_triple() -> ~str { // Get the host triple out of the build environment. This ensures that our // idea of the host triple is the same as for the set of libraries we've diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1c335ee40842..08cba4d51cd3 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -749,11 +749,7 @@ impl Liveness { None => { // Vanilla 'break' or 'loop', so use the enclosing // loop scope - let len = { // FIXME(#5074) stage0 - let loop_scope = &mut *self.loop_scope; - loop_scope.len() - }; - if len == 0 { + if self.loop_scope.len() == 0 { self.tcx.sess.span_bug(sp, "break outside loop"); } else { // FIXME(#5275): this shouldn't have to be a method... diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 55fc22a8fcc0..a050467529ac 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1318,7 +1318,7 @@ pub fn cleanup_and_leave(bcx: block, match cur.kind { block_scope(inf) if !inf.empty_cleanups() => { let (sub_cx, dest, inf_cleanups) = { - let inf = &mut *inf; // FIXME(#5074) workaround stage0 + let inf = &mut *inf; let mut skip = 0; let mut dest = None; { diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 99e68e3330bf..207f986efd92 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -248,16 +248,9 @@ fn lookup_vtable(vcx: &VtableContext, // Nothing found. Continue. } Some(implementations) => { - let len = { // FIXME(#5074): stage0 requires it - let implementations: &mut ~[@Impl] = *implementations; - implementations.len() - }; - // implementations is the list of all impls in scope for // trait_ref. (Usually, there's just one.) - for uint::range(0, len) |i| { - let im = implementations[i]; - + for implementations.iter().advance |im| { // im is one specific impl of trait_ref. // First, ensure we haven't processed this impl yet. diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 9528c825fbed..d71820a67b35 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -520,12 +520,8 @@ impl CoherenceChecker { match extension_methods.find(&trait_def_id) { Some(impls) => { - let len = { // FIXME(#5074) stage0 requires this - let impls: &mut ~[@Impl] = *impls; - impls.len() - }; - for uint::range(0, len) |i| { - f(impls[i]); + for impls.iter().advance |&im| { + f(im); } } None => { /* no impls? */ } diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 1197693d1b6d..021dd6648cbf 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -28,16 +28,8 @@ extern mod core(name = "std"); extern mod extra(name = "extra"); extern mod syntax; -// For deriving(Encodable) purposes... -#[cfg(stage0)] -extern mod std(name = "extra", vers = "0.7-pre"); -#[cfg(not(stage0))] extern mod std(name = "std", vers = "0.7-pre"); -// For bootstrapping purposes. -#[cfg(stage0)] -pub use core::unstable; - use core::prelude::*; use driver::driver::{host_triple, optgroups, early_error}; diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index 900cc6009238..30b6b030dba2 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -14,21 +14,8 @@ use sys; use unstable::intrinsics; /// Casts the value at `src` to U. The two types must have the same length. -#[cfg(stage0)] -pub unsafe fn transmute_copy(src: &T) -> U { - let mut dest: U = intrinsics::uninit(); - { - let dest_ptr: *mut u8 = transmute(&mut dest); - let src_ptr: *u8 = transmute(src); - intrinsics::memmove64(dest_ptr, - src_ptr, - sys::size_of::() as u64); - } - dest -} - /// Casts the value at `src` to U. The two types must have the same length. -#[cfg(target_word_size = "32", not(stage0))] +#[cfg(target_word_size = "32")] #[inline] pub unsafe fn transmute_copy(src: &T) -> U { let mut dest: U = intrinsics::uninit(); @@ -39,7 +26,7 @@ pub unsafe fn transmute_copy(src: &T) -> U { } /// Casts the value at `src` to U. The two types must have the same length. -#[cfg(target_word_size = "64", not(stage0))] +#[cfg(target_word_size = "64")] #[inline] pub unsafe fn transmute_copy(src: &T) -> U { let mut dest: U = intrinsics::uninit(); diff --git a/src/libstd/core.rc b/src/libstd/core.rc index f37f65c1edcd..6911c00e55ba 100644 --- a/src/libstd/core.rc +++ b/src/libstd/core.rc @@ -57,10 +57,6 @@ they contained the following prologue: #[license = "MIT/ASL2"]; #[crate_type = "lib"]; -// NOTE: remove these two attributes after the next snapshot -#[no_core]; // for stage0 -#[allow(unrecognized_lint)]; // otherwise stage0 is seriously ugly - // Don't link to std. We are std. #[no_std]; diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 3e771c4dddeb..e5e8a4cb6018 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1654,9 +1654,7 @@ impl Writer for BytesWriter { vec::reserve(bytes, count); unsafe { - // Silly stage0 borrow check workaround... - let casted: &mut ~[u8] = cast::transmute_copy(&bytes); - vec::raw::set_len(casted, count); + vec::raw::set_len(bytes, count); let view = vec::mut_slice(*bytes, *self.pos, count); vec::bytes::copy_memory(view, v, v_len); diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index b505602702b4..7f89d454be11 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -75,21 +75,7 @@ pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } * and destination may overlap. */ #[inline] -#[cfg(target_word_size = "32", stage0)] -pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { - use unstable::intrinsics::memmove32; - let n = count * sys::size_of::(); - memmove32(dst as *mut u8, src as *u8, n as u32); -} - -/** - * Copies data from one location to another. - * - * Copies `count` elements (not bytes) from `src` to `dst`. The source - * and destination may overlap. - */ -#[inline] -#[cfg(target_word_size = "32", not(stage0))] +#[cfg(target_word_size = "32")] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove32; memmove32(dst, src as *T, count as u32); @@ -102,21 +88,7 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { * and destination may overlap. */ #[inline] -#[cfg(target_word_size = "64", stage0)] -pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { - use unstable::intrinsics::memmove64; - let n = count * sys::size_of::(); - memmove64(dst as *mut u8, src as *u8, n as u64); -} - -/** - * Copies data from one location to another. - * - * Copies `count` elements (not bytes) from `src` to `dst`. The source - * and destination may overlap. - */ -#[inline] -#[cfg(target_word_size = "64", not(stage0))] +#[cfg(target_word_size = "64")] pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove64; memmove64(dst, src as *T, count as u64); @@ -129,21 +101,7 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { * and destination may *not* overlap. */ #[inline] -#[cfg(target_word_size = "32", stage0)] -pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { - use unstable::intrinsics::memmove32; - let n = count * sys::size_of::(); - memmove32(dst as *mut u8, src as *u8, n as u32); -} - -/** - * Copies data from one location to another. - * - * Copies `count` elements (not bytes) from `src` to `dst`. The source - * and destination may *not* overlap. - */ -#[inline] -#[cfg(target_word_size = "32", not(stage0))] +#[cfg(target_word_size = "32")] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memcpy32; memcpy32(dst, src as *T, count as u32); @@ -156,21 +114,7 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u * and destination may *not* overlap. */ #[inline] -#[cfg(target_word_size = "64", stage0)] -pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { - use unstable::intrinsics::memmove64; - let n = count * sys::size_of::(); - memmove64(dst as *mut u8, src as *u8, n as u64); -} - -/** - * Copies data from one location to another. - * - * Copies `count` elements (not bytes) from `src` to `dst`. The source - * and destination may *not* overlap. - */ -#[inline] -#[cfg(target_word_size = "64", not(stage0))] +#[cfg(target_word_size = "64")] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memcpy64; memcpy64(dst, src as *T, count as u64); @@ -181,7 +125,7 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u * bytes of memory starting at `dst` to `c`. */ #[inline] -#[cfg(target_word_size = "32", not(stage0))] +#[cfg(target_word_size = "32")] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { use unstable::intrinsics::memset32; memset32(dst, c, count as u32); @@ -192,7 +136,7 @@ pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { * bytes of memory starting at `dst` to `c`. */ #[inline] -#[cfg(target_word_size = "64", not(stage0))] +#[cfg(target_word_size = "64")] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { use unstable::intrinsics::memset64; memset64(dst, c, count as u64); @@ -592,7 +536,6 @@ pub mod ptr_tests { } #[test] - #[cfg(not(stage0))] fn test_set_memory() { let mut xs = [0u8, ..20]; let ptr = vec::raw::to_mut_ptr(xs); diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 908c5e23ab07..134250077853 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -130,36 +130,23 @@ pub extern "rust-intrinsic" { /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` - #[cfg(not(stage0))] pub fn memcpy32(dst: *mut T, src: *T, count: u32); /// Equivalent to the `llvm.memcpy.p0i8.0i8.i64` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` - #[cfg(not(stage0))] pub fn memcpy64(dst: *mut T, src: *T, count: u64); - /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic. - #[cfg(stage0)] - pub fn memmove32(dst: *mut u8, src: *u8, size: u32); - /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic. - #[cfg(stage0)] - pub fn memmove64(dst: *mut u8, src: *u8, size: u64); - /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` - #[cfg(not(stage0))] pub fn memmove32(dst: *mut T, src: *T, count: u32); /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` - #[cfg(not(stage0))] pub fn memmove64(dst: *mut T, src: *T, count: u64); /// Equivalent to the `llvm.memset.p0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` - #[cfg(not(stage0))] pub fn memset32(dst: *mut T, val: u8, count: u32); /// Equivalent to the `llvm.memset.p0i8.i64` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` - #[cfg(not(stage0))] pub fn memset64(dst: *mut T, val: u8, count: u64); pub fn sqrtf32(x: f32) -> f32; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index fc6f07288f27..555342d3d60a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -402,94 +402,6 @@ impl ident_interner { // return a fresh interner, preloaded with special identifiers. -#[cfg(stage0)] -fn mk_fresh_ident_interner() -> @ident_interner { - // the indices here must correspond to the numbers in - // special_idents. - let init_vec = ~[ - "_", // 0 - "anon", // 1 - "", // 2 - "unary", // 3 - "!", // 4 - "[]", // 5 - "unary-", // 6 - "__extensions__", // 7 - "self", // 8 - "item", // 9 - "block", // 10 - "stmt", // 11 - "pat", // 12 - "expr", // 13 - "ty", // 14 - "ident", // 15 - "path", // 16 - "tt", // 17 - "matchers", // 18 - "str", // 19 - "TyVisitor", // 20 - "arg", // 21 - "descrim", // 22 - "__rust_abi", // 23 - "__rust_stack_shim", // 24 - "TyDesc", // 25 - "main", // 26 - "", // 27 - "blk", // 28 - "static", // 29 - "intrinsic", // 30 - "__foreign_mod__", // 31 - "__field__", // 32 - "C", // 33 - "Self", // 34 - - "as", // 35 - "break", // 36 - "const", // 37 - "copy", // 38 - "do", // 39 - "drop", // 40 - "else", // 41 - "enum", // 42 - "extern", // 43 - "false", // 44 - "fn", // 45 - "for", // 46 - "if", // 47 - "impl", // 48 - "let", // 49 - "__log", // 50 - "loop", // 51 - "match", // 52 - "mod", // 53 - "mut", // 54 - "once", // 55 - "priv", // 56 - "pub", // 57 - "pure", // 58 - "ref", // 59 - "return", // 60 - "static", // 29 -- also a special ident - "self", // 8 -- also a special ident - "struct", // 61 - "super", // 62 - "true", // 63 - "trait", // 64 - "type", // 65 - "unsafe", // 66 - "use", // 67 - "while", // 68 - - "be", // 69 - ]; - - @ident_interner { - interner: interner::StrInterner::prefill(init_vec) - } -} - -// return a fresh interner, preloaded with special identifiers. -#[cfg(not(stage0))] fn mk_fresh_ident_interner() -> @ident_interner { // the indices here must correspond to the numbers in // special_idents. @@ -700,48 +612,6 @@ pub mod keywords { } impl Keyword { - #[cfg(stage0)] - pub fn to_ident(&self) -> ident { - match *self { - As => ident { name: 35, ctxt: 0 }, - Break => ident { name: 36, ctxt: 0 }, - Const => ident { name: 37, ctxt: 0 }, - Copy => ident { name: 38, ctxt: 0 }, - Do => ident { name: 39, ctxt: 0 }, - Else => ident { name: 41, ctxt: 0 }, - Enum => ident { name: 42, ctxt: 0 }, - Extern => ident { name: 43, ctxt: 0 }, - False => ident { name: 44, ctxt: 0 }, - Fn => ident { name: 45, ctxt: 0 }, - For => ident { name: 46, ctxt: 0 }, - If => ident { name: 47, ctxt: 0 }, - Impl => ident { name: 48, ctxt: 0 }, - Let => ident { name: 49, ctxt: 0 }, - __Log => ident { name: 50, ctxt: 0 }, - Loop => ident { name: 51, ctxt: 0 }, - Match => ident { name: 52, ctxt: 0 }, - Mod => ident { name: 53, ctxt: 0 }, - Mut => ident { name: 54, ctxt: 0 }, - Once => ident { name: 55, ctxt: 0 }, - Priv => ident { name: 56, ctxt: 0 }, - Pub => ident { name: 57, ctxt: 0 }, - Pure => ident { name: 58, ctxt: 0 }, - Ref => ident { name: 59, ctxt: 0 }, - Return => ident { name: 60, ctxt: 0 }, - Static => ident { name: 29, ctxt: 0 }, - Self => ident { name: 8, ctxt: 0 }, - Struct => ident { name: 61, ctxt: 0 }, - Super => ident { name: 62, ctxt: 0 }, - True => ident { name: 63, ctxt: 0 }, - Trait => ident { name: 64, ctxt: 0 }, - Type => ident { name: 65, ctxt: 0 }, - Unsafe => ident { name: 66, ctxt: 0 }, - Use => ident { name: 67, ctxt: 0 }, - While => ident { name: 68, ctxt: 0 }, - Be => ident { name: 69, ctxt: 0 }, - } - } - #[cfg(not(stage0))] pub fn to_ident(&self) -> ident { match *self { As => ident { name: 35, ctxt: 0 }, @@ -792,18 +662,6 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool { } } -#[cfg(stage0)] -pub fn is_any_keyword(tok: &Token) -> bool { - match *tok { - token::IDENT(sid, false) => match sid.name { - 8 | 29 | 35 .. 69 => true, - _ => false, - }, - _ => false - } -} - -#[cfg(not(stage0))] pub fn is_any_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { @@ -814,18 +672,6 @@ pub fn is_any_keyword(tok: &Token) -> bool { } } -#[cfg(stage0)] -pub fn is_strict_keyword(tok: &Token) -> bool { - match *tok { - token::IDENT(sid, false) => match sid.name { - 8 | 29 | 35 .. 68 => true, - _ => false, - }, - _ => false, - } -} - -#[cfg(not(stage0))] pub fn is_strict_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { @@ -836,18 +682,6 @@ pub fn is_strict_keyword(tok: &Token) -> bool { } } -#[cfg(stage0)] -pub fn is_reserved_keyword(tok: &Token) -> bool { - match *tok { - token::IDENT(sid, false) => match sid.name { - 69 => true, - _ => false, - }, - _ => false, - } -} - -#[cfg(not(stage0))] pub fn is_reserved_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 78fbcab213c8..278600bc0394 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -30,17 +30,8 @@ extern mod core(name = "std"); extern mod extra(name = "extra"); // For deriving(Encodable) purposes... -#[cfg(stage0)] -extern mod std(name = "extra"); -#[cfg(not(stage0))] extern mod std(name = "std"); -// For bootstrapping purposes. -#[cfg(stage0)] -pub use core::str; -#[cfg(stage0)] -pub use core::unstable; - use core::prelude::*; pub mod util { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 3bd5e09e0073..e476fa0ad5e0 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -732,17 +732,10 @@ rust_task_deref(rust_task *task) { // Must call on rust stack. extern "C" CDECL void rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) { -#ifdef _RUST_STAGE0 - void (*glue_fn)(void *, void *, void *, void *) = - (void (*)(void *, void *, void *, void *))tydesc[glue_index]; - if (glue_fn) - glue_fn(0, 0, 0, root); -#else void (*glue_fn)(void *, void *, void *) = (void (*)(void *, void *, void *))tydesc[glue_index]; if (glue_fn) glue_fn(0, 0, root); -#endif } // Don't run on the Rust stack! @@ -762,11 +755,7 @@ public: virtual void run() { record_sp_limit(0); -#ifdef _RUST_STAGE0 - fn.f(NULL, fn.env, NULL); -#else fn.f(fn.env, NULL); -#endif } }; diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index f9b588b78501..fe1b4622137e 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -162,11 +162,7 @@ void task_start_wrapper(spawn_args *a) bool threw_exception = false; try { -#ifdef _RUST_STAGE0 - a->f(NULL, a->envptr, a->argptr); -#else a->f(a->envptr, a->argptr); -#endif } catch (rust_task *ex) { assert(ex == task && "Expected this task to be thrown for unwinding"); threw_exception = true; @@ -187,11 +183,7 @@ void task_start_wrapper(spawn_args *a) if(env) { // free the environment (which should be a unique closure). const type_desc *td = env->td; -#ifdef _RUST_STAGE0 - td->drop_glue(NULL, NULL, NULL, box_body(env)); -#else td->drop_glue(NULL, NULL, box_body(env)); -#endif task->kernel->region()->free(env); } diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h index b50c08379de7..6d36d2c960a2 100644 --- a/src/rt/rust_type.h +++ b/src/rt/rust_type.h @@ -21,19 +21,11 @@ struct rust_opaque_box; // - the main function: has a NULL environment, but uses the void* arg // - unique closures of type fn~(): have a non-NULL environment, but // no arguments (and hence the final void*) is harmless -#ifdef _RUST_STAGE0 -typedef void (*CDECL spawn_fn)(void *, rust_opaque_box*, void *); -#else typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *); -#endif struct type_desc; -#ifdef _RUST_STAGE0 -typedef void CDECL (glue_fn)(void *, void *, const type_desc **, void *); -#else typedef void CDECL (glue_fn)(void *, const type_desc **, void *); -#endif // Corresponds to the boxed data in the @ region. The body follows the // header; you can obtain a ptr via box_body() below. From 0702e53576886505d5ba7c40fb4beb0df3ed0d9d Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 17:41:54 +1200 Subject: [PATCH 82/96] libstd: cleanup warnings --- src/libstd/comm.rs | 1 - src/libstd/old_iter.rs | 2 +- src/libstd/os.rs | 10 ++++------ src/libstd/pipes.rs | 1 - src/libstd/task/spawn.rs | 1 - src/libstd/unstable/dynamic_lib.rs | 1 - src/libstd/unstable/global.rs | 2 +- src/libstd/unstable/lang.rs | 16 ++-------------- src/libstd/vec.rs | 2 +- 9 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 3f30c811e516..7918abe4ae6a 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -20,7 +20,6 @@ use either::{Either, Left, Right}; use kinds::Owned; use option::{Option, Some, None}; use uint; -use vec; use vec::OwnedVector; use util::replace; use unstable::sync::{Exclusive, exclusive}; diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index d0e1cfd15f48..83bb9eb09088 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -16,7 +16,7 @@ #[allow(missing_doc)]; -use cmp::{Eq, Ord}; +use cmp::{Eq}; use kinds::Copy; use option::{None, Option, Some}; use vec; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e48dc723c47a..59b40b93d4d1 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -959,12 +959,10 @@ pub fn copy_file(from: &Path, to: &Path) -> bool { fclose(ostream); // Give the new file the old file's permissions - unsafe { - if do str::as_c_str(to.to_str()) |to_buf| { - libc::chmod(to_buf, from_mode as mode_t) - } != 0 { - return false; // should be a condition... - } + if do str::as_c_str(to.to_str()) |to_buf| { + libc::chmod(to_buf, from_mode as mode_t) + } != 0 { + return false; // should be a condition... } return ok; } diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index 3448401e0b18..26dd4af45d6c 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -86,7 +86,6 @@ bounded and unbounded protocols allows for less code duplication. use container::Container; use cast::{forget, transmute, transmute_copy, transmute_mut}; -use cast; use either::{Either, Left, Right}; use iterator::IteratorUtil; use kinds::Owned; diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 16bb2fab7ba7..77053f396779 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -79,7 +79,6 @@ use cast; use cell::Cell; use container::Map; use comm::{Chan, GenericChan}; -use ptr; use hashmap::HashSet; use task::local_data_priv::{local_get, local_set, OldHandle}; use task::rt::rust_task; diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index f5f88f2bb880..64dd5bba6bcf 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -15,7 +15,6 @@ Dynamic library facilities. A simple wrapper over the platforms dynamic library facilities */ -use ptr; use cast; use path; use libc; diff --git a/src/libstd/unstable/global.rs b/src/libstd/unstable/global.rs index 96549a83a8cf..f81252274c49 100644 --- a/src/libstd/unstable/global.rs +++ b/src/libstd/unstable/global.rs @@ -105,7 +105,7 @@ unsafe fn global_data_modify_( let dtor: ~fn() = match maybe_dtor { Some(dtor) => dtor, None => { - let dtor: ~fn() = || unsafe { + let dtor: ~fn() = || { let _destroy_value: ~T = transmute(data); }; dtor diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index 505cfa2fcd90..d37579b0c47c 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -387,9 +387,6 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { pub fn start(main: *u8, argc: int, argv: **c_char, crate_map: *u8) -> int { use rt; - use sys::Closure; - use ptr; - use cast; use os; unsafe { @@ -399,17 +396,8 @@ pub fn start(main: *u8, argc: int, argv: **c_char, crate_map as *c_void) as int; } else { return do rt::start(argc, argv as **u8, crate_map) { - unsafe { - // `main` is an `fn() -> ()` that doesn't take an environment - // XXX: Could also call this as an `extern "Rust" fn` once they work - let main = Closure { - code: main as *(), - env: ptr::null(), - }; - let mainfn: &fn() = cast::transmute(main); - - mainfn(); - } + let main: extern "Rust" fn() = transmute(main); + main(); }; } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 0af69815cf23..7f683d0070fb 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -19,7 +19,7 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use old_iter::BaseIter; use old_iter; -use iterator::{Iterator, IteratorUtil}; +use iterator::{Iterator}; use iter::FromIter; use kinds::Copy; use libc; From b6ecf60d894cb54a7f59e768ec7859186dc9479b Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 17:44:12 +1200 Subject: [PATCH 83/96] libsyntax: cleanup warnings --- src/libsyntax/parse/token.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 555342d3d60a..273a59f0a3de 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -498,9 +498,7 @@ pub fn get_ident_interner() -> @ident_interner { Some(interner) => *interner, None => { let interner = mk_fresh_ident_interner(); - unsafe { - local_data::local_data_set(key, @interner); - } + local_data::local_data_set(key, @interner); interner } } From 4e3b196670364df6370ea9010b58c19e578fee1a Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 17:44:34 +1200 Subject: [PATCH 84/96] libextra: cleanup warnings --- src/libextra/arc.rs | 16 +-- src/libextra/flatpipes.rs | 1 - src/libextra/net_tcp.rs | 264 ++++++++++++++++++-------------------- 3 files changed, 134 insertions(+), 147 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 6dc37ef58d3a..661224b0a803 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -200,15 +200,13 @@ impl MutexARC { */ #[inline] pub unsafe fn access(&self, blk: &fn(x: &mut T) -> U) -> U { - unsafe { - let state = self.x.get(); - // Borrowck would complain about this if the function were - // not already unsafe. See borrow_rwlock, far below. - do (&(*state).lock).lock { - check_poison(true, (*state).failed); - let _z = PoisonOnFail(&mut (*state).failed); - blk(&mut (*state).data) - } + let state = self.x.get(); + // Borrowck would complain about this if the function were + // not already unsafe. See borrow_rwlock, far below. + do (&(*state).lock).lock { + check_poison(true, (*state).failed); + let _z = PoisonOnFail(&mut (*state).failed); + blk(&mut (*state).data) } } diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index 4ff67fc3f42c..9a8ee3959364 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -516,7 +516,6 @@ pub mod bytepipes { use core::comm::{Port, Chan}; use core::comm; use core::io::{Writer, Reader, ReaderUtil}; - use core::vec; pub struct ReaderBytePort { reader: R diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index 28b3700399a6..51d744955b81 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -181,90 +181,88 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, debug!("stream_handle_ptr outside interact %?", stream_handle_ptr); do iotask::interact(iotask) |loop_ptr| { - unsafe { - debug!("in interact cb for tcp client connect.."); - debug!("stream_handle_ptr in interact %?", - stream_handle_ptr); - match uv::ll::tcp_init( loop_ptr, stream_handle_ptr) { - 0i32 => { - debug!("tcp_init successful"); - debug!("dealing w/ ipv4 connection.."); - let connect_req_ptr: *uv::ll::uv_connect_t = - &(*socket_data_ptr).connect_req; - let addr_str = ip::format_addr(&input_ip); - let connect_result = match input_ip { - ip::Ipv4(ref addr) => { - // have to "recreate" the - // sockaddr_in/6 since the ip_addr - // discards the port info.. should - // probably add an additional rust - // type that actually is closer to - // what the libuv API expects (ip str - // + port num) - debug!("addr: %?", addr); - let in_addr = uv::ll::ip4_addr(addr_str, - port as int); - uv::ll::tcp_connect( - connect_req_ptr, - stream_handle_ptr, - &in_addr, - tcp_connect_on_connect_cb) - } - ip::Ipv6(ref addr) => { - debug!("addr: %?", addr); - let in_addr = uv::ll::ip6_addr(addr_str, - port as int); - uv::ll::tcp_connect6( - connect_req_ptr, - stream_handle_ptr, - &in_addr, - tcp_connect_on_connect_cb) - } - }; - match connect_result { - 0i32 => { - debug!("tcp_connect successful: \ - stream %x, - socket data %x", - stream_handle_ptr as uint, - socket_data_ptr as uint); - // reusable data that we'll have for the - // duration.. - uv::ll::set_data_for_uv_handle( - stream_handle_ptr, - socket_data_ptr as - *libc::c_void); - // just so the connect_cb can send the - // outcome.. - uv::ll::set_data_for_req(connect_req_ptr, - conn_data_ptr); - debug!("leaving tcp_connect interact cb..."); - // let tcp_connect_on_connect_cb send on - // the result_ch, now.. - } - _ => { - // immediate connect - // failure.. probably a garbage ip or - // somesuch - let err_data = - uv::ll::get_last_err_data(loop_ptr); - let result_ch = (*conn_data_ptr) - .result_ch.clone(); - result_ch.send(ConnFailure(err_data)); - uv::ll::set_data_for_uv_handle( - stream_handle_ptr, - conn_data_ptr); - uv::ll::close(stream_handle_ptr, - stream_error_close_cb); - } + debug!("in interact cb for tcp client connect.."); + debug!("stream_handle_ptr in interact %?", + stream_handle_ptr); + match uv::ll::tcp_init( loop_ptr, stream_handle_ptr) { + 0i32 => { + debug!("tcp_init successful"); + debug!("dealing w/ ipv4 connection.."); + let connect_req_ptr: *uv::ll::uv_connect_t = + &(*socket_data_ptr).connect_req; + let addr_str = ip::format_addr(&input_ip); + let connect_result = match input_ip { + ip::Ipv4(ref addr) => { + // have to "recreate" the + // sockaddr_in/6 since the ip_addr + // discards the port info.. should + // probably add an additional rust + // type that actually is closer to + // what the libuv API expects (ip str + // + port num) + debug!("addr: %?", addr); + let in_addr = uv::ll::ip4_addr(addr_str, + port as int); + uv::ll::tcp_connect( + connect_req_ptr, + stream_handle_ptr, + &in_addr, + tcp_connect_on_connect_cb) + } + ip::Ipv6(ref addr) => { + debug!("addr: %?", addr); + let in_addr = uv::ll::ip6_addr(addr_str, + port as int); + uv::ll::tcp_connect6( + connect_req_ptr, + stream_handle_ptr, + &in_addr, + tcp_connect_on_connect_cb) + } + }; + match connect_result { + 0i32 => { + debug!("tcp_connect successful: \ + stream %x, + socket data %x", + stream_handle_ptr as uint, + socket_data_ptr as uint); + // reusable data that we'll have for the + // duration.. + uv::ll::set_data_for_uv_handle( + stream_handle_ptr, + socket_data_ptr as + *libc::c_void); + // just so the connect_cb can send the + // outcome.. + uv::ll::set_data_for_req(connect_req_ptr, + conn_data_ptr); + debug!("leaving tcp_connect interact cb..."); + // let tcp_connect_on_connect_cb send on + // the result_ch, now.. + } + _ => { + // immediate connect + // failure.. probably a garbage ip or + // somesuch + let err_data = + uv::ll::get_last_err_data(loop_ptr); + let result_ch = (*conn_data_ptr) + .result_ch.clone(); + result_ch.send(ConnFailure(err_data)); + uv::ll::set_data_for_uv_handle( + stream_handle_ptr, + conn_data_ptr); + uv::ll::close(stream_handle_ptr, + stream_error_close_cb); } } - _ => { - // failure to create a tcp handle - let err_data = uv::ll::get_last_err_data(loop_ptr); - let result_ch = (*conn_data_ptr).result_ch.clone(); - result_ch.send(ConnFailure(err_data)); - } + } + _ => { + // failure to create a tcp handle + let err_data = uv::ll::get_last_err_data(loop_ptr); + let result_ch = (*conn_data_ptr).result_ch.clone(); + result_ch.send(ConnFailure(err_data)); } } } @@ -1015,14 +1013,12 @@ fn tear_down_socket_data(socket_data: @TcpSocketData) { let close_data_ptr: *TcpSocketCloseData = &close_data; let stream_handle_ptr = (*socket_data).stream_handle_ptr; do iotask::interact(&(*socket_data).iotask) |loop_ptr| { - unsafe { - debug!( - "interact dtor for tcp_socket stream %? loop %?", - stream_handle_ptr, loop_ptr); - uv::ll::set_data_for_uv_handle(stream_handle_ptr, - close_data_ptr); - uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb); - } + debug!( + "interact dtor for tcp_socket stream %? loop %?", + stream_handle_ptr, loop_ptr); + uv::ll::set_data_for_uv_handle(stream_handle_ptr, + close_data_ptr); + uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb); }; closed_po.recv(); //the line below will most likely crash @@ -1082,19 +1078,17 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) -> let stream_handle_ptr = (*socket_data).stream_handle_ptr; let (stop_po, stop_ch) = stream::>(); do iotask::interact(&(*socket_data).iotask) |loop_ptr| { - unsafe { - debug!("in interact cb for tcp::read_stop"); - match uv::ll::read_stop(stream_handle_ptr - as *uv::ll::uv_stream_t) { - 0i32 => { - debug!("successfully called uv_read_stop"); - stop_ch.send(None); - } - _ => { - debug!("failure in calling uv_read_stop"); - let err_data = uv::ll::get_last_err_data(loop_ptr); - stop_ch.send(Some(err_data.to_tcp_err())); - } + debug!("in interact cb for tcp::read_stop"); + match uv::ll::read_stop(stream_handle_ptr + as *uv::ll::uv_stream_t) { + 0i32 => { + debug!("successfully called uv_read_stop"); + stop_ch.send(None); + } + _ => { + debug!("failure in calling uv_read_stop"); + let err_data = uv::ll::get_last_err_data(loop_ptr); + stop_ch.send(Some(err_data.to_tcp_err())); } } } @@ -1114,22 +1108,20 @@ fn read_start_common_impl(socket_data: *TcpSocketData) let (start_po, start_ch) = stream::>(); debug!("in tcp::read_start before interact loop"); do iotask::interact(&(*socket_data).iotask) |loop_ptr| { - unsafe { - debug!("in tcp::read_start interact cb %?", - loop_ptr); - match uv::ll::read_start(stream_handle_ptr - as *uv::ll::uv_stream_t, - on_alloc_cb, - on_tcp_read_cb) { - 0i32 => { - debug!("success doing uv_read_start"); - start_ch.send(None); - } - _ => { - debug!("error attempting uv_read_start"); - let err_data = uv::ll::get_last_err_data(loop_ptr); - start_ch.send(Some(err_data)); - } + debug!("in tcp::read_start interact cb %?", + loop_ptr); + match uv::ll::read_start(stream_handle_ptr + as *uv::ll::uv_stream_t, + on_alloc_cb, + on_tcp_read_cb) { + 0i32 => { + debug!("success doing uv_read_start"); + start_ch.send(None); + } + _ => { + debug!("error attempting uv_read_start"); + let err_data = uv::ll::get_last_err_data(loop_ptr); + start_ch.send(Some(err_data)); } } } @@ -1166,24 +1158,22 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData, }; let write_data_ptr: *WriteReqData = &write_data; do iotask::interact(&(*socket_data_ptr).iotask) |loop_ptr| { - unsafe { - debug!("in interact cb for tcp::write %?", - loop_ptr); - match uv::ll::write(write_req_ptr, - stream_handle_ptr, - write_buf_vec_ptr, - tcp_write_complete_cb) { - 0i32 => { - debug!("uv_write() invoked successfully"); - uv::ll::set_data_for_req(write_req_ptr, - write_data_ptr); - } - _ => { - debug!("error invoking uv_write()"); - let err_data = uv::ll::get_last_err_data(loop_ptr); - let result_ch = (*write_data_ptr).result_ch.clone(); - result_ch.send(TcpWriteError(err_data.to_tcp_err())); - } + debug!("in interact cb for tcp::write %?", + loop_ptr); + match uv::ll::write(write_req_ptr, + stream_handle_ptr, + write_buf_vec_ptr, + tcp_write_complete_cb) { + 0i32 => { + debug!("uv_write() invoked successfully"); + uv::ll::set_data_for_req(write_req_ptr, + write_data_ptr); + } + _ => { + debug!("error invoking uv_write()"); + let err_data = uv::ll::get_last_err_data(loop_ptr); + let result_ch = (*write_data_ptr).result_ch.clone(); + result_ch.send(TcpWriteError(err_data.to_tcp_err())); } } } From 229a88217f3d8d6e866728143349acd92b5dc60a Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 20 Jun 2013 17:52:02 +1200 Subject: [PATCH 85/96] librust: cleanup warnings (except 1) --- src/librustc/lib/llvm.rs | 4 +- src/librustc/metadata/loader.rs | 44 +++++++++++----------- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/build.rs | 12 ++---- src/librustc/middle/trans/context.rs | 4 +- src/librustc/middle/trans/debuginfo.rs | 4 +- src/librustc/middle/typeck/check/vtable.rs | 2 - 7 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 2b2c1e27cbc3..5d5a5e736bce 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2192,9 +2192,7 @@ pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef) let out_ty: TypeRef = llvm::LLVMGetReturnType(ty); let n_args = llvm::LLVMCountParamTypes(ty) as uint; let args = vec::from_elem(n_args, 0 as TypeRef); - unsafe { - llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); - } + llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); // See [Note at-str] return fmt!("fn(%s) -> %s", tys_str(names, outer, args), diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 5d9355053de9..585704381b69 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -204,35 +204,33 @@ fn get_metadata_section(os: os, let si = mk_section_iter(of.llof); while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { let name_buf = llvm::LLVMGetSectionName(si.llsi); - let name = unsafe { str::raw::from_c_str(name_buf) }; + let name = str::raw::from_c_str(name_buf); debug!("get_metadata_section: name %s", name); if name == read_meta_section_name(os) { let cbuf = llvm::LLVMGetSectionContents(si.llsi); let csz = llvm::LLVMGetSectionSize(si.llsi) as uint; let mut found = None; - unsafe { - let cvbuf: *u8 = cast::transmute(cbuf); - let vlen = encoder::metadata_encoding_version.len(); - debug!("checking %u bytes of metadata-version stamp", - vlen); - let minsz = uint::min(vlen, csz); - let mut version_ok = false; - do vec::raw::buf_as_slice(cvbuf, minsz) |buf0| { - version_ok = (buf0 == - encoder::metadata_encoding_version); - } - if !version_ok { return None; } + let cvbuf: *u8 = cast::transmute(cbuf); + let vlen = encoder::metadata_encoding_version.len(); + debug!("checking %u bytes of metadata-version stamp", + vlen); + let minsz = uint::min(vlen, csz); + let mut version_ok = false; + do vec::raw::buf_as_slice(cvbuf, minsz) |buf0| { + version_ok = (buf0 == + encoder::metadata_encoding_version); + } + if !version_ok { return None; } - let cvbuf1 = ptr::offset(cvbuf, vlen); - debug!("inflating %u bytes of compressed metadata", - csz - vlen); - do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| { - let inflated = flate::inflate_bytes(bytes); - found = Some(@(inflated)); - } - if found != None { - return found; - } + let cvbuf1 = ptr::offset(cvbuf, vlen); + debug!("inflating %u bytes of compressed metadata", + csz - vlen); + do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| { + let inflated = flate::inflate_bytes(bytes); + found = Some(@(inflated)); + } + if found != None { + return found; } } llvm::LLVMMoveToNextSection(si.llsi); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a050467529ac..d7d21707f40f 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3050,7 +3050,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { // Writes the current ABI version into the crate. pub fn write_abi_version(ccx: &mut CrateContext) { - mk_global(ccx, ~"rust_abi_version", C_uint(ccx, abi::abi_version), + mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), false); } diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 604cd3d2ba66..a55e89747f5b 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -618,13 +618,11 @@ pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } - unsafe { - count_insn(cx, "inboundsgep"); + count_insn(cx, "inboundsgep"); return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname()); - } } } @@ -1072,11 +1070,9 @@ pub fn Trap(cx: block) { }); assert!((T as int != 0)); let Args: ~[ValueRef] = ~[]; - unsafe { - count_insn(cx, "trap"); - llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), - Args.len() as c_uint, noname()); - } + count_insn(cx, "trap"); + llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), + Args.len() as c_uint, noname()); } } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 7aab1d0239e6..d6c7472424f7 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -211,9 +211,7 @@ impl CrateContext { int_type: int_type, float_type: float_type, opaque_vec_type: T_opaque_vec(targ_cfg), - builder: BuilderRef_res(unsafe { - llvm::LLVMCreateBuilderInContext(llcx) - }), + builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), shape_cx: mk_ctxt(llmod), crate_map: crate_map, uses_gc: false, diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 91e3276d8aa6..269451b13070 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -242,7 +242,7 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { ast::ty_f32 => (~"f32", DW_ATE_float), ast::ty_f64 => (~"f64", DW_ATE_float) }, - _ => cx.sess.bug(~"debuginfo::create_basic_type - t is invalid type") + _ => cx.sess.bug("debuginfo::create_basic_type - t is invalid type") }; let (size, align) = size_and_align_of(cx, t); @@ -572,7 +572,7 @@ fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { ty::ty_tup(ref elements) => { create_tuple(cx, t, *elements, span) }, - _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") + _ => cx.sess.bug("debuginfo: unexpected type in create_ty") }; dbg_cx(cx).created_types.insert(ty_id, ty_md); diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 207f986efd92..197bf5d82cce 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -10,7 +10,6 @@ use core::prelude::*; -use middle::resolve::Impl; use middle::ty::param_ty; use middle::ty; use middle::typeck::check::{FnCtxt, impl_self_ty}; @@ -27,7 +26,6 @@ use util::ppaux; use core::hashmap::HashSet; use core::result; -use core::uint; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; From adeb7e77ccff938c0afb105a14a2ff4df4c7efc8 Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 21 Jun 2013 02:42:55 +1200 Subject: [PATCH 86/96] Update snapshots.txt --- src/snapshots.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/snapshots.txt b/src/snapshots.txt index a68d2205cfba..1aaf5fee26ab 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2013-06-21 6759ce4 + macos-i386 6e5395d2fda1db356f64af28ba525031bf9871c7 + macos-x86_64 7b8ded4e1ba1e999a5614eea3a4acacb2c7cef1d + winnt-i386 8337460667b1ea67d5a7aeeb7ba34c0b87e44b83 + freebsd-x86_64 21e5219ac858795c757a3ac894a6c3e88b43f74d + linux-i386 f02609c28f05d9feb9ba4b5f34940a77f22d76f2 + linux-x86_64 951c9fe9082393c5761bac3163ea59c253f1bece + S 2013-05-17 2d28d64 macos-i386 abadafb33c9f858543351c822fb468195163559f macos-x86_64 4a484693f73bcc8ce2a85708fd4f0c3f6e34969d From 4d39253a9623ff30c27cee3c9770634a41f4412d Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 20 Jun 2013 12:16:04 -0700 Subject: [PATCH 87/96] std::rt: Whitespace --- src/libstd/rt/sched.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 453d3303db66..bbe4aa25e296 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -646,12 +646,12 @@ impl Scheduler { } } -// The cases for the below function. +// The cases for the below function. enum ResumeAction { SendHome, Requeue, ResumeNow, - Homeless + Homeless } impl SchedHandle { From 7a9a6e45911636eae3ec4e1c111bc0e120601a5a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 20 Jun 2013 18:26:56 -0700 Subject: [PATCH 88/96] std: Port SharedChan to newsched --- src/libstd/comm.rs | 40 +++++++++++++++++++++++++--------------- src/libstd/rt/task.rs | 12 ++++++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 7918abe4ae6a..00c33c8ab325 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -220,7 +220,7 @@ impl Peekable for PortSet { /// A channel that can be shared between many senders. pub struct SharedChan { - ch: Exclusive> + inner: Either>, rtcomm::SharedChan> } impl SharedChan { @@ -228,40 +228,50 @@ impl SharedChan { pub fn new(c: Chan) -> SharedChan { let Chan { inner } = c; let c = match inner { - Left(c) => c, - Right(_) => fail!("SharedChan not implemented") + Left(c) => Left(exclusive(c)), + Right(c) => Right(rtcomm::SharedChan::new(c)) }; - SharedChan { ch: exclusive(c) } + SharedChan { inner: c } } } impl GenericChan for SharedChan { fn send(&self, x: T) { - unsafe { - let mut xx = Some(x); - do self.ch.with_imm |chan| { - let x = replace(&mut xx, None); - chan.send(x.unwrap()) + match self.inner { + Left(ref chan) => { + unsafe { + let mut xx = Some(x); + do chan.with_imm |chan| { + let x = replace(&mut xx, None); + chan.send(x.unwrap()) + } + } } + Right(ref chan) => chan.send(x) } } } impl GenericSmartChan for SharedChan { fn try_send(&self, x: T) -> bool { - unsafe { - let mut xx = Some(x); - do self.ch.with_imm |chan| { - let x = replace(&mut xx, None); - chan.try_send(x.unwrap()) + match self.inner { + Left(ref chan) => { + unsafe { + let mut xx = Some(x); + do chan.with_imm |chan| { + let x = replace(&mut xx, None); + chan.try_send(x.unwrap()) + } + } } + Right(ref chan) => chan.try_send(x) } } } impl ::clone::Clone for SharedChan { fn clone(&self) -> SharedChan { - SharedChan { ch: self.ch.clone() } + SharedChan { inner: self.inner.clone() } } } diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index e7f87906fe59..833f25b253c0 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -248,6 +248,18 @@ mod test { } } + #[test] + fn comm_shared_chan() { + use comm::*; + + do run_in_newsched_task() { + let (port, chan) = stream(); + let chan = SharedChan::new(chan); + chan.send(10); + assert!(port.recv() == 10); + } + } + #[test] fn linked_failure() { do run_in_newsched_task() { From 1b7c99655f300aa0b8ba216cd2029dc588c3ef88 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Jun 2013 01:28:23 -0700 Subject: [PATCH 89/96] std::rt: Support os::args --- src/libstd/os.rs | 17 ++++-- src/libstd/rt/args.rs | 125 ++++++++++++++++++++++++++++++++++++++++ src/libstd/rt/mod.rs | 26 ++++++--- src/rt/rust_builtin.cpp | 18 ++++++ src/rt/rustrt.def.in | 1 + 5 files changed, 176 insertions(+), 11 deletions(-) create mode 100644 src/libstd/rt/args.rs diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 59b40b93d4d1..765dd30febcf 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -40,6 +40,8 @@ use option::{Some, None}; use os; use prelude::*; use ptr; +use rt; +use rt::TaskContext; use str; use uint; use unstable::finally::Finally; @@ -1167,10 +1169,17 @@ pub fn real_args() -> ~[~str] { #[cfg(target_os = "android")] #[cfg(target_os = "freebsd")] pub fn real_args() -> ~[~str] { - unsafe { - let argc = rustrt::rust_get_argc(); - let argv = rustrt::rust_get_argv(); - load_argc_and_argv(argc, argv) + if rt::context() == TaskContext { + match rt::args::clone() { + Some(args) => args, + None => fail!("process arguments not initialized") + } + } else { + unsafe { + let argc = rustrt::rust_get_argc(); + let argv = rustrt::rust_get_argv(); + load_argc_and_argv(argc, argv) + } } } diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs new file mode 100644 index 000000000000..75ee4f381f6e --- /dev/null +++ b/src/libstd/rt/args.rs @@ -0,0 +1,125 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Global storage for command line arguments +//! +//! The current incarnation of the Rust runtime expects for +//! the processes `argc` and `argv` arguments to be stored +//! in a globally-accessible location for use by the `os` module. +//! +//! XXX: Would be nice for this to not exist. +//! XXX: This has a lot of C glue for lack of globals. + +use libc; +use option::{Option, Some, None}; +use str; +use uint; +use unstable::finally::Finally; +use util; + +/// One-time global initialization. +pub unsafe fn init(argc: int, argv: **u8) { + let args = load_argc_and_argv(argc, argv); + put(args); +} + +/// One-time global cleanup. +pub fn cleanup() { + rtassert!(take().is_some()); +} + +/// Take the global arguments from global storage. +pub fn take() -> Option<~[~str]> { + with_lock(|| unsafe { + let ptr = get_global_ptr(); + let val = util::replace(&mut *ptr, None); + val.map(|s: &~~[~str]| (**s).clone()) + }) +} + +/// Give the global arguments to global storage. +/// +/// It is an error if the arguments already exist. +pub fn put(args: ~[~str]) { + with_lock(|| unsafe { + let ptr = get_global_ptr(); + rtassert!((*ptr).is_none()); + (*ptr) = Some(~args.clone()); + }) +} + +/// Make a clone of the global arguments. +pub fn clone() -> Option<~[~str]> { + with_lock(|| unsafe { + let ptr = get_global_ptr(); + (*ptr).map(|s: &~~[~str]| (**s).clone()) + }) +} + +fn with_lock(f: &fn() -> T) -> T { + do (|| { + unsafe { + rust_take_global_args_lock(); + f() + } + }).finally { + unsafe { + rust_drop_global_args_lock(); + } + } +} + +fn get_global_ptr() -> *mut Option<~~[~str]> { + unsafe { rust_get_global_args_ptr() } +} + +// Copied from `os`. +unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] { + let mut args = ~[]; + for uint::range(0, argc as uint) |i| { + args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i))); + } + return args; +} + +extern { + fn rust_take_global_args_lock(); + fn rust_drop_global_args_lock(); + fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>; +} + +#[cfg(test)] +mod tests { + use option::{Some, None}; + use super::*; + use unstable::finally::Finally; + + #[test] + fn smoke_test() { + // Preserve the actual global state. + let saved_value = take(); + + let expected = ~[~"happy", ~"today?"]; + + put(expected.clone()); + assert!(clone() == Some(expected.clone())); + assert!(take() == Some(expected.clone())); + assert!(take() == None); + + do (|| { + }).finally { + // Restore the actual global state. + match saved_value { + Some(ref args) => put(args.clone()), + None => () + } + } + } +} diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index a80fb15bad79..7e1d18f95486 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -159,6 +159,9 @@ pub mod metrics; /// Just stuff pub mod util; +// Global command line argument storage +pub mod args; + /// Set up a default runtime configuration, given compiler-supplied arguments. /// /// This is invoked by the `start` _language item_ (unstable::lang) to @@ -173,20 +176,28 @@ pub mod util; /// # Return value /// /// The return value is used as the process return code. 0 on success, 101 on error. -pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int { +pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int { - init(crate_map); + init(argc, argv, crate_map); let exit_code = run(main); cleanup(); return exit_code; } -/// One-time runtime initialization. Currently all this does is set up logging -/// based on the RUST_LOG environment variable. -pub fn init(crate_map: *u8) { - logging::init(crate_map); - unsafe { rust_update_gc_metadata(crate_map) } +/// One-time runtime initialization. +/// +/// Initializes global state, including frobbing +/// the crate's logging flags, registering GC +/// metadata, and storing the process arguments. +pub fn init(argc: int, argv: **u8, crate_map: *u8) { + // XXX: Derefing these pointers is not safe. + // Need to propagate the unsafety to `start`. + unsafe { + args::init(argc, argv); + logging::init(crate_map); + rust_update_gc_metadata(crate_map); + } extern { fn rust_update_gc_metadata(crate_map: *u8); @@ -195,6 +206,7 @@ pub fn init(crate_map: *u8) { /// One-time runtime cleanup. pub fn cleanup() { + args::cleanup(); global_heap::cleanup(); } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 8e494cb577b5..86b8881b9f2e 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -932,6 +932,24 @@ rust_get_num_cpus() { return get_num_cpus(); } +static lock_and_signal global_args_lock; +static uintptr_t global_args_ptr = 0; + +extern "C" CDECL void +rust_take_global_args_lock() { + global_args_lock.lock(); +} + +extern "C" CDECL void +rust_drop_global_args_lock() { + global_args_lock.unlock(); +} + +extern "C" CDECL uintptr_t* +rust_get_global_args_ptr() { + return &global_args_ptr; +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 425f17d42900..ca813c5d3ae5 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -242,3 +242,4 @@ rust_drop_env_lock rust_update_log_settings rust_running_on_valgrind rust_get_num_cpus +rust_get_global_args_ptr \ No newline at end of file From 95eb01957bf23922abdf083f677c6c2d6927713a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Jun 2013 16:52:07 -0700 Subject: [PATCH 90/96] std: Make console log off/on controls work with newsched --- src/libstd/logging.rs | 24 ++++++++++++++++++++---- src/libstd/rt/logging.rs | 22 +++++++++++++++++----- src/rt/rust_builtin.cpp | 12 +++++++++--- src/rt/rust_log.cpp | 12 ++++++++---- src/rt/rustrt.def.in | 1 + 5 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs index c2f854179b8d..743b71e33ea8 100644 --- a/src/libstd/logging.rs +++ b/src/libstd/logging.rs @@ -11,13 +11,20 @@ //! Logging use option::*; +use os; use either::*; +use rt; +use rt::OldTaskContext; use rt::logging::{Logger, StdErrLogger}; /// Turns on logging to stdout globally pub fn console_on() { - unsafe { - rustrt::rust_log_console_on(); + if rt::context() == OldTaskContext { + unsafe { + rustrt::rust_log_console_on(); + } + } else { + rt::logging::console_on(); } } @@ -29,8 +36,17 @@ pub fn console_on() { * the RUST_LOG environment variable */ pub fn console_off() { - unsafe { - rustrt::rust_log_console_off(); + // If RUST_LOG is set then the console can't be turned off + if os::getenv("RUST_LOG").is_some() { + return; + } + + if rt::context() == OldTaskContext { + unsafe { + rustrt::rust_log_console_off(); + } + } else { + rt::logging::console_off(); } } diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs index a0d053976891..84186180aa65 100644 --- a/src/libstd/rt/logging.rs +++ b/src/libstd/rt/logging.rs @@ -9,6 +9,7 @@ // except according to those terms. use either::*; +use libc; pub trait Logger { fn log(&mut self, msg: Either<~str, &'static str>); @@ -20,6 +21,10 @@ impl Logger for StdErrLogger { fn log(&mut self, msg: Either<~str, &'static str>) { use io::{Writer, WriterUtil}; + if !should_log_console() { + return; + } + let s: &str = match msg { Left(ref s) => { let s: &str = *s; @@ -44,7 +49,6 @@ pub fn init(crate_map: *u8) { use str; use ptr; use option::{Some, None}; - use libc::c_char; let log_spec = os::getenv("RUST_LOG"); match log_spec { @@ -61,8 +65,16 @@ pub fn init(crate_map: *u8) { } } } - - extern { - fn rust_update_log_settings(crate_map: *u8, settings: *c_char); - } } + +pub fn console_on() { unsafe { rust_log_console_on() } } +pub fn console_off() { unsafe { rust_log_console_off() } } +fn should_log_console() -> bool { unsafe { rust_should_log_console() != 0 } } + +extern { + fn rust_update_log_settings(crate_map: *u8, settings: *libc::c_char); + fn rust_log_console_on(); + fn rust_log_console_off(); + fn rust_should_log_console() -> libc::uintptr_t; +} + diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 86b8881b9f2e..f0b68d4a1569 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -591,12 +591,18 @@ rust_log_console_on() { log_console_on(); } -extern void log_console_off(rust_env *env); +extern void log_console_off(); extern "C" CDECL void rust_log_console_off() { - rust_task *task = rust_get_current_task(); - log_console_off(task->kernel->env); + log_console_off(); +} + +extern bool should_log_console(); + +extern "C" CDECL uintptr_t +rust_should_log_console() { + return (uintptr_t)should_log_console(); } extern "C" CDECL void diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp index df24f569495b..8179c53e96d5 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -43,11 +43,15 @@ log_console_on() { * overridden by the environment. */ void -log_console_off(rust_env *env) { +log_console_off() { scoped_lock with(_log_lock); - if (env->logspec == NULL) { - _log_to_console = false; - } + _log_to_console = false; +} + +bool +should_log_console() { + scoped_lock with(_log_lock); + return _log_to_console; } rust_log::rust_log(rust_sched_loop *sched_loop) : diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index ca813c5d3ae5..950662b91f8e 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -37,6 +37,7 @@ rust_list_dir_wfd_size rust_list_dir_wfd_fp_buf rust_log_console_on rust_log_console_off +rust_should_log_console rust_set_environ rust_unset_sigprocmask rust_sched_current_nonlazy_threads From aa9210d25afb3779e1d95722b73b62a7be6274fe Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Jun 2013 19:40:00 -0700 Subject: [PATCH 91/96] std: Rewrite vec_reserve_shared_actual in Rust --- src/libstd/at_vec.rs | 62 +++++++++++++++++++++++---------- src/libstd/rt/local_heap.rs | 9 +++++ src/libstd/vec.rs | 10 ++---- src/rt/rust_builtin.cpp | 12 ++++--- src/rt/rust_util.h | 10 ------ src/rt/rustrt.def.in | 3 +- src/test/run-pass/extern-pub.rs | 6 +--- 7 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 3875847ff9bb..18dfbd82c5ae 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -23,20 +23,6 @@ use vec; /// Code for dealing with @-vectors. This is pretty incomplete, and /// contains a bunch of duplication from the code for ~-vectors. -pub mod rustrt { - use libc; - use sys; - use vec; - - #[abi = "cdecl"] - #[link_name = "rustrt"] - pub extern { - pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, - v: **vec::raw::VecRepr, - n: libc::size_t); - } -} - /// Returns the number of elements the vector can hold without reallocating #[inline] pub fn capacity(v: @[T]) -> uint { @@ -189,7 +175,7 @@ pub mod traits { pub mod traits {} pub mod raw { - use at_vec::{capacity, rustrt}; + use at_vec::capacity; use cast::{transmute, transmute_copy}; use libc; use ptr; @@ -197,6 +183,8 @@ pub mod raw { use uint; use unstable::intrinsics::{move_val_init}; use vec; + use vec::UnboxedVecRepr; + use sys::TypeDesc; pub type VecRepr = vec::raw::VecRepr; pub type SliceRepr = vec::raw::SliceRepr; @@ -257,9 +245,47 @@ pub mod raw { pub unsafe fn reserve(v: &mut @[T], n: uint) { // Only make the (slow) call into the runtime if we have to if capacity(*v) < n { - let ptr: **VecRepr = transmute(v); - rustrt::vec_reserve_shared_actual(sys::get_type_desc::(), - ptr, n as libc::size_t); + let ptr: *mut *mut VecRepr = transmute(v); + let ty = sys::get_type_desc::(); + return reserve_raw(ty, ptr, n); + } + } + + // Implementation detail. Shouldn't be public + #[allow(missing_doc)] + pub fn reserve_raw(ty: *TypeDesc, ptr: *mut *mut VecRepr, n: uint) { + + unsafe { + let size_in_bytes = n * (*ty).size; + if size_in_bytes > (**ptr).unboxed.alloc { + let total_size = size_in_bytes + sys::size_of::(); + // XXX: UnboxedVecRepr has an extra u8 at the end + let total_size = total_size - sys::size_of::(); + (*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr; + (**ptr).unboxed.alloc = size_in_bytes; + } + } + + fn local_realloc(ptr: *(), size: uint) -> *() { + use rt; + use rt::OldTaskContext; + use rt::local::Local; + use rt::task::Task; + + if rt::context() == OldTaskContext { + unsafe { + return rust_local_realloc(ptr, size as libc::size_t); + } + + extern { + #[fast_ffi] + fn rust_local_realloc(ptr: *(), size: libc::size_t) -> *(); + } + } else { + do Local::borrow:: |task| { + task.heap.realloc(ptr as *libc::c_void, size) as *() + } + } } } diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 6bf228a1b220..38cd25f9da5d 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -49,6 +49,12 @@ impl LocalHeap { } } + pub fn realloc(&mut self, ptr: *OpaqueBox, size: uint) -> *OpaqueBox { + unsafe { + return rust_boxed_region_realloc(self.boxed_region, ptr, size as size_t); + } + } + pub fn free(&mut self, box: *OpaqueBox) { unsafe { return rust_boxed_region_free(self.boxed_region, box); @@ -76,5 +82,8 @@ extern { fn rust_boxed_region_malloc(region: *BoxedRegion, td: *TypeDesc, size: size_t) -> *OpaqueBox; + fn rust_boxed_region_realloc(region: *BoxedRegion, + ptr: *OpaqueBox, + size: size_t) -> *OpaqueBox; fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox); } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 7f683d0070fb..4339153c43ee 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -48,12 +48,8 @@ pub mod rustrt { // to ~[] and reserve_shared_actual applies to @[]. #[fast_ffi] unsafe fn vec_reserve_shared(t: *sys::TypeDesc, - v: **raw::VecRepr, + v: *mut *mut raw::VecRepr, n: libc::size_t); - #[fast_ffi] - unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, - v: **raw::VecRepr, - n: libc::size_t); } } @@ -79,11 +75,11 @@ pub fn reserve(v: &mut ~[T], n: uint) { use managed; if capacity(v) < n { unsafe { - let ptr: **raw::VecRepr = cast::transmute(v); + let ptr: *mut *mut raw::VecRepr = cast::transmute(v); let td = sys::get_type_desc::(); if ((**ptr).box_header.ref_count == managed::raw::RC_MANAGED_UNIQUE) { - rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); + ::at_vec::raw::reserve_raw(td, ptr, n); } else { rustrt::vec_reserve_shared(td, ptr, n as libc::size_t); } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index f0b68d4a1569..9ed389b178ae 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -68,11 +68,10 @@ rust_env_pairs() { } #endif -extern "C" CDECL void -vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp, - size_t n_elts) { +extern "C" CDECL void * +rust_local_realloc(rust_opaque_box *ptr, size_t size) { rust_task *task = rust_get_current_task(); - reserve_vec_exact_shared(task, vp, n_elts * ty->size); + return task->boxed.realloc(ptr, size); } // This is completely misnamed. @@ -899,6 +898,11 @@ rust_boxed_region_malloc(boxed_region *region, type_desc *td, size_t size) { return region->malloc(td, size); } +extern "C" CDECL rust_opaque_box* +rust_boxed_region_realloc(boxed_region *region, rust_opaque_box *ptr, size_t size) { + return region->realloc(ptr, size); +} + extern "C" CDECL void rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) { region->free(box); diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index 5b8378b0ad35..242c2ef0a81a 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -57,16 +57,6 @@ vec_data(rust_vec *v) { return reinterpret_cast(v->data); } -inline void reserve_vec_exact_shared(rust_task* task, rust_vec_box** vpp, - size_t size) { - rust_opaque_box** ovpp = (rust_opaque_box**)vpp; - if (size > (*vpp)->body.alloc) { - *vpp = (rust_vec_box*)task->boxed.realloc( - *ovpp, size + sizeof(rust_vec)); - (*vpp)->body.alloc = size; - } -} - inline void reserve_vec_exact(rust_vec_box** vpp, size_t size) { if (size > (*vpp)->body.alloc) { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 950662b91f8e..9add8d537af0 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -53,7 +53,7 @@ rust_get_stack_segment rust_get_c_stack rust_log_str start_task -vec_reserve_shared_actual +rust_local_realloc vec_reserve_shared task_clear_event_reject task_wait_event @@ -231,6 +231,7 @@ rust_delete_memory_region rust_new_boxed_region rust_delete_boxed_region rust_boxed_region_malloc +rust_boxed_region_realloc rust_boxed_region_free rust_try rust_begin_unwind diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index 29b0457fc050..e722c4f5c6a9 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,11 +1,7 @@ use std::libc; -use std::sys; -use std::vec; extern { - pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, - v: **vec::raw::VecRepr, - n: libc::size_t); + pub unsafe fn debug_get_stk_seg() -> *libc::c_void; } pub fn main() { From a09972db3545344048b90e90d1f1821b621a38b9 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 22 Jun 2013 16:52:40 -0700 Subject: [PATCH 92/96] std: Move dynamic borrowck code from unstable::lang to rt::borrowck --- src/libstd/cleanup.rs | 2 +- src/libstd/rt/borrowck.rs | 283 ++++++++++++++++++++++++++++++++++++ src/libstd/rt/mod.rs | 3 + src/libstd/unstable/lang.rs | 235 +----------------------------- 4 files changed, 294 insertions(+), 229 deletions(-) create mode 100644 src/libstd/rt/borrowck.rs diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index d1460b7a3c96..dd7e85ce7e11 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -15,7 +15,7 @@ use ptr::mut_null; use repr::BoxRepr; use sys::TypeDesc; use cast::transmute; -#[cfg(not(test))] use unstable::lang::clear_task_borrow_list; +#[cfg(not(test))] use rt::borrowck::clear_task_borrow_list; #[cfg(not(test))] use ptr::to_unsafe_ptr; diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs new file mode 100644 index 000000000000..e057f6e96371 --- /dev/null +++ b/src/libstd/rt/borrowck.rs @@ -0,0 +1,283 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use cast::transmute; +use libc::{c_char, c_void, size_t, STDERR_FILENO}; +use io; +use io::{Writer, WriterUtil}; +use managed::raw::BoxRepr; +use option::{Option, None, Some}; +use uint; +use str; +use str::OwnedStr; +use sys; +use vec::ImmutableVector; + +#[allow(non_camel_case_types)] +type rust_task = c_void; + +pub static FROZEN_BIT: uint = 1 << (uint::bits - 1); +pub static MUT_BIT: uint = 1 << (uint::bits - 2); +static ALL_BITS: uint = FROZEN_BIT | MUT_BIT; + +#[deriving(Eq)] +struct BorrowRecord { + box: *mut BoxRepr, + file: *c_char, + line: size_t +} + +fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> { + unsafe { + let cur_task: *rust_task = rust_try_get_task(); + if cur_task.is_not_null() { + let ptr = rust_take_task_borrow_list(cur_task); + if ptr.is_null() { + None + } else { + let v: ~[BorrowRecord] = transmute(ptr); + Some(v) + } + } else { + None + } + } +} + +fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) { + unsafe { + let cur_task: *rust_task = rust_try_get_task(); + if cur_task.is_not_null() { + let mut borrow_list: ~[BorrowRecord] = { + let ptr = rust_take_task_borrow_list(cur_task); + if ptr.is_null() { ~[] } else { transmute(ptr) } + }; + borrow_list = f(borrow_list); + rust_set_task_borrow_list(cur_task, transmute(borrow_list)); + } + } +} + +pub unsafe fn clear_task_borrow_list() { + // pub because it is used by the box annihilator. + let _ = try_take_task_borrow_list(); +} + +unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) { + debug_borrow("fail_borrowed: ", box, 0, 0, file, line); + + match try_take_task_borrow_list() { + None => { // not recording borrows + let msg = "borrowed"; + do str::as_buf(msg) |msg_p, _| { + sys::begin_unwind_(msg_p as *c_char, file, line); + } + } + Some(borrow_list) => { // recording borrows + let mut msg = ~"borrowed"; + let mut sep = " at "; + for borrow_list.rev_iter().advance |entry| { + if entry.box == box { + msg.push_str(sep); + let filename = str::raw::from_c_str(entry.file); + msg.push_str(filename); + msg.push_str(fmt!(":%u", entry.line as uint)); + sep = " and at "; + } + } + do str::as_buf(msg) |msg_p, _| { + sys::begin_unwind_(msg_p as *c_char, file, line) + } + } + } +} + +/// Because this code is so perf. sensitive, use a static constant so that +/// debug printouts are compiled out most of the time. +static ENABLE_DEBUG: bool = false; + +#[inline] +unsafe fn debug_borrow(tag: &'static str, + p: *const T, + old_bits: uint, + new_bits: uint, + filename: *c_char, + line: size_t) { + //! A useful debugging function that prints a pointer + tag + newline + //! without allocating memory. + + if ENABLE_DEBUG && ::rt::env::get().debug_borrow { + debug_borrow_slow(tag, p, old_bits, new_bits, filename, line); + } + + unsafe fn debug_borrow_slow(tag: &'static str, + p: *const T, + old_bits: uint, + new_bits: uint, + filename: *c_char, + line: size_t) { + let dbg = STDERR_FILENO as io::fd_t; + dbg.write_str(tag); + dbg.write_hex(p as uint); + dbg.write_str(" "); + dbg.write_hex(old_bits); + dbg.write_str(" "); + dbg.write_hex(new_bits); + dbg.write_str(" "); + dbg.write_cstr(filename); + dbg.write_str(":"); + dbg.write_hex(line as uint); + dbg.write_str("\n"); + } +} + +trait DebugPrints { + fn write_hex(&self, val: uint); + unsafe fn write_cstr(&self, str: *c_char); +} + +impl DebugPrints for io::fd_t { + fn write_hex(&self, mut i: uint) { + let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'a', 'b', 'c', 'd', 'e', 'f']; + static uint_nibbles: uint = ::uint::bytes << 1; + let mut buffer = [0_u8, ..uint_nibbles+1]; + let mut c = uint_nibbles; + while c > 0 { + c -= 1; + buffer[c] = letters[i & 0xF] as u8; + i >>= 4; + } + self.write(buffer.slice(0, uint_nibbles)); + } + + unsafe fn write_cstr(&self, p: *c_char) { + use libc::strlen; + use vec; + + let len = strlen(p); + let p: *u8 = transmute(p); + do vec::raw::buf_as_slice(p, len as uint) |s| { + self.write(s); + } + } +} + +#[inline] +pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint { + let a: *mut BoxRepr = transmute(a); + let old_ref_count = (*a).header.ref_count; + let new_ref_count = old_ref_count | FROZEN_BIT; + + debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line); + + if (old_ref_count & MUT_BIT) != 0 { + fail_borrowed(a, file, line); + } + + (*a).header.ref_count = new_ref_count; + + old_ref_count +} + +#[inline] +pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint { + let a: *mut BoxRepr = transmute(a); + let old_ref_count = (*a).header.ref_count; + let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT; + + debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line); + + if (old_ref_count & (MUT_BIT|FROZEN_BIT)) != 0 { + fail_borrowed(a, file, line); + } + + (*a).header.ref_count = new_ref_count; + + old_ref_count +} + +pub unsafe fn record_borrow(a: *u8, old_ref_count: uint, + file: *c_char, line: size_t) { + if (old_ref_count & ALL_BITS) == 0 { + // was not borrowed before + let a: *mut BoxRepr = transmute(a); + debug_borrow("record_borrow:", a, old_ref_count, 0, file, line); + do swap_task_borrow_list |borrow_list| { + let mut borrow_list = borrow_list; + borrow_list.push(BorrowRecord {box: a, file: file, line: line}); + borrow_list + } + } +} + +pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint, + file: *c_char, line: size_t) { + if (old_ref_count & ALL_BITS) == 0 { + // was not borrowed before, so we should find the record at + // the end of the list + let a: *mut BoxRepr = transmute(a); + debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line); + do swap_task_borrow_list |borrow_list| { + let mut borrow_list = borrow_list; + assert!(!borrow_list.is_empty()); + let br = borrow_list.pop(); + if br.box != a || br.file != file || br.line != line { + let err = fmt!("wrong borrow found, br=%?", br); + do str::as_buf(err) |msg_p, _| { + sys::begin_unwind_(msg_p as *c_char, file, line) + } + } + borrow_list + } + } +} + +#[inline] +pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint, + file: *c_char, line: size_t) { + // Sometimes the box is null, if it is conditionally frozen. + // See e.g. #4904. + if !a.is_null() { + let a: *mut BoxRepr = transmute(a); + let old_ref_count = (*a).header.ref_count; + let new_ref_count = + (old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS); + + debug_borrow("return_to_mut:", + a, old_ref_count, new_ref_count, file, line); + + (*a).header.ref_count = new_ref_count; + } +} + +#[inline] +pub unsafe fn check_not_borrowed(a: *u8, + file: *c_char, + line: size_t) { + let a: *mut BoxRepr = transmute(a); + let ref_count = (*a).header.ref_count; + debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line); + if (ref_count & FROZEN_BIT) != 0 { + fail_borrowed(a, file, line); + } +} + + +extern { + #[rust_stack] + pub fn rust_take_task_borrow_list(task: *rust_task) -> *c_void; + + #[rust_stack] + pub fn rust_set_task_borrow_list(task: *rust_task, map: *c_void); + + #[rust_stack] + pub fn rust_try_get_task() -> *rust_task; +} diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 7e1d18f95486..6c4e5742eb33 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -162,6 +162,9 @@ pub mod util; // Global command line argument storage pub mod args; +// Support for dynamic borrowck +pub mod borrowck; + /// Set up a default runtime configuration, given compiler-supplied arguments. /// /// This is invoked by the `start` _language item_ (unstable::lang) to diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index fa067da2ebc7..d71a672eb355 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -14,7 +14,6 @@ use iterator::IteratorUtil; use uint; use cast::transmute; use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO}; -use managed::raw::BoxRepr; use str; use sys; use rt::{context, OldTaskContext}; @@ -23,14 +22,11 @@ use rt::local::Local; use option::{Option, Some, None}; use io; use rt::global_heap; +use rt::borrowck; #[allow(non_camel_case_types)] pub type rust_task = c_void; -pub static FROZEN_BIT: uint = 1 << (uint::bits - 1); -pub static MUT_BIT: uint = 1 << (uint::bits - 2); -static ALL_BITS: uint = FROZEN_BIT | MUT_BIT; - pub mod rustrt { use unstable::lang::rust_task; use libc::{c_void, c_char, uintptr_t}; @@ -50,12 +46,6 @@ pub mod rustrt { #[fast_ffi] unsafe fn rust_upcall_free_noswitch(ptr: *c_char); - #[rust_stack] - fn rust_take_task_borrow_list(task: *rust_task) -> *c_void; - - #[rust_stack] - fn rust_set_task_borrow_list(task: *rust_task, map: *c_void); - #[rust_stack] fn rust_try_get_task() -> *rust_task; @@ -78,78 +68,6 @@ pub fn fail_bounds_check(file: *c_char, line: size_t, } } -#[deriving(Eq)] -struct BorrowRecord { - box: *mut BoxRepr, - file: *c_char, - line: size_t -} - -fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> { - unsafe { - let cur_task: *rust_task = rustrt::rust_try_get_task(); - if cur_task.is_not_null() { - let ptr = rustrt::rust_take_task_borrow_list(cur_task); - if ptr.is_null() { - None - } else { - let v: ~[BorrowRecord] = transmute(ptr); - Some(v) - } - } else { - None - } - } -} - -fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) { - unsafe { - let cur_task: *rust_task = rustrt::rust_try_get_task(); - if cur_task.is_not_null() { - let mut borrow_list: ~[BorrowRecord] = { - let ptr = rustrt::rust_take_task_borrow_list(cur_task); - if ptr.is_null() { ~[] } else { transmute(ptr) } - }; - borrow_list = f(borrow_list); - rustrt::rust_set_task_borrow_list(cur_task, transmute(borrow_list)); - } - } -} - -pub unsafe fn clear_task_borrow_list() { - // pub because it is used by the box annihilator. - let _ = try_take_task_borrow_list(); -} - -unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) { - debug_borrow("fail_borrowed: ", box, 0, 0, file, line); - - match try_take_task_borrow_list() { - None => { // not recording borrows - let msg = "borrowed"; - do str::as_buf(msg) |msg_p, _| { - fail_(msg_p as *c_char, file, line); - } - } - Some(borrow_list) => { // recording borrows - let mut msg = ~"borrowed"; - let mut sep = " at "; - for borrow_list.rev_iter().advance |entry| { - if entry.box == box { - msg.push_str(sep); - let filename = str::raw::from_c_str(entry.file); - msg.push_str(filename); - msg.push_str(fmt!(":%u", entry.line as uint)); - sep = " and at "; - } - } - do str::as_buf(msg) |msg_p, _| { - fail_(msg_p as *c_char, file, line) - } - } - } -} - // FIXME #4942: Make these signatures agree with exchange_alloc's signatures #[lang="exchange_malloc"] #[inline] @@ -157,77 +75,6 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { transmute(global_heap::malloc(transmute(td), transmute(size))) } -/// Because this code is so perf. sensitive, use a static constant so that -/// debug printouts are compiled out most of the time. -static ENABLE_DEBUG: bool = false; - -#[inline] -unsafe fn debug_borrow(tag: &'static str, - p: *const T, - old_bits: uint, - new_bits: uint, - filename: *c_char, - line: size_t) { - //! A useful debugging function that prints a pointer + tag + newline - //! without allocating memory. - - if ENABLE_DEBUG && ::rt::env::get().debug_borrow { - debug_borrow_slow(tag, p, old_bits, new_bits, filename, line); - } - - unsafe fn debug_borrow_slow(tag: &'static str, - p: *const T, - old_bits: uint, - new_bits: uint, - filename: *c_char, - line: size_t) { - let dbg = STDERR_FILENO as io::fd_t; - dbg.write_str(tag); - dbg.write_hex(p as uint); - dbg.write_str(" "); - dbg.write_hex(old_bits); - dbg.write_str(" "); - dbg.write_hex(new_bits); - dbg.write_str(" "); - dbg.write_cstr(filename); - dbg.write_str(":"); - dbg.write_hex(line as uint); - dbg.write_str("\n"); - } -} - -trait DebugPrints { - fn write_hex(&self, val: uint); - unsafe fn write_cstr(&self, str: *c_char); -} - -impl DebugPrints for io::fd_t { - fn write_hex(&self, mut i: uint) { - let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', - '9', 'a', 'b', 'c', 'd', 'e', 'f']; - static uint_nibbles: uint = ::uint::bytes << 1; - let mut buffer = [0_u8, ..uint_nibbles+1]; - let mut c = uint_nibbles; - while c > 0 { - c -= 1; - buffer[c] = letters[i & 0xF] as u8; - i >>= 4; - } - self.write(buffer.slice(0, uint_nibbles)); - } - - unsafe fn write_cstr(&self, p: *c_char) { - use libc::strlen; - use vec; - - let len = strlen(p); - let p: *u8 = transmute(p); - do vec::raw::buf_as_slice(p, len as uint) |s| { - self.write(s); - } - } -} - // NB: Calls to free CANNOT be allowed to fail, as throwing an exception from // inside a landing pad may corrupt the state of the exception handler. If a // problem occurs, call exit instead. @@ -273,95 +120,32 @@ pub unsafe fn local_free(ptr: *c_char) { #[lang="borrow_as_imm"] #[inline] pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint { - let a: *mut BoxRepr = transmute(a); - let old_ref_count = (*a).header.ref_count; - let new_ref_count = old_ref_count | FROZEN_BIT; - - debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line); - - if (old_ref_count & MUT_BIT) != 0 { - fail_borrowed(a, file, line); - } - - (*a).header.ref_count = new_ref_count; - - old_ref_count + borrowck::borrow_as_imm(a, file, line) } #[lang="borrow_as_mut"] #[inline] pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint { - let a: *mut BoxRepr = transmute(a); - let old_ref_count = (*a).header.ref_count; - let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT; - - debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line); - - if (old_ref_count & (MUT_BIT|FROZEN_BIT)) != 0 { - fail_borrowed(a, file, line); - } - - (*a).header.ref_count = new_ref_count; - - old_ref_count + borrowck::borrow_as_mut(a, file, line) } - #[lang="record_borrow"] pub unsafe fn record_borrow(a: *u8, old_ref_count: uint, file: *c_char, line: size_t) { - if (old_ref_count & ALL_BITS) == 0 { - // was not borrowed before - let a: *mut BoxRepr = transmute(a); - debug_borrow("record_borrow:", a, old_ref_count, 0, file, line); - do swap_task_borrow_list |borrow_list| { - let mut borrow_list = borrow_list; - borrow_list.push(BorrowRecord {box: a, file: file, line: line}); - borrow_list - } - } + borrowck::record_borrow(a, old_ref_count, file, line) } #[lang="unrecord_borrow"] pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint, file: *c_char, line: size_t) { - if (old_ref_count & ALL_BITS) == 0 { - // was not borrowed before, so we should find the record at - // the end of the list - let a: *mut BoxRepr = transmute(a); - debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line); - do swap_task_borrow_list |borrow_list| { - let mut borrow_list = borrow_list; - assert!(!borrow_list.is_empty()); - let br = borrow_list.pop(); - if br.box != a || br.file != file || br.line != line { - let err = fmt!("wrong borrow found, br=%?", br); - do str::as_buf(err) |msg_p, _| { - fail_(msg_p as *c_char, file, line) - } - } - borrow_list - } - } + borrowck::unrecord_borrow(a, old_ref_count, file, line) } #[lang="return_to_mut"] #[inline] pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint, file: *c_char, line: size_t) { - // Sometimes the box is null, if it is conditionally frozen. - // See e.g. #4904. - if !a.is_null() { - let a: *mut BoxRepr = transmute(a); - let old_ref_count = (*a).header.ref_count; - let new_ref_count = - (old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS); - - debug_borrow("return_to_mut:", - a, old_ref_count, new_ref_count, file, line); - - (*a).header.ref_count = new_ref_count; - } + borrowck::return_to_mut(a, orig_ref_count, file, line) } #[lang="check_not_borrowed"] @@ -369,12 +153,7 @@ pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint, pub unsafe fn check_not_borrowed(a: *u8, file: *c_char, line: size_t) { - let a: *mut BoxRepr = transmute(a); - let ref_count = (*a).header.ref_count; - debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line); - if (ref_count & FROZEN_BIT) != 0 { - fail_borrowed(a, file, line); - } + borrowck::check_not_borrowed(a, file, line) } #[lang="strdup_uniq"] From 5e7c5d6c3d532e7b536b76044cd47b72b8eadaad Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 22 Jun 2013 01:09:06 -0700 Subject: [PATCH 93/96] std: Make box annihilator work with newsched --- src/libstd/cleanup.rs | 116 ++++-------------------------------- src/libstd/rt/comm.rs | 12 ---- src/libstd/rt/local_heap.rs | 50 +++++++++++++++- src/libstd/rt/mod.rs | 2 +- src/libstd/rt/task.rs | 21 +++++++ src/libstd/sys.rs | 5 +- src/libstd/unstable/lang.rs | 19 ++---- src/rt/rust_builtin.cpp | 6 ++ src/rt/rustrt.def.in | 3 +- 9 files changed, 102 insertions(+), 132 deletions(-) diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index dd7e85ce7e11..36c1fdf781b2 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -13,107 +13,14 @@ use libc::{c_char, c_void, intptr_t, uintptr_t}; use ptr::mut_null; use repr::BoxRepr; +use rt; +use rt::OldTaskContext; use sys::TypeDesc; use cast::transmute; -#[cfg(not(test))] use rt::borrowck::clear_task_borrow_list; #[cfg(not(test))] use ptr::to_unsafe_ptr; -/** - * Runtime structures - * - * NB: These must match the representation in the C++ runtime. - */ - type DropGlue<'self> = &'self fn(**TypeDesc, *c_void); -type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void); - -type TaskID = uintptr_t; - -struct StackSegment { priv opaque: () } -struct Scheduler { priv opaque: () } -struct SchedulerLoop { priv opaque: () } -struct Kernel { priv opaque: () } -struct Env { priv opaque: () } -struct AllocHeader { priv opaque: () } -struct MemoryRegion { priv opaque: () } - -#[cfg(target_arch="x86")] -struct Registers { - data: [u32, ..16] -} - -#[cfg(target_arch="arm")] -#[cfg(target_arch="mips")] -struct Registers { - data: [u32, ..32] -} - -#[cfg(target_arch="x86")] -#[cfg(target_arch="arm")] -#[cfg(target_arch="mips")] -struct Context { - regs: Registers, - next: *Context, - pad: [u32, ..3] -} - -#[cfg(target_arch="x86_64")] -struct Registers { - data: [u64, ..22] -} - -#[cfg(target_arch="x86_64")] -struct Context { - regs: Registers, - next: *Context, - pad: uintptr_t -} - -struct BoxedRegion { - env: *Env, - backing_region: *MemoryRegion, - live_allocs: *BoxRepr -} - -#[cfg(target_arch="x86")] -#[cfg(target_arch="arm")] -#[cfg(target_arch="mips")] -struct Task { - // Public fields - refcount: intptr_t, // 0 - id: TaskID, // 4 - pad: [u32, ..2], // 8 - ctx: Context, // 16 - stack_segment: *StackSegment, // 96 - runtime_sp: uintptr_t, // 100 - scheduler: *Scheduler, // 104 - scheduler_loop: *SchedulerLoop, // 108 - - // Fields known only to the runtime - kernel: *Kernel, // 112 - name: *c_char, // 116 - list_index: i32, // 120 - boxed_region: BoxedRegion // 128 -} - -#[cfg(target_arch="x86_64")] -struct Task { - // Public fields - refcount: intptr_t, - id: TaskID, - ctx: Context, - stack_segment: *StackSegment, - runtime_sp: uintptr_t, - scheduler: *Scheduler, - scheduler_loop: *SchedulerLoop, - - // Fields known only to the runtime - kernel: *Kernel, - name: *c_char, - list_index: i32, - boxed_region: BoxedRegion -} /* * Box annihilation @@ -132,9 +39,9 @@ unsafe fn each_live_alloc(read_next_before: bool, //! Walks the internal list of allocations use managed; + use rt::local_heap; - let task: *Task = transmute(rustrt::rust_get_task()); - let box = (*task).boxed_region.live_allocs; + let box = local_heap::live_allocs(); let mut box: *mut BoxRepr = transmute(copy box); while box != mut_null() { let next_before = transmute(copy (*box).header.next); @@ -156,7 +63,11 @@ unsafe fn each_live_alloc(read_next_before: bool, #[cfg(unix)] fn debug_mem() -> bool { - ::rt::env::get().debug_mem + // XXX: Need to port the environment struct to newsched + match rt::context() { + OldTaskContext => ::rt::env::get().debug_mem, + _ => false + } } #[cfg(windows)] @@ -165,13 +76,12 @@ fn debug_mem() -> bool { } /// Destroys all managed memory (i.e. @ boxes) held by the current task. -#[cfg(not(test))] -#[lang="annihilate"] pub unsafe fn annihilate() { - use unstable::lang::local_free; + use rt::local_heap::local_free; use io::WriterUtil; use io; use libc; + use rt::borrowck; use sys; use managed; @@ -183,7 +93,7 @@ pub unsafe fn annihilate() { // Quick hack: we need to free this list upon task exit, and this // is a convenient place to do it. - clear_task_borrow_list(); + borrowck::clear_task_borrow_list(); // Pass 1: Make all boxes immortal. // @@ -207,7 +117,7 @@ pub unsafe fn annihilate() { if !uniq { let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc); let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0)); - drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data)); + drop_glue(&tydesc, transmute(&(*box).data)); } } diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index 82e6d44fe625..dd27c03ff516 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -399,12 +399,6 @@ impl GenericChan for SharedChan { } impl GenericSmartChan for SharedChan { - #[cfg(stage0)] // odd type checking errors - fn try_send(&self, _val: T) -> bool { - fail!() - } - - #[cfg(not(stage0))] fn try_send(&self, val: T) -> bool { unsafe { let (next_pone, next_cone) = oneshot(); @@ -448,12 +442,6 @@ impl GenericPort for SharedPort { } } - #[cfg(stage0)] // odd type checking errors - fn try_recv(&self) -> Option { - fail!() - } - - #[cfg(not(stage0))] fn try_recv(&self) -> Option { unsafe { let (next_link_port, next_link_chan) = oneshot(); diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 38cd25f9da5d..f62c9fb2c660 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -10,11 +10,24 @@ //! The local, garbage collected heap +use libc; use libc::{c_void, uintptr_t, size_t}; use ops::Drop; +use repr::BoxRepr; +use rt; +use rt::OldTaskContext; +use rt::local::Local; +use rt::task::Task; type MemoryRegion = c_void; -type BoxedRegion = c_void; + +struct Env { priv opaque: () } + +struct BoxedRegion { + env: *Env, + backing_region: *MemoryRegion, + live_allocs: *BoxRepr +} pub type OpaqueBox = c_void; pub type TypeDesc = c_void; @@ -71,6 +84,40 @@ impl Drop for LocalHeap { } } +// A little compatibility function +pub unsafe fn local_free(ptr: *libc::c_char) { + match rt::context() { + OldTaskContext => { + rust_upcall_free_noswitch(ptr); + + extern { + #[fast_ffi] + unsafe fn rust_upcall_free_noswitch(ptr: *libc::c_char); + } + } + _ => { + do Local::borrow:: |task| { + task.heap.free(ptr as *libc::c_void); + } + } + } +} + +pub fn live_allocs() -> *BoxRepr { + let region = match rt::context() { + OldTaskContext => { + unsafe { rust_current_boxed_region() } + } + _ => { + do Local::borrow:: |task| { + task.heap.boxed_region + } + } + }; + + return unsafe { (*region).live_allocs }; +} + extern { fn rust_new_memory_region(synchronized: uintptr_t, detailed_leaks: uintptr_t, @@ -86,4 +133,5 @@ extern { ptr: *OpaqueBox, size: size_t) -> *OpaqueBox; fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox); + fn rust_current_boxed_region() -> *BoxedRegion; } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 6c4e5742eb33..fec555e8afd4 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -124,7 +124,7 @@ mod thread; pub mod env; /// The local, managed heap -mod local_heap; +pub mod local_heap; /// The Logger trait and implementations pub mod logging; diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 833f25b253c0..68f7eb659b01 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -15,6 +15,7 @@ use borrow; use cast::transmute; +use cleanup; use libc::{c_void, uintptr_t}; use ptr; use prelude::*; @@ -118,6 +119,10 @@ impl Task { } _ => () } + + // Destroy remaining boxes + unsafe { cleanup::annihilate(); } + self.destroyed = true; } } @@ -269,4 +274,20 @@ mod test { assert!(res.is_err()); } } + + #[test] + fn heap_cycles() { + use option::{Option, Some, None}; + + do run_in_newsched_task { + struct List { + next: Option<@mut List>, + } + + let a = @mut List { next: None }; + let b = @mut List { next: Some(a) }; + + a.next = Some(b); + } + } } diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 8ac60ffb979c..523c5d633cf4 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -216,12 +216,15 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { task.logger.log(Left(outmsg.take())); } } else { - rtdebug!("%s", outmsg); + rterrln!("%s", outmsg); } gc::cleanup_stack_for_failure(); let task = Local::unsafe_borrow::(); + if (*task).unwinder.unwinding { + rtabort!("unwinding again"); + } (*task).unwinder.begin_unwind(); } } diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index d71a672eb355..f750b31a466b 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -43,9 +43,6 @@ pub mod rustrt { size: uintptr_t) -> *c_char; - #[fast_ffi] - unsafe fn rust_upcall_free_noswitch(ptr: *c_char); - #[rust_stack] fn rust_try_get_task() -> *rust_task; @@ -105,16 +102,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char { // problem occurs, call exit instead. #[lang="free"] pub unsafe fn local_free(ptr: *c_char) { - match context() { - OldTaskContext => { - rustrt::rust_upcall_free_noswitch(ptr); - } - _ => { - do Local::borrow:: |task| { - task.heap.free(ptr as *c_void); - } - } - } + ::rt::local_heap::local_free(ptr); } #[lang="borrow_as_imm"] @@ -162,6 +150,11 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { str::raw::from_buf_len(ptr, len) } +#[lang="annihilate"] +pub unsafe fn annihilate() { + ::cleanup::annihilate() +} + #[lang="start"] pub fn start(main: *u8, argc: int, argv: **c_char, crate_map: *u8) -> int { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 9ed389b178ae..51e2849eb548 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -882,6 +882,12 @@ rust_delete_memory_region(memory_region *region) { delete region; } +extern "C" CDECL boxed_region* +rust_current_boxed_region() { + rust_task *task = rust_get_current_task(); + return &task->boxed; +} + extern "C" CDECL boxed_region* rust_new_boxed_region(memory_region *region, uintptr_t poison_on_free) { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 9add8d537af0..d85700435e00 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -244,4 +244,5 @@ rust_drop_env_lock rust_update_log_settings rust_running_on_valgrind rust_get_num_cpus -rust_get_global_args_ptr \ No newline at end of file +rust_get_global_args_ptr +rust_current_boxed_region \ No newline at end of file From b530ca103388c99e774868645758785d6ad6b9a9 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 23 Jun 2013 14:01:59 -0700 Subject: [PATCH 94/96] std: Make unlinking and task notification work with newsched --- src/libstd/rt/task.rs | 25 +++++++++++++++++++++++++ src/libstd/task/spawn.rs | 22 +++++++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 68f7eb659b01..97c3b6a749bc 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -290,4 +290,29 @@ mod test { a.next = Some(b); } } + + // XXX: This is a copy of test_future_result in std::task. + // It can be removed once the scheduler is turned on by default. + #[test] + fn future_result() { + do run_in_newsched_task { + use option::{Some, None}; + use task::*; + + let mut result = None; + let mut builder = task(); + builder.future_result(|r| result = Some(r)); + do builder.spawn {} + assert_eq!(result.unwrap().recv(), Success); + + result = None; + let mut builder = task(); + builder.future_result(|r| result = Some(r)); + builder.unlinked(); + do builder.spawn { + fail!(); + } + assert_eq!(result.unwrap().recv(), Failure); + } + } } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 344a58a877fc..63eb768d1c9c 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -578,13 +578,29 @@ pub fn spawn_raw(opts: TaskOpts, f: ~fn()) { } } -fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) { +fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { use rt::sched::*; - let task = do Local::borrow::() |running_task| { - ~running_task.new_child() + let mut task = if opts.linked { + do Local::borrow::() |running_task| { + ~running_task.new_child() + } + } else { + // An unlinked task is a new root in the task tree + ~Task::new_root() }; + if opts.notify_chan.is_some() { + let notify_chan = opts.notify_chan.swap_unwrap(); + let notify_chan = Cell::new(notify_chan); + let on_exit: ~fn(bool) = |success| { + notify_chan.take().send( + if success { Success } else { Failure } + ) + }; + task.on_exit = Some(on_exit); + } + let mut sched = Local::take::(); let task = ~Coroutine::with_task(&mut sched.stack_pool, task, f); From d071f51cdc7c3492ae2bc4180ffbf13bcdb31439 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 23 Jun 2013 14:15:39 -0700 Subject: [PATCH 95/96] std::rt: deny(unused_unsafe) --- src/libstd/rt/mod.rs | 3 ++- src/libstd/rt/test.rs | 2 +- src/libstd/rt/uv/timer.rs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index fec555e8afd4..8713cf05a477 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -58,6 +58,7 @@ Several modules in `core` are clients of `rt`: #[deny(unused_imports)]; #[deny(unused_mut)]; #[deny(unused_variable)]; +#[deny(unused_unsafe)]; use cell::Cell; use clone::Clone; @@ -224,7 +225,7 @@ pub fn run(main: ~fn()) -> int { let nthreads = match os::getenv("RUST_THREADS") { Some(nstr) => FromStr::from_str(nstr).get(), - None => unsafe { util::num_cpus() } + None => util::num_cpus() }; // The shared list of sleeping schedulers. Schedulers wake each other diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs index 36efcd91834b..b0e496840147 100644 --- a/src/libstd/rt/test.rs +++ b/src/libstd/rt/test.rs @@ -74,7 +74,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) { do run_in_bare_thread { let nthreads = match os::getenv("RUST_TEST_THREADS") { Some(nstr) => FromStr::from_str(nstr).get(), - None => unsafe { + None => { // Using more threads than cores in test code // to force the OS to preempt them frequently. // Assuming that this help stress test concurrent types. diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index cd6fc5c0a250..14465eb7dfd3 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -160,14 +160,14 @@ mod test { let mut timer2 = TimerWatcher::new(&mut loop_); do timer2.start(10, 0) |timer2, _| { - unsafe { *count_ptr += 1; } + *count_ptr += 1; timer2.close(||()); // Restart the original timer let mut timer = timer; do timer.start(1, 0) |timer, _| { - unsafe { *count_ptr += 1; } + *count_ptr += 1; timer.close(||()); } } From e65d0cbabebc73f2c9733a7ed158576c9702e71e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 23 Jun 2013 18:22:57 -0700 Subject: [PATCH 96/96] extra: Make test runner compatible with newsched --- src/libextra/test.rs | 17 ++++------------- src/libstd/rt/mod.rs | 9 ++------- src/libstd/rt/util.rs | 12 ++++++++++++ src/test/run-pass/morestack6.rs | 3 --- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 72837cb4ae1f..64c6a822a86e 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -31,14 +31,6 @@ use core::to_str::ToStr; use core::uint; use core::vec; -pub mod rustrt { - use core::libc::size_t; - - #[abi = "cdecl"] - pub extern { - pub unsafe fn rust_sched_threads() -> size_t; - } -} // The name of a test. By convention this follows the rules for rust // paths; i.e. it should be a series of identifiers separated by double @@ -488,11 +480,10 @@ static sched_overcommit : uint = 1; static sched_overcommit : uint = 4u; fn get_concurrency() -> uint { - unsafe { - let threads = rustrt::rust_sched_threads() as uint; - if threads == 1 { 1 } - else { threads * sched_overcommit } - } + use core::rt; + let threads = rt::util::default_sched_threads(); + if threads == 1 { 1 } + else { threads * sched_overcommit } } #[allow(non_implicitly_copyable_typarams)] diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 8713cf05a477..bbf1cf0d9b79 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -63,11 +63,9 @@ Several modules in `core` are clients of `rt`: use cell::Cell; use clone::Clone; use container::Container; -use from_str::FromStr; use iter::Times; use iterator::IteratorUtil; -use option::{Some, None}; -use os; +use option::Some; use ptr::RawPtr; use rt::sched::{Scheduler, Coroutine, Shutdown}; use rt::sleeper_list::SleeperList; @@ -223,10 +221,7 @@ pub fn run(main: ~fn()) -> int { static DEFAULT_ERROR_CODE: int = 101; - let nthreads = match os::getenv("RUST_THREADS") { - Some(nstr) => FromStr::from_str(nstr).get(), - None => util::num_cpus() - }; + let nthreads = util::default_sched_threads(); // The shared list of sleeping schedulers. Schedulers wake each other // occassionally to do new work. diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 904b2f8bbb93..5219ae1d5406 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -9,8 +9,11 @@ // except according to those terms. use container::Container; +use from_str::FromStr; use iterator::IteratorUtil; use libc; +use option::{Some, None}; +use os; use str::StrSlice; /// Get the number of cores available @@ -24,6 +27,15 @@ pub fn num_cpus() -> uint { } } +/// Get's the number of scheduler threads requested by the environment +/// either `RUST_THREADS` or `num_cpus`. +pub fn default_sched_threads() -> uint { + match os::getenv("RUST_THREADS") { + Some(nstr) => FromStr::from_str(nstr).get(), + None => num_cpus() + } +} + pub fn dumb_println(s: &str) { use io::WriterUtil; let dbg = ::libc::STDERR_FILENO as ::io::fd_t; diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 1dc8503aeb22..0e0bf2a13e17 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -23,7 +23,6 @@ mod rustrt { pub fn rust_get_sched_id() -> libc::intptr_t; pub fn rust_get_argc() -> libc::c_int; pub fn get_task_id() -> libc::intptr_t; - pub fn rust_sched_threads(); pub fn rust_get_task(); } } @@ -31,7 +30,6 @@ mod rustrt { fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } } fn calllink02() { unsafe { rustrt::rust_get_argc(); } } fn calllink08() { unsafe { rustrt::get_task_id(); } } -fn calllink09() { unsafe { rustrt::rust_sched_threads(); } } fn calllink10() { unsafe { rustrt::rust_get_task(); } } fn runtest(f: extern fn(), frame_backoff: u32) { @@ -64,7 +62,6 @@ pub fn main() { calllink01, calllink02, calllink08, - calllink09, calllink10 ]; let mut rng = rand::rng();