]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #14388 : kballard/rust/nonfatal_lexer_errors, r=alexcrichton
authorbors <bors@rust-lang.org>
Sat, 24 May 2014 07:01:25 +0000 (00:01 -0700)
committerbors <bors@rust-lang.org>
Sat, 24 May 2014 07:01:25 +0000 (00:01 -0700)
Most errors that arise in the lexer can be recovered from. This allows
for more than one syntax error to be reported at a time.

40 files changed:
mk/platform.mk
src/libcore/cell.rs
src/libcore/finally.rs
src/libcore/lib.rs
src/libcore/ptr.rs
src/libcore/simd.rs [new file with mode: 0644]
src/librustc/lib/llvm.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/util/ppaux.rs
src/libstd/hash/sip.rs
src/libstd/io/test.rs
src/libstd/lib.rs
src/libstd/rt/args.rs
src/libstd/rt/mod.rs
src/libstd/rt/task.rs
src/libstd/rt/util.rs
src/libstd/slice.rs
src/libstd/unstable/mod.rs
src/libstd/unstable/simd.rs [deleted file]
src/libsync/raw.rs
src/llvm
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/llvm-auto-clean-trigger
src/test/bench/shootout-mandelbrot.rs
src/test/compile-fail/issue-10291.rs [new file with mode: 0644]
src/test/compile-fail/simd-binop.rs
src/test/compile-fail/simd-experimental.rs
src/test/debuginfo/simd.rs
src/test/run-pass/backtrace.rs
src/test/run-pass/simd-binop.rs
src/test/run-pass/simd-issue-10604.rs

index ecc4c33d154841e80fceb022a67fafa549d3710e..3ab55ce4b7b1b95e7f0d8a88c84bb950b1bc994a 100644 (file)
@@ -97,13 +97,6 @@ endef
 $(foreach cvar,CC CXX CPP CFLAGS CXXFLAGS CPPFLAGS,\
   $(eval $(call SET_FROM_CFG,$(cvar))))
 
-ifeq ($(CFG_USING_CLANG),1)
-  # The -Qunused-arguments sidesteps spurious warnings from clang
-  CFLAGS += -Qunused-arguments
-  CXXFLAGS += -Qunused-arguments
-  CPPFLAGS += -Qunused-arguments
-endif
-
 CFG_RLIB_GLOB=lib$(1)-*.rlib
 
 # x86_64-unknown-linux-gnu configuration
@@ -516,6 +509,21 @@ CFG_LDPATH_x86_64-unknown-freebsd :=
 CFG_RUN_x86_64-unknown-freebsd=$(2)
 CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))
 
+
+# The -Qunused-arguments sidesteps spurious warnings from clang
+define FILTER_FLAGS
+  ifeq ($$(CFG_USING_CLANG),1)
+    ifneq ($(findstring clang,$$(shell $(CC_$(1)) -v)),)
+      CFG_GCCISH_CFLAGS_$(1) += -Qunused-arguments
+      CFG_GCCISH_CXXFLAGS_$(1) += -Qunused-arguments
+    endif
+  endif
+endef
+
+$(foreach target,$(CFG_TARGET),\
+  $(eval $(call FILTER_FLAGS,$(target))))
+
+
 ifeq ($(CFG_CCACHE_CPP2),1)
   CCACHE_CPP2=1
   export CCACHE_CPP
index 3b1322cdc1b05a64afafa5559c16dfa686d1b96f..4d630db898bc3ca89bfd3cfe1cb7da2fc000b604 100644 (file)
 //! ```
 //! extern crate collections;
 //!
-//! use collections::HashMap;
 //! use std::cell::RefCell;
 //!
 //! struct Graph {
-//!     edges: HashMap<uint, uint>,
+//!     edges: Vec<(uint, uint)>,
 //!     span_tree_cache: RefCell<Option<Vec<(uint, uint)>>>
 //! }
 //!
index a4d261f539a5005a8761a049a22b628a059ed5b0..9f7592a80bd180621d923635455c0e5226281517 100644 (file)
@@ -20,7 +20,7 @@
 # Example
 
 ```
-use std::unstable::finally::Finally;
+use std::finally::Finally;
 
 (|| {
     // ...
@@ -75,7 +75,7 @@ fn finally(&mut self, dtor: ||) -> T {
  * # Example
  *
  * ```
- * use std::unstable::finally::try_finally;
+ * use std::finally::try_finally;
  *
  * struct State<'a> { buffer: &'a mut [u8], len: uint }
  * # let mut buf = [];
index 6de7e8bcacac5d13db9f82d8013762e99f8a0a7c..56cbe2e2a30d187ec32bea4f82fc34ed6f1febe0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! The Rust Core Library
+//! The Rust Core Library
 //!
 //! The Rust Core Library is the dependency-free foundation of [The
 //! Rust Standard Library](../std/index.html). It is the portable glue
@@ -53,7 +53,7 @@
        html_root_url = "http://doc.rust-lang.org/")]
 
 #![no_std]
-#![feature(globs, macro_rules, managed_boxes, phase)]
+#![feature(globs, macro_rules, managed_boxes, phase, simd)]
 #![deny(missing_doc)]
 
 #[cfg(test)] extern crate realcore = "core";
 pub mod option;
 pub mod raw;
 pub mod result;
+pub mod simd;
 pub mod slice;
 pub mod str;
 pub mod tuple;
index 90b5b0d8753e432af7d80df6f21da82231681f97..13d803a6b0e80a2ade733b842df8b50ffa4f67d8 100644 (file)
 
 // FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
 
-//! Conveniences for working with unsafe pointers, the `*T`, and `*mut T` types.
+//! Operations on unsafe pointers, `*T`, and `*mut T`.
 //!
-//! Working with unsafe pointers in Rust is fairly uncommon,
-//! and often limited to some narrow use cases: holding
-//! an unsafe pointer when safe pointers are unsuitable;
-//! checking for null; and converting back to safe pointers.
-//! As a result, there is not yet an abundance of library code
-//! for working with unsafe pointers, and in particular,
-//! since pointer math is fairly uncommon in Rust, it is not
-//! all that convenient.
+//! Working with unsafe pointers in Rust is uncommon,
+//! typically limited to a few patterns.
 //!
 //! Use the [`null` function](fn.null.html) to create null pointers,
 //! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
 //! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
 //! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
 //! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
-//! work everywhere.
+//! work everywhere. The `RawPtr` also defines the `offset` method,
+//! for pointer math.
 //!
 //! # Common ways to create unsafe pointers
 //!
@@ -316,7 +311,7 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
     array_each_with_len(arr, len, cb);
 }
 
-/// Extension methods for raw pointers.
+/// Methods on raw pointers
 pub trait RawPtr<T> {
     /// Returns the null pointer.
     fn null() -> Self;
diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs
new file mode 100644 (file)
index 0000000..99b802f
--- /dev/null
@@ -0,0 +1,96 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! SIMD vectors.
+//!
+//! These types can be used for accessing basic SIMD operations. Each of them
+//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div,
+//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently
+//! comparison operators are not implemented. To use SSE3+, you must enable
+//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
+//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
+//! provided beyond this module.
+//!
+//! ```rust
+//! #[allow(experimental)];
+//!
+//! fn main() {
+//!     use std::simd::f32x4;
+//!     let a = f32x4(40.0, 41.0, 42.0, 43.0);
+//!     let b = f32x4(1.0, 1.1, 3.4, 9.8);
+//!     println!("{}", a + b);
+//! }
+//! ```
+//!
+//! ## Stability Note
+//!
+//! These are all experimental. The inferface may change entirely, without
+//! warning.
+
+#![allow(non_camel_case_types)]
+#![allow(missing_doc)]
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
+                 pub i8, pub i8, pub i8, pub i8,
+                 pub i8, pub i8, pub i8, pub i8,
+                 pub i8, pub i8, pub i8, pub i8);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
+                 pub i16, pub i16, pub i16, pub i16);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct i64x2(pub i64, pub i64);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
+                 pub u8, pub u8, pub u8, pub u8,
+                 pub u8, pub u8, pub u8, pub u8,
+                 pub u8, pub u8, pub u8, pub u8);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
+                 pub u16, pub u16, pub u16, pub u16);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct u64x2(pub u64, pub u64);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[experimental]
+#[simd]
+#[deriving(Show)]
+pub struct f64x2(pub f64, pub f64);
index 711081f46d6669703a276c2d8981881c4398b078..dacda4e2a0b7c7bb3abffb5ede781e7a58196099 100644 (file)
@@ -15,7 +15,7 @@
 use std::c_str::ToCStr;
 use std::cell::RefCell;
 use collections::HashMap;
-use libc::{c_uint, c_ushort, c_void, free};
+use libc::{c_uint, c_ushort, c_void, free, uint64_t};
 use std::str::raw::from_c_str;
 
 use middle::trans::type_::Type;
@@ -92,6 +92,33 @@ pub enum Attribute {
     NonLazyBindAttribute = 1 << 31,
 }
 
+#[repr(u64)]
+pub enum OtherAttribute {
+    // The following are not really exposed in
+    // the LLVM c api so instead to add these
+    // we call a wrapper function in RustWrapper
+    // that uses the C++ api.
+    SanitizeAddressAttribute = 1 << 32,
+    MinSizeAttribute = 1 << 33,
+    NoDuplicateAttribute = 1 << 34,
+    StackProtectStrongAttribute = 1 << 35,
+    SanitizeThreadAttribute = 1 << 36,
+    SanitizeMemoryAttribute = 1 << 37,
+    NoBuiltinAttribute = 1 << 38,
+    ReturnedAttribute = 1 << 39,
+    ColdAttribute = 1 << 40,
+    BuiltinAttribute = 1 << 41,
+    OptimizeNoneAttribute = 1 << 42,
+    InAllocaAttribute = 1 << 43,
+    NonNullAttribute = 1 << 44,
+}
+
+#[repr(C)]
+pub enum AttributeSet {
+    ReturnIndex = 0,
+    FunctionIndex = !0
+}
+
 // enum for the LLVM IntPredicate type
 pub enum IntPredicate {
     IntEQ = 32,
@@ -308,7 +335,7 @@ pub mod llvm {
     use super::{CodeGenModel, RelocMode, CodeGenOptLevel};
     use super::debuginfo::*;
     use libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong,
-                    size_t};
+               size_t, uint64_t};
 
     // Link to our native llvm bindings (things that we need to use the C++ api
     // for) and because llvm is written in C++ we need to link against libstdc++
@@ -706,20 +733,11 @@ pub fn LLVMGetOrInsertFunction(M: ModuleRef,
         pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
         pub fn LLVMGetGC(Fn: ValueRef) -> *c_char;
         pub fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
-        pub fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint);
-        pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char);
-        pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, Name: *c_char);
+        pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
+        pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *c_char);
+        pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *c_char);
         pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
 
-        pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
-        pub fn LLVMRemoveReturnAttribute(Fn: ValueRef, PA: c_uint);
-
-        pub fn LLVMAddColdAttribute(Fn: ValueRef);
-
-        pub fn LLVMRemoveFunctionAttr(Fn: ValueRef,
-                                      PA: c_ulonglong,
-                                      HighPA: c_ulonglong);
-
         /* Operations on parameters */
         pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
         pub fn LLVMGetParams(Fn: ValueRef, Params: *ValueRef);
@@ -783,6 +801,9 @@ pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
         pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
                                           index: c_uint,
                                           align: c_uint);
+        pub fn LLVMAddCallSiteAttribute(Instr: ValueRef,
+                                        index: c_uint,
+                                        Val: uint64_t);
 
         /* Operations on call instructions (only) */
         pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
@@ -1835,7 +1856,7 @@ pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
 
 pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
     unsafe {
-        llvm::LLVMAddFunctionAttr(fn_, attr as c_uint)
+        llvm::LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t)
     }
 }
 /* Memory-managed object interface to type handles. */
index e208097e99b33a27cd8261bf66aad140039878ff..43f3442ec472ec79b29bcd379eb481c2777431e7 100644 (file)
@@ -73,7 +73,7 @@
 use util::nodemap::NodeMap;
 
 use arena::TypedArena;
-use libc::c_uint;
+use libc::{c_uint, uint64_t};
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
 use std::rc::Rc;
@@ -167,6 +167,7 @@ fn drop(&mut self) {
 // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
 fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
            ty: Type, output: ty::t) -> ValueRef {
+
     let llfn: ValueRef = name.with_c_str(|buf| {
         unsafe {
             llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
@@ -177,14 +178,9 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
         // functions returning bottom may unwind, but can never return normally
         ty::ty_bot => {
             unsafe {
-                llvm::LLVMAddFunctionAttr(llfn, lib::llvm::NoReturnAttribute as c_uint)
-            }
-        }
-        // `~` pointer return values never alias because ownership is transferred
-        ty::ty_uniq(..) // | ty::ty_trait(_, _, ty::UniqTraitStore, _, _)
-         => {
-            unsafe {
-                llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
+                llvm::LLVMAddFunctionAttribute(llfn,
+                                               lib::llvm::FunctionIndex as c_uint,
+                                               lib::llvm::NoReturnAttribute as uint64_t)
             }
         }
         _ => {}
@@ -207,8 +203,8 @@ pub fn decl_cdecl_fn(llmod: ModuleRef,
 }
 
 // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
-pub fn get_extern_fn(externs: &mut ExternMap,
-                     llmod: ModuleRef,
+pub fn get_extern_fn(ccx: &CrateContext,
+                     externs: &mut ExternMap,
                      name: &str,
                      cc: lib::llvm::CallConv,
                      ty: Type,
@@ -218,19 +214,19 @@ pub fn get_extern_fn(externs: &mut ExternMap,
         Some(n) => return *n,
         None => {}
     }
-    let f = decl_fn(llmod, name, cc, ty, output);
+    let f = decl_fn(ccx.llmod, name, cc, ty, output);
     externs.insert(name.to_strbuf(), f);
     f
 }
 
-fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
-                      name: &str, did: ast::DefId) -> ValueRef {
+fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::DefId) -> ValueRef {
     match ccx.externs.borrow().find_equiv(&name) {
         Some(n) => return *n,
         None => ()
     }
 
-    let f = decl_rust_fn(ccx, false, inputs, output, name);
+    let f = decl_rust_fn(ccx, fn_ty, name);
+
     csearch::get_item_attrs(&ccx.sess().cstore, did, |meta_items| {
         set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr_outer(x))
                                     .collect::<Vec<_>>().as_slice(), f)
@@ -240,72 +236,27 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
     f
 }
 
-pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
-                    inputs: &[ty::t], output: ty::t,
-                    name: &str) -> ValueRef {
-    use middle::ty::{BrAnon, ReLateBound};
-
-    let llfty = type_of_rust_fn(ccx, has_env, inputs, output);
-    let llfn = decl_cdecl_fn(ccx.llmod, name, llfty, output);
-
-    let uses_outptr = type_of::return_uses_outptr(ccx, output);
-    let offset = if uses_outptr { 1 } else { 0 };
-    let offset = if has_env { offset + 1 } else { offset };
-
-    for (i, &arg_ty) in inputs.iter().enumerate() {
-        let llarg = unsafe { llvm::LLVMGetParam(llfn, (offset + i) as c_uint) };
-        match ty::get(arg_ty).sty {
-            // `~` pointer parameters never alias because ownership is transferred
-            ty::ty_uniq(..) => {
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
-                }
-            }
-            // `&mut` pointer parameters never alias other parameters, or mutable global data
-            ty::ty_rptr(_, mt) if mt.mutbl == ast::MutMutable => {
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
-                }
-            }
-            // When a reference in an argument has no named lifetime, it's impossible for that
-            // reference to escape this function (returned or stored beyond the call by a closure).
-            ty::ty_rptr(ReLateBound(_, BrAnon(_)), _) => {
-                debug!("marking argument of {} as nocapture because of anonymous lifetime", name);
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, lib::llvm::NoCaptureAttribute as c_uint);
-                }
-            }
-            _ => {
-                // For non-immediate arguments the callee gets its own copy of
-                // the value on the stack, so there are no aliases
-                if !type_is_immediate(ccx, arg_ty) {
-                    unsafe {
-                        llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
-                        llvm::LLVMAddAttribute(llarg, lib::llvm::NoCaptureAttribute as c_uint);
-                    }
-                }
-            }
-        }
-    }
+pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
+    let (inputs, output, has_env) = match ty::get(fn_ty).sty {
+        ty::ty_bare_fn(ref f) => (f.sig.inputs.clone(), f.sig.output, false),
+        ty::ty_closure(ref f) => (f.sig.inputs.clone(), f.sig.output, true),
+        _ => fail!("expected closure or fn")
+    };
 
-    // The out pointer will never alias with any other pointers, as the object only exists at a
-    // language level after the call. It can also be tagged with SRet to indicate that it is
-    // guaranteed to point to a usable block of memory for the type.
-    if uses_outptr {
+    let llfty = type_of_rust_fn(ccx, has_env, inputs.as_slice(), output);
+    let llfn = decl_fn(ccx.llmod, name, lib::llvm::CCallConv, llfty, output);
+    let attrs = get_fn_llvm_attributes(ccx, fn_ty);
+    for &(idx, attr) in attrs.iter() {
         unsafe {
-            let outptr = llvm::LLVMGetParam(llfn, 0);
-            llvm::LLVMAddAttribute(outptr, lib::llvm::StructRetAttribute as c_uint);
-            llvm::LLVMAddAttribute(outptr, lib::llvm::NoAliasAttribute as c_uint);
+            llvm::LLVMAddFunctionAttribute(llfn, idx as c_uint, attr);
         }
     }
 
     llfn
 }
 
-pub fn decl_internal_rust_fn(ccx: &CrateContext, has_env: bool,
-                             inputs: &[ty::t], output: ty::t,
-                             name: &str) -> ValueRef {
-    let llfn = decl_rust_fn(ccx, has_env, inputs, output, name);
+pub fn decl_internal_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
+    let llfn = decl_rust_fn(ccx, fn_ty, name);
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
     llfn
 }
@@ -453,7 +404,11 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
     }
 
     if contains_name(attrs, "cold") {
-        unsafe { llvm::LLVMAddColdAttribute(llfn) }
+        unsafe {
+            llvm::LLVMAddFunctionAttribute(llfn,
+                                           lib::llvm::FunctionIndex as c_uint,
+                                           lib::llvm::ColdAttribute as uint64_t)
+        }
     }
 }
 
@@ -463,13 +418,13 @@ pub fn set_always_inline(f: ValueRef) {
 
 pub fn set_split_stack(f: ValueRef) {
     "split-stack".with_c_str(|buf| {
-        unsafe { llvm::LLVMAddFunctionAttrString(f, buf); }
+        unsafe { llvm::LLVMAddFunctionAttrString(f, lib::llvm::FunctionIndex as c_uint, buf); }
     })
 }
 
 pub fn unset_split_stack(f: ValueRef) {
     "split-stack".with_c_str(|buf| {
-        unsafe { llvm::LLVMRemoveFunctionAttrString(f, buf); }
+        unsafe { llvm::LLVMRemoveFunctionAttrString(f, lib::llvm::FunctionIndex as c_uint, buf); }
     })
 }
 
@@ -485,6 +440,7 @@ pub fn note_unique_llvm_symbol(ccx: &CrateContext, sym: StrBuf) {
 
 pub fn get_res_dtor(ccx: &CrateContext,
                     did: ast::DefId,
+                    t: ty::t,
                     parent_id: ast::DefId,
                     substs: &ty::substs)
                  -> ValueRef {
@@ -510,13 +466,14 @@ pub fn get_res_dtor(ccx: &CrateContext,
         let class_ty = ty::subst(tcx, substs,
                                  ty::lookup_item_type(tcx, parent_id).ty);
         let llty = type_of_dtor(ccx, class_ty);
-
-        get_extern_fn(&mut *ccx.externs.borrow_mut(),
-                      ccx.llmod,
+        let dtor_ty = ty::mk_ctor_fn(ccx.tcx(), ast::DUMMY_NODE_ID,
+                                     [glue::get_drop_glue_type(ccx, t)], ty::mk_nil());
+        get_extern_fn(ccx,
+                      &mut *ccx.externs.borrow_mut(),
                       name.as_slice(),
                       lib::llvm::CCallConv,
                       llty,
-                      ty::mk_nil())
+                      dtor_ty)
     }
 }
 
@@ -858,11 +815,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
             match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
                                        ccx.sess().targ_cfg.arch) {
                 Some(Rust) | Some(RustIntrinsic) => {
-                    get_extern_rust_fn(ccx,
-                                       fn_ty.sig.inputs.as_slice(),
-                                       fn_ty.sig.output,
-                                       name.as_slice(),
-                                       did)
+                    get_extern_rust_fn(ccx, t, name.as_slice(), did)
                 }
                 Some(..) | None => {
                     foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
@@ -870,12 +823,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
                 }
             }
         }
-        ty::ty_closure(ref f) => {
-            get_extern_rust_fn(ccx,
-                               f.sig.inputs.as_slice(),
-                               f.sig.output,
-                               name.as_slice(),
-                               did)
+        ty::ty_closure(_) => {
+            get_extern_rust_fn(ccx, t, name.as_slice(), did)
         }
         _ => {
             let llty = type_of(ccx, t);
@@ -891,7 +840,7 @@ pub fn invoke<'a>(
               bcx: &'a Block<'a>,
               llfn: ValueRef,
               llargs: Vec<ValueRef> ,
-              attributes: &[(uint, lib::llvm::Attribute)],
+              fn_ty: ty::t,
               call_info: Option<NodeInfo>)
               -> (ValueRef, &'a Block<'a>) {
     let _icx = push_ctxt("invoke_");
@@ -899,6 +848,8 @@ pub fn invoke<'a>(
         return (C_null(Type::i8(bcx.ccx())), bcx);
     }
 
+    let attributes = get_fn_llvm_attributes(bcx.ccx(), fn_ty);
+
     match bcx.opt_node_id {
         None => {
             debug!("invoke at ???");
@@ -926,7 +877,7 @@ pub fn invoke<'a>(
                               llargs.as_slice(),
                               normal_bcx.llbb,
                               landing_pad,
-                              attributes);
+                              attributes.as_slice());
         return (llresult, normal_bcx);
     } else {
         debug!("calling {} at {}", llfn, bcx.llbb);
@@ -939,7 +890,7 @@ pub fn invoke<'a>(
             None => debuginfo::clear_source_location(bcx.fcx)
         };
 
-        let llresult = Call(bcx, llfn, llargs.as_slice(), attributes);
+        let llresult = Call(bcx, llfn, llargs.as_slice(), attributes.as_slice());
         return (llresult, bcx);
     }
 }
@@ -1708,34 +1659,132 @@ fn register_fn(ccx: &CrateContext,
                node_id: ast::NodeId,
                node_type: ty::t)
                -> ValueRef {
-    let f = match ty::get(node_type).sty {
+    match ty::get(node_type).sty {
         ty::ty_bare_fn(ref f) => {
             assert!(f.abi == Rust || f.abi == RustIntrinsic);
-            f
         }
         _ => fail!("expected bare rust fn or an intrinsic")
     };
 
-    let llfn = decl_rust_fn(ccx,
-                            false,
-                            f.sig.inputs.as_slice(),
-                            f.sig.output,
-                            sym.as_slice());
+    let llfn = decl_rust_fn(ccx, node_type, sym.as_slice());
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
 
+pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u64)> {
+    use middle::ty::{BrAnon, ReLateBound};
+
+    let (fn_sig, has_env) = match ty::get(fn_ty).sty {
+        ty::ty_closure(ref f) => (f.sig.clone(), true),
+        ty::ty_bare_fn(ref f) => (f.sig.clone(), false),
+        _ => fail!("expected closure or function.")
+    };
+
+    // Since index 0 is the return value of the llvm func, we start
+    // at either 1 or 2 depending on whether there's an env slot or not
+    let mut first_arg_offset = if has_env { 2 } else { 1 };
+    let mut attrs = Vec::new();
+    let ret_ty = fn_sig.output;
+
+    // A function pointer is called without the declaration
+    // available, so we have to apply any attributes with ABI
+    // implications directly to the call instruction. Right now,
+    // the only attribute we need to worry about is `sret`.
+    if type_of::return_uses_outptr(ccx, ret_ty) {
+        attrs.push((1, lib::llvm::StructRetAttribute as u64));
+
+        // The outptr can be noalias and nocapture because it's entirely
+        // invisible to the program. We can also mark it as nonnull
+        attrs.push((1, lib::llvm::NoAliasAttribute as u64));
+        attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
+        attrs.push((1, lib::llvm::NonNullAttribute as u64));
+
+        // Add one more since there's an outptr
+        first_arg_offset += 1;
+    } else {
+        // The `noalias` attribute on the return value is useful to a
+        // function ptr caller.
+        match ty::get(ret_ty).sty {
+            // `~` pointer return values never alias because ownership
+            // is transferred
+            ty::ty_uniq(_) => {
+                attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NoAliasAttribute as u64));
+            }
+            _ => {}
+        }
+
+        // We can also mark the return value as `nonnull` in certain cases
+        match ty::get(ret_ty).sty {
+            // These are not really pointers but pairs, (pointer, len)
+            ty::ty_rptr(_, ty::mt { ty: it, .. }) |
+            ty::ty_rptr(_, ty::mt { ty: it, .. }) if match ty::get(it).sty {
+                ty::ty_str | ty::ty_vec(..) => true, _ => false
+            } => {}
+            ty::ty_uniq(_) | ty::ty_rptr(_, _) => {
+                attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NonNullAttribute as u64));
+            }
+            _ => {}
+        }
+    }
+
+    for (idx, &t) in fn_sig.inputs.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
+        match ty::get(t).sty {
+            // `~` pointer parameters never alias because ownership is transferred
+            ty::ty_uniq(_) => {
+                attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
+                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+            }
+            // These are not really pointers but pairs, (pointer, len)
+            ty::ty_rptr(_, ty::mt { ty: it, .. }) |
+            ty::ty_rptr(_, ty::mt { ty: it, .. }) if match ty::get(it).sty {
+                ty::ty_str | ty::ty_vec(..) => true, _ => false
+            } => {}
+            // `&mut` pointer parameters never alias other parameters, or mutable global data
+            ty::ty_rptr(b, mt) if mt.mutbl == ast::MutMutable => {
+                attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
+                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+                match b {
+                    ReLateBound(_, BrAnon(_)) => {
+                        attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
+                    }
+                    _ => {}
+                }
+            }
+            // When a reference in an argument has no named lifetime, it's impossible for that
+            // reference to escape this function (returned or stored beyond the call by a closure).
+            ty::ty_rptr(ReLateBound(_, BrAnon(_)), _) => {
+                attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
+                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+            }
+            // & pointer parameters are never null
+            ty::ty_rptr(_, _) => {
+                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+            }
+            _ => {
+                // For non-immediate arguments the callee gets its own copy of
+                // the value on the stack, so there are no aliases. It's also
+                // program-invisible so can't possibly capture
+                if !type_is_immediate(ccx, t) {
+                    attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
+                    attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
+                }
+            }
+        }
+    }
+
+    attrs
+}
+
 // only use this for foreign function ABIs and glue, use `register_fn` for Rust functions
 pub fn register_fn_llvmty(ccx: &CrateContext,
                           sp: Span,
                           sym: StrBuf,
                           node_id: ast::NodeId,
                           cc: lib::llvm::CallConv,
-                          fn_ty: Type,
-                          output: ty::t) -> ValueRef {
+                          llfty: Type) -> ValueRef {
     debug!("register_fn_llvmty id={} sym={}", node_id, sym);
 
-    let llfn = decl_fn(ccx.llmod, sym.as_slice(), cc, fn_ty, output);
+    let llfn = decl_fn(ccx.llmod, sym.as_slice(), cc, llfty, ty::mk_nil());
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
index bc4a2d9f96fb01435f57a6791cefbc27bdc6ce51..b0a73c4e6f7918a81f156278f7221ec2388d73e8 100644 (file)
@@ -113,7 +113,7 @@ pub fn Invoke(cx: &Block,
               args: &[ValueRef],
               then: BasicBlockRef,
               catch: BasicBlockRef,
-              attributes: &[(uint, lib::llvm::Attribute)])
+              attributes: &[(uint, u64)])
               -> ValueRef {
     if cx.unreachable.get() {
         return C_null(Type::i8(cx.ccx()));
@@ -679,13 +679,13 @@ pub fn InlineAsmCall(cx: &Block, asm: *c_char, cons: *c_char,
 }
 
 pub fn Call(cx: &Block, fn_: ValueRef, args: &[ValueRef],
-            attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
+            attributes: &[(uint, u64)]) -> ValueRef {
     if cx.unreachable.get() { return _UndefReturn(cx, fn_); }
     B(cx).call(fn_, args, attributes)
 }
 
 pub fn CallWithConv(cx: &Block, fn_: ValueRef, args: &[ValueRef], conv: CallConv,
-                    attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
+                    attributes: &[(uint, u64)]) -> ValueRef {
     if cx.unreachable.get() { return _UndefReturn(cx, fn_); }
     B(cx).call_with_conv(fn_, args, conv, attributes)
 }
index f82a609d69572f0d90fb027aa079f4beceaedfed..278e586c6ac161b8074083d2b3356c70bf231935 100644 (file)
@@ -156,7 +156,7 @@ pub fn invoke(&self,
                   args: &[ValueRef],
                   then: BasicBlockRef,
                   catch: BasicBlockRef,
-                  attributes: &[(uint, lib::llvm::Attribute)])
+                  attributes: &[(uint, u64)])
                   -> ValueRef {
         self.count_insn("invoke");
         unsafe {
@@ -168,7 +168,7 @@ pub fn invoke(&self,
                                           catch,
                                           noname());
             for &(idx, attr) in attributes.iter() {
-                llvm::LLVMAddInstrAttribute(v, idx as c_uint, attr as c_uint);
+                llvm::LLVMAddCallSiteAttribute(v, idx as c_uint, attr);
             }
             v
         }
@@ -799,7 +799,7 @@ pub fn inline_asm_call(&self, asm: *c_char, cons: *c_char,
     }
 
     pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
-                attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
+                attributes: &[(uint, u64)]) -> ValueRef {
         self.count_insn("call");
 
         debug!("Call {} with args ({})",
@@ -813,14 +813,14 @@ pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
             let v = llvm::LLVMBuildCall(self.llbuilder, llfn, args.as_ptr(),
                                         args.len() as c_uint, noname());
             for &(idx, attr) in attributes.iter() {
-                llvm::LLVMAddInstrAttribute(v, idx as c_uint, attr as c_uint);
+                llvm::LLVMAddCallSiteAttribute(v, idx as c_uint, attr);
             }
             v
         }
     }
 
     pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
-                          conv: CallConv, attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
+                          conv: CallConv, attributes: &[(uint, u64)]) -> ValueRef {
         self.count_insn("callwithconv");
         let v = self.call(llfn, args, attributes);
         lib::llvm::SetInstructionCallConv(v, conv);
index fe9581c638e7751cf886de89d2090334f37d1974..90600ea2d3b2f869ee6419f7eafcbe06e62f3ea9 100644 (file)
@@ -18,7 +18,7 @@
 
 use back::abi;
 use driver::session;
-use lib::llvm::{ValueRef, NoAliasAttribute, StructRetAttribute, NoCaptureAttribute};
+use lib::llvm::ValueRef;
 use lib::llvm::llvm;
 use metadata::csearch;
 use middle::trans::base;
@@ -614,13 +614,9 @@ pub fn trans_call_inner<'a>(
             llargs.push(opt_llretslot.unwrap());
         }
 
-        // start at 1, because index 0 is the return value of the llvm func
-        let mut first_arg_offset = 1;
-
         // Push the environment (or a trait object's self).
         match (llenv, llself) {
             (Some(llenv), None) => {
-                first_arg_offset += 1;
                 llargs.push(llenv)
             },
             (None, Some(llself)) => llargs.push(llself),
@@ -634,61 +630,11 @@ pub fn trans_call_inner<'a>(
 
         fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
 
-        // A function pointer is called without the declaration
-        // available, so we have to apply any attributes with ABI
-        // implications directly to the call instruction. Right now,
-        // the only attribute we need to worry about is `sret`.
-        let mut attrs = Vec::new();
-        if type_of::return_uses_outptr(ccx, ret_ty) {
-            attrs.push((1, StructRetAttribute));
-            // The outptr can be noalias and nocapture because it's entirely
-            // invisible to the program.
-            attrs.push((1, NoAliasAttribute));
-            attrs.push((1, NoCaptureAttribute));
-            first_arg_offset += 1;
-        }
-
-        // The `noalias` attribute on the return value is useful to a
-        // function ptr caller.
-        match ty::get(ret_ty).sty {
-            // `~` pointer return values never alias because ownership
-            // is transferred
-            ty::ty_uniq(ty) => match ty::get(ty).sty {
-                ty::ty_str => {}
-                _ => attrs.push((0, NoAliasAttribute)),
-            },
-            _ => {}
-        }
-
-        debug!("trans_callee_inner: first_arg_offset={}", first_arg_offset);
-
-        for (idx, &t) in ty::ty_fn_args(callee_ty).iter().enumerate()
-                                                  .map(|(i, v)| (i+first_arg_offset, v)) {
-            use middle::ty::{BrAnon, ReLateBound};
-            if !type_is_immediate(ccx, t) {
-                // if it's not immediate, we have a program-invisible pointer,
-                // which it can't possibly capture
-                attrs.push((idx, NoCaptureAttribute));
-                debug!("trans_callee_inner: argument {} nocapture because it's non-immediate", idx);
-                continue;
-            }
-
-            let t_ = ty::get(t);
-            match t_.sty {
-                ty::ty_rptr(ReLateBound(_, BrAnon(_)), _) => {
-                    debug!("trans_callee_inner: argument {} nocapture because \
-                           of anonymous lifetime", idx);
-                    attrs.push((idx, NoCaptureAttribute));
-                },
-                _ => { }
-            }
-        }
-
         // Invoke the actual rust fn and update bcx/llresult.
         let (llret, b) = base::invoke(bcx,
                                       llfn,
                                       llargs,
-                                      attrs.as_slice(),
+                                      callee_ty,
                                       call_info);
         bcx = b;
         llresult = llret;
index c804cb77fb29d0e8201195e4bc609e2a45b21eb0..5fe6c234579bb73513fa2e799fdd30e53073de57 100644 (file)
@@ -340,21 +340,12 @@ pub fn trans_expr_fn<'a>(
     };
 
     let ccx = bcx.ccx();
-    let fty = node_id_type(bcx, id);
-    let f = match ty::get(fty).sty {
-        ty::ty_closure(ref f) => f,
-        _ => fail!("expected closure")
-    };
-
     let tcx = bcx.tcx();
+    let fty = node_id_type(bcx, id);
     let s = tcx.map.with_path(id, |path| {
         mangle_internal_name_by_path_and_seq(path, "closure")
     });
-    let llfn = decl_internal_rust_fn(ccx,
-                                     true,
-                                     f.sig.inputs.as_slice(),
-                                     f.sig.output,
-                                     s.as_slice());
+    let llfn = decl_internal_rust_fn(ccx, fty, s.as_slice());
 
     // set an inline hint for all closures
     set_inline_hint(llfn);
@@ -414,17 +405,9 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
         mangle_internal_name_by_path_and_seq(path, "as_closure")
     });
     let llfn = if is_local {
-        decl_internal_rust_fn(ccx,
-                              true,
-                              f.sig.inputs.as_slice(),
-                              f.sig.output,
-                              name.as_slice())
+        decl_internal_rust_fn(ccx, closure_ty, name.as_slice())
     } else {
-        decl_rust_fn(ccx,
-                     true,
-                     f.sig.inputs.as_slice(),
-                     f.sig.output,
-                     name.as_slice())
+        decl_rust_fn(ccx, closure_ty, name.as_slice())
     };
 
     ccx.closure_bare_wrapper_cache.borrow_mut().insert(fn_ptr, llfn);
index e08ab33808ac95afcca84df0b8b2e8a61b6d095d..f723a4556b9a3982ad180fe051d3c61462de8818 100644 (file)
@@ -227,12 +227,12 @@ pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi, fty: ty::t,
     // Create the LLVM value for the C extern fn
     let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
 
-    let llfn = base::get_extern_fn(&mut *ccx.externs.borrow_mut(),
-                                   ccx.llmod,
+    let llfn = base::get_extern_fn(ccx,
+                                   &mut *ccx.externs.borrow_mut(),
                                    name,
                                    cc,
                                    llfn_ty,
-                                   tys.fn_sig.output);
+                                   fty);
     add_argument_attributes(&tys, llfn);
 
     llfn
@@ -378,17 +378,21 @@ pub fn trans_native_call<'a>(
     // A function pointer is called without the declaration available, so we have to apply
     // any attributes with ABI implications directly to the call instruction. Right now, the
     // only attribute we need to worry about is `sret`.
-    let sret_attr = if fn_type.ret_ty.is_indirect() {
-        Some((1, StructRetAttribute))
-    } else {
-        None
+    let mut attrs = Vec::new();
+    if fn_type.ret_ty.is_indirect() {
+        attrs.push((1, lib::llvm::StructRetAttribute as u64));
+
+        // The outptr can be noalias and nocapture because it's entirely
+        // invisible to the program. We can also mark it as nonnull
+        attrs.push((1, lib::llvm::NoAliasAttribute as u64));
+        attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
+        attrs.push((1, lib::llvm::NonNullAttribute as u64));
     };
-    let attrs = sret_attr.as_slice();
     let llforeign_retval = CallWithConv(bcx,
                                         llfn,
                                         llargs_foreign.as_slice(),
                                         cc,
-                                        attrs);
+                                        attrs.as_slice());
 
     // If the function we just called does not use an outpointer,
     // store the result into the rust outpointer. Cast the outpointer
@@ -500,14 +504,14 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
     let tys = foreign_types_for_id(ccx, node_id);
     let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
     let t = ty::node_id_to_type(ccx.tcx(), node_id);
-    let (cconv, output) = match ty::get(t).sty {
+    let cconv = match ty::get(t).sty {
         ty::ty_bare_fn(ref fn_ty) => {
             let c = llvm_calling_convention(ccx, fn_ty.abi);
-            (c.unwrap_or(lib::llvm::CCallConv), fn_ty.sig.output)
+            c.unwrap_or(lib::llvm::CCallConv)
         }
         _ => fail!("expected bare fn in register_rust_fn_with_foreign_abi")
     };
-    let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty, output);
+    let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
     add_argument_attributes(&tys, llfn);
     debug!("register_rust_fn_with_foreign_abi(node_id={:?}, llfn_ty={}, llfn={})",
            node_id, ccx.tn.type_to_str(llfn_ty), ccx.tn.val_to_str(llfn));
@@ -528,7 +532,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
         let llrustfn = build_rust_fn(ccx, decl, body, attrs, id);
 
         // Build up the foreign wrapper (`foo` above).
-        return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys);
+        return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys, id);
     }
 
     fn build_rust_fn(ccx: &CrateContext,
@@ -548,10 +552,9 @@ fn build_rust_fn(ccx: &CrateContext,
 
         // Compute the type that the function would have if it were just a
         // normal Rust function. This will be the type of the wrappee fn.
-        let f = match ty::get(t).sty {
+        match ty::get(t).sty {
             ty::ty_bare_fn(ref f) => {
                 assert!(f.abi != Rust && f.abi != RustIntrinsic);
-                f
             }
             _ => {
                 ccx.sess().bug(format!("build_rust_fn: extern fn {} has ty {}, \
@@ -565,11 +568,7 @@ fn build_rust_fn(ccx: &CrateContext,
                ccx.tcx.map.path_to_str(id),
                id, t.repr(tcx));
 
-        let llfn = base::decl_internal_rust_fn(ccx,
-                                               false,
-                                               f.sig.inputs.as_slice(),
-                                               f.sig.output,
-                                               ps.as_slice());
+        let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice());
         base::set_llvm_fn_attrs(attrs, llfn);
         base::trans_fn(ccx, decl, body, llfn, None, id, []);
         llfn
@@ -578,14 +577,18 @@ fn build_rust_fn(ccx: &CrateContext,
     unsafe fn build_wrap_fn(ccx: &CrateContext,
                             llrustfn: ValueRef,
                             llwrapfn: ValueRef,
-                            tys: &ForeignTypes) {
+                            tys: &ForeignTypes,
+                            id: ast::NodeId) {
         let _icx = push_ctxt(
             "foreign::trans_rust_fn_with_foreign_abi::build_wrap_fn");
         let tcx = ccx.tcx();
 
-        debug!("build_wrap_fn(llrustfn={}, llwrapfn={})",
+        let t = ty::node_id_to_type(tcx, id);
+
+        debug!("build_wrap_fn(llrustfn={}, llwrapfn={}, t={})",
                ccx.tn.val_to_str(llrustfn),
-               ccx.tn.val_to_str(llwrapfn));
+               ccx.tn.val_to_str(llwrapfn),
+               t.repr(ccx.tcx()));
 
         // Avoid all the Rust generation stuff and just generate raw
         // LLVM here.
@@ -731,10 +734,15 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
         }
 
         // Perform the call itself
-        debug!("calling llrustfn = {}", ccx.tn.val_to_str(llrustfn));
+        debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_str(llrustfn), t.repr(ccx.tcx()));
         let llrust_ret_val = llvm::LLVMBuildCall(builder, llrustfn, llrust_args.as_ptr(),
                                                  llrust_args.len() as c_uint, noname());
 
+        let attributes = base::get_fn_llvm_attributes(ccx, t);
+        for &(idx, attr) in attributes.iter() {
+            llvm::LLVMAddCallSiteAttribute(llrust_ret_val, idx as c_uint, attr);
+        }
+
         // Get the return value where the foreign fn expects it.
         let llforeign_ret_ty = match tys.fn_ty.ret_ty.cast {
             Some(ty) => ty,
index c103a44aa754363aad881a381247ffad68050c42..6d269756931f7a9c76d38736b894d0686b5c372f 100644 (file)
@@ -88,7 +88,7 @@ pub fn take_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
     }
 }
 
-fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
+pub fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
     let tcx = ccx.tcx();
     if !ty::type_needs_drop(tcx, t) {
         return ty::mk_i8();
@@ -248,7 +248,7 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
     let repr = adt::represent_type(bcx.ccx(), t);
 
     // Find and call the actual destructor
-    let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
+    let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, t,
                                  class_did, substs);
 
     // The second argument is the "self" argument for drop
@@ -279,7 +279,9 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
                                   fld.mt.ty);
     }
 
-    let (_, bcx) = invoke(bcx, dtor_addr, args, [], None);
+    let dtor_ty = ty::mk_ctor_fn(bcx.tcx(), ast::DUMMY_NODE_ID,
+                                 [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil());
+    let (_, bcx) = invoke(bcx, dtor_addr, args, dtor_ty, None);
 
     bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, field_scope)
 }
@@ -459,10 +461,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
         t,
         format!("glue_{}", name).as_slice());
     debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t));
-    let llfn = decl_cdecl_fn(ccx.llmod,
-                             fn_nm.as_slice(),
-                             llfnty,
-                             ty::mk_nil());
+    let llfn = decl_cdecl_fn(ccx.llmod, fn_nm.as_slice(), llfnty, ty::mk_nil());
     note_unique_llvm_symbol(ccx, fn_nm);
     return llfn;
 }
index 3076a19228c39dc2acf04a79dbca156b3818c204..e0fd872fb06a7330a257db8ee175616713c05619 100644 (file)
@@ -172,14 +172,6 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         }
     };
 
-    let f = match ty::get(mono_ty).sty {
-        ty::ty_bare_fn(ref f) => {
-            assert!(f.abi == abi::Rust || f.abi == abi::RustIntrinsic);
-            f
-        }
-        _ => fail!("expected bare rust fn or an intrinsic")
-    };
-
     ccx.stats.n_monos.set(ccx.stats.n_monos.get() + 1);
 
     let depth;
@@ -214,11 +206,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
     // This shouldn't need to option dance.
     let mut hash_id = Some(hash_id);
     let mk_lldecl = || {
-        let lldecl = decl_internal_rust_fn(ccx,
-                                           false,
-                                           f.sig.inputs.as_slice(),
-                                           f.sig.output,
-                                           s.as_slice());
+        let lldecl = decl_internal_rust_fn(ccx, mono_ty, s.as_slice());
         ccx.monomorphized.borrow_mut().insert(hash_id.take_unwrap(), lldecl);
         lldecl
     };
index a65802d2c36ff1c498a9834632e1712093da5c5d..f5f3d4366f6e081f30d5d39f4334c4c72601a99b 100644 (file)
@@ -291,10 +291,10 @@ pub fn visit_ty(&mut self, t: ty::t) {
                 let sym = mangle_internal_name_by_path_and_seq(
                     ast_map::Values([].iter()).chain(None), "get_disr");
 
+                let fn_ty = ty::mk_ctor_fn(&ccx.tcx, ast::DUMMY_NODE_ID,
+                                           [opaqueptrty], ty::mk_u64());
                 let llfdecl = decl_internal_rust_fn(ccx,
-                                                    false,
-                                                    [opaqueptrty],
-                                                    ty::mk_u64(),
+                                                    fn_ty,
                                                     sym.as_slice());
                 let arena = TypedArena::new();
                 let fcx = new_fn_ctxt(ccx, llfdecl, -1, false,
index 087a4e58d497808299dcf75127e0969e387ddb32..2dff56d32d28d0f46a01c633924034c331eed34b 100644 (file)
@@ -145,7 +145,7 @@ fn explain_span(cx: &ctxt, heading: &str, span: Span)
 }
 
 pub fn bound_region_ptr_to_str(cx: &ctxt, br: BoundRegion) -> StrBuf {
-    bound_region_to_str(cx, "&", true, br)
+    bound_region_to_str(cx, "", false, br)
 }
 
 pub fn bound_region_to_str(cx: &ctxt,
index 1434e3c7ad71e693f60ea4a57615087f02e5f1f8..d7dae94cf167acbb36bf909ec9ffbcf9c6cb4088 100644 (file)
@@ -645,7 +645,7 @@ fn bench_compound_1(b: &mut Bencher) {
             y: 2,
         };
         b.iter(|| {
-            assert_eq!(hash(&compound), 15783192367317361799);
+            assert_eq!(hash(&compound), 12506681940457338191);
         })
     }
 }
index de8a6f4beb5ea3102bad955d034d578bbe409cb0..bc52bc9946c087c15fafe4ed8fb6538dcad7c2f4 100644 (file)
@@ -37,7 +37,7 @@ mod $name {
             use io::net::unix::*;
             use io::timer::*;
             use io::process::*;
-            use unstable::running_on_valgrind;
+            use rt::running_on_valgrind;
             use str;
 
             fn f() $b
index 51cf2aabf55a52ddc4945686f604870e20fddd6f..ca70fd162b7d8f7d3fb417075cd66dc56f2bdd61 100644 (file)
@@ -20,8 +20,7 @@
 //! modules deal with unsafe pointers and memory manipulation.
 //! [`kinds`](../core/kinds/index.html) defines the special built-in traits,
 //! and [`raw`](../core/raw/index.html) the runtime representation of Rust types.
-//! These are some of the lowest-level building blocks of Rust
-//! abstractions.
+//! These are some of the lowest-level building blocks in Rust.
 //!
 //! ## Math on primitive types and math traits
 //!
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/")]
 #![feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args,
-           simd, linkage, default_type_params, phase, concat_idents, quad_precision_float)]
+           linkage, default_type_params, phase, concat_idents, quad_precision_float)]
 
 // Don't link to std. We are std.
 #![no_std]
 #[cfg(not(test))] pub use core::cmp;
 pub use core::container;
 pub use core::default;
+pub use core::finally;
 pub use core::intrinsics;
 pub use core::iter;
 #[cfg(not(test))] pub use core::kinds;
 #[cfg(not(test))] pub use core::ops;
 pub use core::ptr;
 pub use core::raw;
+pub use core::simd;
 pub use core::tuple;
 #[cfg(not(test))] pub use core::ty;
 pub use core::result;
index cde20521c2f66bda09b1486bfa368ffa9f338da1..4316fb21d415047ecbef2d5a04107dbb4061718f 100644 (file)
@@ -144,7 +144,7 @@ unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> Vec<Vec<u8>> {
     mod tests {
         use prelude::*;
         use super::*;
-        use unstable::finally::Finally;
+        use finally::Finally;
 
         #[test]
         fn smoke_test() {
index daf18346fee2afcfcf0f261e84d7c2ea078e16bf..d2131ad44fb301cabf0e674d45b6935aa74739f2 100644 (file)
 
 pub use alloc::{heap, libc_heap};
 
+// Used by I/O tests
+#[experimental]
+pub use self::util::running_on_valgrind;
+
 // FIXME: these probably shouldn't be public...
 #[doc(hidden)]
 pub mod shouldnt_be_public {
index 749f44d1c9d2c0e37837a0d64527c86b0426f8bc..3e61f3ff23624050614b0570ab0ec863b9aad0e0 100644 (file)
@@ -36,7 +36,7 @@
 use str::SendStr;
 use sync::atomics::{AtomicUint, SeqCst};
 use task::{TaskResult, TaskOpts};
-use unstable::finally::Finally;
+use finally::Finally;
 
 /// The Task struct represents all state associated with a rust
 /// task. There are at this point two primary "subtypes" of task,
index 1ab9ac1b11edca81f18d34c48acc4d7b3d92c4bb..103fbdc0bc93d2f58ce9f1e51595a375f4826757 100644 (file)
 use io;
 use iter::Iterator;
 use libc;
+use libc::uintptr_t;
 use option::{Some, None, Option};
 use os;
 use result::Ok;
 use str::{Str, StrSlice};
-use unstable::running_on_valgrind;
 use slice::ImmutableVector;
 
 // Indicates whether we should perform expensive sanity checks, including rtassert!
@@ -162,3 +162,15 @@ fn abort() -> ! {
         unsafe { intrinsics::abort() }
     }
 }
+
+/// Dynamically inquire about whether we're running under V.
+/// You should usually not use this unless your test definitely
+/// can't run correctly un-altered. Valgrind is there to help
+/// you notice weirdness in normal, un-doctored code paths!
+pub fn running_on_valgrind() -> bool {
+    unsafe { rust_running_on_valgrind() != 0 }
+}
+
+extern {
+    fn rust_running_on_valgrind() -> uintptr_t;
+}
index 18dc871fb27102ead4937f74a9a2bc5d327acd08..e1242e24537572d4d4c183d2d8bb2212ce4ab25a 100644 (file)
 use ptr::RawPtr;
 use ptr;
 use rt::heap::{allocate, deallocate};
-use unstable::finally::try_finally;
+use finally::try_finally;
 use vec::Vec;
 
 pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows};
index f464f70772d9412e6616f21c4f3b9bf70931f9d4..d8de6463fabbd73c7feb9da30b987f5daec9b4c2 100644 (file)
 
 #![doc(hidden)]
 
-use libc::uintptr_t;
-
-pub use core::finally;
-
 pub mod dynamic_lib;
 
-pub mod simd;
 pub mod sync;
 pub mod mutex;
 
-/// Dynamically inquire about whether we're running under V.
-/// You should usually not use this unless your test definitely
-/// can't run correctly un-altered. Valgrind is there to help
-/// you notice weirdness in normal, un-doctored code paths!
-pub fn running_on_valgrind() -> bool {
-    unsafe { rust_running_on_valgrind() != 0 }
-}
-
-extern {
-    fn rust_running_on_valgrind() -> uintptr_t;
-}
diff --git a/src/libstd/unstable/simd.rs b/src/libstd/unstable/simd.rs
deleted file mode 100644 (file)
index a7a314d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! SIMD vectors
-
-#![allow(non_camel_case_types)]
-
-#[experimental]
-#[simd]
-pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8);
-
-#[experimental]
-#[simd]
-pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
-                 pub i16, pub i16, pub i16, pub i16);
-
-#[experimental]
-#[simd]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[experimental]
-#[simd]
-pub struct i64x2(pub i64, pub i64);
-
-#[experimental]
-#[simd]
-pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8);
-
-#[experimental]
-#[simd]
-pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
-                 pub u16, pub u16, pub u16, pub u16);
-
-#[experimental]
-#[simd]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[experimental]
-#[simd]
-pub struct u64x2(pub u64, pub u64);
-
-#[experimental]
-#[simd]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[experimental]
-#[simd]
-pub struct f64x2(pub f64, pub f64);
index 591318d24b23c45c7af18de9131c0d8293521166..aae790f887a61caf4f1a595f0ae4cf740ec026a5 100644 (file)
@@ -18,7 +18,7 @@
 use std::kinds::marker;
 use std::mem;
 use std::sync::atomics;
-use std::unstable::finally::Finally;
+use std::finally::Finally;
 
 use mutex;
 
index 4b4d0533b4f76cc3fbba31bd9e7ac02e0c738b1d..0a894645cf120539876e9eb4eb0d7b572dfa9d14 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 4b4d0533b4f76cc3fbba31bd9e7ac02e0c738b1d
+Subproject commit 0a894645cf120539876e9eb4eb0d7b572dfa9d14
index 64776421fa1451c122839a93926844d4b8b52087..195b044ccdcef57ee72d6524b10bc65bc27c1add 100644 (file)
@@ -13,6 +13,7 @@
 #include "rustllvm.h"
 
 #include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 
index 717cd333a79ce800e41dee9ee23fb20871f5b2a1..2157aecf37613f18104337eca70833917825ef1f 100644 (file)
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/ObjectFile.h"
 
+#if LLVM_VERSION_MINOR >= 5
+#include "llvm/IR/CallSite.h"
+#else
+#include "llvm/Support/CallSite.h"
+#endif
+
 //===----------------------------------------------------------------------===
 //
 // This file defines alternate interfaces to core functions that are more
@@ -83,46 +89,43 @@ extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
   return wrap(Type::getMetadataTy(*unwrap(C)));
 }
 
-extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
-  unwrap<Function>(fn)->addFnAttr(Name);
+extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) {
+  CallSite Call = CallSite(unwrap<Instruction>(Instr));
+  AttrBuilder B;
+  B.addRawValue(Val);
+  Call.setAttributes(
+    Call.getAttributes().addAttributes(Call->getContext(), index,
+                                       AttributeSet::get(Call->getContext(),
+                                                         index, B)));
+}
+
+extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64_t Val) {
+  Function *A = unwrap<Function>(Fn);
+  AttrBuilder B;
+  B.addRawValue(Val);
+  A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
+}
+
+extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
+  Function *F = unwrap<Function>(Fn);
+  AttrBuilder B;
+  B.addAttribute(Name);
+  F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
 }
 
-extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, const char *Name) {
+extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
   Function *f = unwrap<Function>(fn);
   LLVMContext &C = f->getContext();
   AttrBuilder B;
   B.addAttribute(Name);
-  AttributeSet to_remove = AttributeSet::get(C, AttributeSet::FunctionIndex, B);
+  AttributeSet to_remove = AttributeSet::get(C, index, B);
 
   AttributeSet attrs = f->getAttributes();
   f->setAttributes(attrs.removeAttributes(f->getContext(),
-                                          AttributeSet::FunctionIndex,
+                                          index,
                                           to_remove));
 }
 
-extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
-  Function *A = unwrap<Function>(Fn);
-  AttrBuilder B(PA);
-  A->addAttributes(AttributeSet::ReturnIndex,
-                   AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex,  B));
-}
-
-extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
-  Function *A = unwrap<Function>(Fn);
-  AttrBuilder B(PA);
-  A->removeAttributes(AttributeSet::ReturnIndex,
-                      AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex,  B));
-}
-
-#if LLVM_VERSION_MINOR >= 5
-extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {
-  Function *A = unwrap<Function>(Fn);
-  A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold);
-}
-#else
-extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {}
-#endif
-
 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
                                             LLVMValueRef source,
                                             const char* Name,
index 340a491527710eb8c574852cf8660823562854d4..4e599ad115db36dc9e66602a112073caae7ce50d 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2014-04-14
+2014-05-20
index 6b3079b8fc8d1246761b77f490cea9609d707352..70abebd321a94862215e0bc867f8cb381751f610 100644 (file)
@@ -17,7 +17,7 @@
 
 use std::io;
 use std::os;
-use std::unstable::simd::f64x2;
+use std::simd::f64x2;
 use sync::Future;
 use sync::Arc;
 
diff --git a/src/test/compile-fail/issue-10291.rs b/src/test/compile-fail/issue-10291.rs
new file mode 100644 (file)
index 0000000..71b98bb
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn test<'x>(x: &'x int) { //~ NOTE the lifetime 'x as defined
+    drop::< <'z>|&'z int| -> &'z int>(|z| {
+        //~^ ERROR mismatched types
+        //~^^ ERROR cannot infer an appropriate lifetime
+        x
+    });
+}
+
+fn main() {}
index 281e879592dde592a5b5ce0ba4e1c87cc4a6dd86..9fbb7364054d51c6b0d13020c1a7c6f8a7b38a37 100644 (file)
 
 #![allow(experimental)]
 
-use std::unstable::simd::f32x4;
+use std::simd::f32x4;
 
 fn main() {
 
     let _ = f32x4(0.0, 0.0, 0.0, 0.0) == f32x4(0.0, 0.0, 0.0, 0.0);
-    //~^ ERROR binary comparison operation `==` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
+    //~^ ERROR binary comparison operation `==` not supported for floating point SIMD vector `core::simd::f32x4`
 
     let _ = f32x4(0.0, 0.0, 0.0, 0.0) != f32x4(0.0, 0.0, 0.0, 0.0);
-    //~^ ERROR binary comparison operation `!=` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
+    //~^ ERROR binary comparison operation `!=` not supported for floating point SIMD vector `core::simd::f32x4`
 
     let _ = f32x4(0.0, 0.0, 0.0, 0.0) < f32x4(0.0, 0.0, 0.0, 0.0);
-    //~^ ERROR binary comparison operation `<` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
+    //~^ ERROR binary comparison operation `<` not supported for floating point SIMD vector `core::simd::f32x4`
 
     let _ = f32x4(0.0, 0.0, 0.0, 0.0) <= f32x4(0.0, 0.0, 0.0, 0.0);
-    //~^ ERROR binary comparison operation `<=` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
+    //~^ ERROR binary comparison operation `<=` not supported for floating point SIMD vector `core::simd::f32x4`
 
     let _ = f32x4(0.0, 0.0, 0.0, 0.0) >= f32x4(0.0, 0.0, 0.0, 0.0);
-    //~^ ERROR binary comparison operation `>=` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
+    //~^ ERROR binary comparison operation `>=` not supported for floating point SIMD vector `core::simd::f32x4`
 
     let _ = f32x4(0.0, 0.0, 0.0, 0.0) > f32x4(0.0, 0.0, 0.0, 0.0);
-    //~^ ERROR binary comparison operation `>` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
+    //~^ ERROR binary comparison operation `>` not supported for floating point SIMD vector `core::simd::f32x4`
 
 }
index f9cc4d0d8c372f1658dc1eed65a325e1d07c3e91..5f9f56bf3c0f4800e52d8ed641a87a445d127a6d 100644 (file)
@@ -10,7 +10,7 @@
 
 #![deny(experimental)]
 
-use std::unstable::simd;
+use std::simd;
 
 fn main() {
     let _ = simd::i64x2(0, 0); //~ ERROR: experimental
index ff9618aa1f1eb08a6fc363e96ba133e525b4a73a..b84405ee7270e76271bd289cb26dfc27cedd923c 100644 (file)
@@ -43,7 +43,7 @@
 #![allow(experimental)]
 #![allow(unused_variable)]
 
-use std::unstable::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
+use std::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
 
 fn main() {
 
index 5e7b9d9560e381794df09e73205090b79d22cee2..7f2c9e14af10d747728660012a1b616c79548566 100644 (file)
@@ -15,7 +15,7 @@
 
 use std::os;
 use std::io::process::Command;
-use std::unstable::finally::Finally;
+use std::finally::Finally;
 use std::str;
 
 #[start]
index efcd99a04cedd86534ddb475e9dee433b831cc9a..7f9be78d5832db8aac58f5f06f2c57aa029a1e6a 100644 (file)
@@ -10,7 +10,7 @@
 
 #![allow(experimental)]
 
-use std::unstable::simd::{i32x4, f32x4, u32x4};
+use std::simd::{i32x4, f32x4, u32x4};
 
 fn eq_u32x4(u32x4(x0, x1, x2, x3): u32x4, u32x4(y0, y1, y2, y3): u32x4) -> bool {
     (x0 == y0) && (x1 == y1) && (x2 == y2) && (x3 == y3)
index 2e533e3b263a0186ad3815941464b2c23c0568ee..966db25a128a797849065b9f8a3d8350ac3cfc3b 100644 (file)
@@ -13,5 +13,5 @@
 #![feature(simd)]
 
 pub fn main() {
-    let _o = None::<std::unstable::simd::i32x4>;
+    let _o = None::<std::simd::i32x4>;
 }