]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15086 : jakub-/rust/xc-struct-variants-match, r=alexcrichton
authorbors <bors@rust-lang.org>
Mon, 23 Jun 2014 09:16:36 +0000 (09:16 +0000)
committerbors <bors@rust-lang.org>
Mon, 23 Jun 2014 09:16:36 +0000 (09:16 +0000)
Turns out field names of struct variants are not encoded in crate metadata.

51 files changed:
src/doc/guide-container.md
src/doc/rust.md
src/doc/tutorial.md
src/etc/generate-deriving-span-tests.py
src/etc/vim/syntax/rust.vim
src/libcollections/vec.rs
src/librustc/front/feature_gate.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/astencode.rs
src/librustc/middle/check_match.rs
src/librustc/middle/lint.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/cabi_arm.rs
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/cabi_x86.rs
src/librustc/middle/trans/cabi_x86_64.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustc/middle/typeck/mod.rs
src/librustc/util/ppaux.rs
src/libserialize/json.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs
src/llvm
src/rt/rust_test_helpers.c
src/rustllvm/RustWrapper.cpp
src/rustllvm/llvm-auto-clean-trigger
src/test/compile-fail/destructure-trait-ref.rs [new file with mode: 0644]
src/test/compile-fail/issue-4972.rs
src/test/run-pass/foreign-fn-with-byval.rs [new file with mode: 0644]
src/test/run-pass/issue-15080.rs [new file with mode: 0644]
src/test/run-pass/vec-matching.rs

index cca8cd7a84ac12be7f9fceee72cea3d4b4111d6e..903aa86840918b78fd199da4fcc7f114ab5c5656 100644 (file)
@@ -26,7 +26,7 @@ The standard library provides three owned map/set types:
   implement `Eq` and `Hash`
 * `collections::TrieMap` and `collections::TrieSet`, requiring the keys to be `uint`
 * `collections::TreeMap` and `collections::TreeSet`, requiring the keys
-  to implement `TotalOrd`
+  to implement `Ord`
 
 These maps do not use managed pointers so they can be sent between tasks as
 long as the key and value types are sendable. Neither the key or value type has
index 6049ffab2bf7330732a1aec7700f1af51b9b336a..e7b6941b622e81475ae9024b265666eb3f1fe28f 100644 (file)
@@ -2270,7 +2270,7 @@ impl<T: PartialEq> PartialEq for Foo<T> {
 
 Supported traits for `deriving` are:
 
-* Comparison traits: `PartialEq`, `TotalEq`, `PartialOrd`, `TotalOrd`.
+* Comparison traits: `PartialEq`, `Eq`, `PartialOrd`, `Ord`.
 * Serialization: `Encodable`, `Decodable`. These require `serialize`.
 * `Clone`, to create `T` from `&T` via a copy.
 * `Hash`, to iterate over the bytes in a data type.
index 6d9aa484167f1550e563d53f5de4bd710dba67c5..e6d9cef7a31083296eb27206df9616c7b8db6c2b 100644 (file)
@@ -2619,8 +2619,8 @@ fn main() {
 }
 ~~~
 
-The full list of derivable traits is `PartialEq`, `TotalEq`, `Ord`,
-`TotalOrd`, `Encodable`, `Decodable`, `Clone`,
+The full list of derivable traits is `PartialEq`, `Eq`, `PartialOrd`,
+`Ord`, `Encodable`, `Decodable`, `Clone`,
 `Hash`, `Rand`, `Default`, `Zero`, `FromPrimitive` and `Show`.
 
 # Crates and the module system
index 7e6bfcdd4ec64e9e09926c971aecd0a17bd729e6..94b3fb6b93aa47ad74881799e5986f5611cfbd7d 100755 (executable)
@@ -119,8 +119,8 @@ for (trait, supers, errs) in [('Rand', [], 1),
                               ('Clone', [], 1),
                               ('PartialEq', [], 2),
                               ('PartialOrd', ['PartialEq'], 8),
-                              ('TotalEq', ['PartialEq'], 1),
-                              ('TotalOrd', ['TotalEq', 'PartialOrd', 'PartialEq'], 1),
+                              ('Eq', ['PartialEq'], 1),
+                              ('Ord', ['Eq', 'PartialOrd', 'PartialEq'], 1),
                               ('Show', [], 1),
                               ('Hash', [], 1)]:
     traits[trait] = (ALL, supers, errs)
index a0488cdb05ab47c42f02f59e379370db671441f2..8ef03f87b5b391b7e9fa8855ff79fc10d5697e7a 100644 (file)
@@ -82,7 +82,7 @@ syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr IntoBytes
 syn keyword rustTrait ToCStr
 syn keyword rustTrait Char
 syn keyword rustTrait Clone
-syn keyword rustTrait Eq Ord TotalEq TotalOrd Ordering Equiv
+syn keyword rustTrait Eq Ord PartialEq PartialOrd Ordering Equiv
 syn keyword rustEnumVariant Less Equal Greater
 syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
 syn keyword rustTrait FromIterator Extendable
@@ -104,7 +104,7 @@ syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
 syn keyword rustTrait CloneableVector ImmutableCloneableVector MutableCloneableVector
 syn keyword rustTrait ImmutableVector MutableVector
-syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector MutableTotalOrdVector
+syn keyword rustTrait ImmutableEqVector ImmutableOrdVector MutableOrdVector
 syn keyword rustTrait Vector VectorVector OwnedVector MutableVectorAllocating
 syn keyword rustTrait String
 syn keyword rustTrait Vec
index 61e732846a1a3db6f0e43d5ec3129ef2af2610f2..953fa68138a0755ef4930f78f5ef245ebea315c8 100644 (file)
@@ -85,6 +85,7 @@ pub fn new() -> Vec<T> {
     /// # use std::vec::Vec;
     /// let vec: Vec<int> = Vec::with_capacity(10);
     /// ```
+    #[inline]
     pub fn with_capacity(capacity: uint) -> Vec<T> {
         if mem::size_of::<T>() == 0 {
             Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
@@ -110,6 +111,7 @@ pub fn with_capacity(capacity: uint) -> Vec<T> {
     /// let vec = Vec::from_fn(3, |idx| idx * 2);
     /// assert_eq!(vec, vec!(0, 2, 4));
     /// ```
+    #[inline]
     pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
         unsafe {
             let mut xs = Vec::with_capacity(length);
@@ -193,6 +195,7 @@ pub fn append(mut self, second: &[T]) -> Vec<T> {
     /// let slice = [1, 2, 3];
     /// let vec = Vec::from_slice(slice);
     /// ```
+    #[inline]
     pub fn from_slice(values: &[T]) -> Vec<T> {
         values.iter().map(|x| x.clone()).collect()
     }
@@ -207,6 +210,7 @@ pub fn from_slice(values: &[T]) -> Vec<T> {
     /// let vec = Vec::from_elem(3, "hi");
     /// println!("{}", vec); // prints [hi, hi, hi]
     /// ```
+    #[inline]
     pub fn from_elem(length: uint, value: T) -> Vec<T> {
         unsafe {
             let mut xs = Vec::with_capacity(length);
@@ -353,6 +357,7 @@ fn clone_from(&mut self, other: &Vec<T>) {
 }
 
 impl<T> FromIterator<T> for Vec<T> {
+    #[inline]
     fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
         let (lower, _) = iterator.size_hint();
         let mut vector = Vec::with_capacity(lower);
@@ -364,6 +369,7 @@ fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
 }
 
 impl<T> Extendable<T> for Vec<T> {
+    #[inline]
     fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
         let (lower, _) = iterator.size_hint();
         self.reserve_additional(lower);
@@ -1029,6 +1035,7 @@ pub fn remove(&mut self, index: uint) -> Option<T> {
     /// vec.push_all_move(vec!(box 2, box 3, box 4));
     /// assert_eq!(vec, vec!(box 1, box 2, box 3, box 4));
     /// ```
+    #[inline]
     pub fn push_all_move(&mut self, other: Vec<T>) {
         self.extend(other.move_iter());
     }
@@ -1306,6 +1313,7 @@ impl<T:PartialEq> Vec<T> {
     /// let vec = vec!(1, 2, 3);
     /// assert!(vec.contains(&1));
     /// ```
+    #[inline]
     pub fn contains(&self, x: &T) -> bool {
         self.as_slice().contains(x)
     }
@@ -1544,8 +1552,11 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> Vec<T> {
 
 #[cfg(test)]
 mod tests {
+    extern crate test;
+
     use std::prelude::*;
     use std::mem::size_of;
+    use test::Bencher;
     use super::{unzip, raw, Vec};
 
     #[test]
@@ -1836,4 +1847,111 @@ fn drop(&mut self) {
         let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
         v.truncate(0);
     }
+
+    #[bench]
+    fn bench_new(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::new();
+            assert_eq!(v.capacity(), 0);
+            assert!(v.as_slice() == []);
+        })
+    }
+
+    #[bench]
+    fn bench_with_capacity_0(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::with_capacity(0);
+            assert_eq!(v.capacity(), 0);
+            assert!(v.as_slice() == []);
+        })
+    }
+
+
+    #[bench]
+    fn bench_with_capacity_5(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::with_capacity(5);
+            assert_eq!(v.capacity(), 5);
+            assert!(v.as_slice() == []);
+        })
+    }
+
+    #[bench]
+    fn bench_with_capacity_100(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::with_capacity(100);
+            assert_eq!(v.capacity(), 100);
+            assert!(v.as_slice() == []);
+        })
+    }
+
+    #[bench]
+    fn bench_from_fn_0(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::from_fn(0, |_| 5);
+            assert!(v.as_slice() == []);
+        })
+    }
+
+    #[bench]
+    fn bench_from_fn_5(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::from_fn(5, |_| 5);
+            assert!(v.as_slice() == [5, 5, 5, 5, 5]);
+        })
+    }
+
+    #[bench]
+    fn bench_from_slice_0(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::from_slice([]);
+            assert!(v.as_slice() == []);
+        })
+    }
+
+    #[bench]
+    fn bench_from_slice_5(b: &mut Bencher) {
+        b.iter(|| {
+            let v: Vec<int> = Vec::from_slice([1, 2, 3, 4, 5]);
+            assert!(v.as_slice() == [1, 2, 3, 4, 5]);
+        })
+    }
+
+    #[bench]
+    fn bench_from_iter_0(b: &mut Bencher) {
+        b.iter(|| {
+            let v0: Vec<int> = vec!();
+            let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
+            assert!(v1.as_slice() == []);
+        })
+    }
+
+    #[bench]
+    fn bench_from_iter_5(b: &mut Bencher) {
+        b.iter(|| {
+            let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
+            let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
+            assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
+        })
+    }
+
+    #[bench]
+    fn bench_extend_0(b: &mut Bencher) {
+        b.iter(|| {
+            let v0: Vec<int> = vec!();
+            let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
+            v1.extend(v0.move_iter());
+            assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
+        })
+    }
+
+    #[bench]
+    fn bench_extend_5(b: &mut Bencher) {
+        b.iter(|| {
+            let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
+            let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
+            v1.extend(v0.move_iter());
+            assert!(v1.as_slice() == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]);
+        })
+    }
 }
index 07926ee112d5ae70543e68943e46521c8520ce64..07715684db3ef3f2fa5a41a7663ba0210f67db82 100644 (file)
@@ -16,7 +16,7 @@
 //! enabled.
 //!
 //! Features are enabled in programs via the crate-level attributes of
-//! #![feature(...)] with a comma-separated list of features.
+//! `#![feature(...)]` with a comma-separated list of features.
 
 use middle::lint;
 
index 32b7df23d520add0e2fa708227f4583c0e85e263..5ab8eeeb36055c7242e3d192f66eb6cd4ccf6038 100644 (file)
@@ -193,7 +193,7 @@ pub fn get_struct_fields(cstore: &cstore::CStore,
 
 pub fn get_type(tcx: &ty::ctxt,
                 def: ast::DefId)
-             -> ty::ty_param_bounds_and_ty {
+             -> ty::Polytype {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_type(&*cdata, def.node, tcx)
@@ -206,7 +206,7 @@ pub fn get_trait_def(tcx: &ty::ctxt, def: ast::DefId) -> ty::TraitDef {
 }
 
 pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
-                      def: ast::DefId) -> ty::ty_param_bounds_and_ty {
+                      def: ast::DefId) -> ty::Polytype {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(class_id.krate);
     let all_items = reader::get_doc(ebml::Doc::new(cdata.data()), tag_items);
@@ -224,7 +224,7 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
                     def)).to_string()
         });
     let ty = decoder::item_type(def, the_field, tcx, &*cdata);
-    ty::ty_param_bounds_and_ty {
+    ty::Polytype {
         generics: ty::Generics {types: VecPerParamSpace::empty(),
                                 regions: VecPerParamSpace::empty()},
         ty: ty
index 548a8c50501ddd97951fe7d7205a16cc07002a2f..f5ce8cda8c4a6d1b35f00a77c4304701a74e263e 100644 (file)
@@ -422,7 +422,7 @@ pub fn get_trait_def(cdata: Cmd,
 }
 
 pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
-    -> ty::ty_param_bounds_and_ty {
+    -> ty::Polytype {
 
     let item = lookup_item(id, cdata.data());
 
@@ -432,7 +432,7 @@ pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
     let tp_defs = item_ty_param_defs(item, tcx, cdata, tag_items_data_item_ty_param_bounds);
     let rp_defs = item_region_param_defs(item, cdata);
 
-    ty::ty_param_bounds_and_ty {
+    ty::Polytype {
         generics: ty::Generics {types: tp_defs,
                                 regions: rp_defs},
         ty: t
index a94ea0b98eb6aeb307cdf69cbde723764b10778d..b606ba3b87a53e983d14d317d28b3389d497dcdc 100644 (file)
@@ -196,11 +196,11 @@ fn encode_item_variances(ebml_w: &mut Encoder,
 
 fn encode_bounds_and_type(ebml_w: &mut Encoder,
                           ecx: &EncodeContext,
-                          tpt: &ty::ty_param_bounds_and_ty) {
-    encode_ty_type_param_defs(ebml_w, ecx, &tpt.generics.types,
+                          pty: &ty::Polytype) {
+    encode_ty_type_param_defs(ebml_w, ecx, &pty.generics.types,
                               tag_items_data_item_ty_param_bounds);
-    encode_region_param_defs(ebml_w, &tpt.generics.regions);
-    encode_type(ecx, ebml_w, tpt.ty);
+    encode_region_param_defs(ebml_w, &pty.generics.regions);
+    encode_type(ecx, ebml_w, pty.ty);
 }
 
 fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
@@ -772,8 +772,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
     encode_stability(ebml_w, stab);
 
     // The type for methods gets encoded twice, which is unfortunate.
-    let tpt = lookup_item_type(ecx.tcx, m.def_id);
-    encode_bounds_and_type(ebml_w, ecx, &tpt);
+    let pty = lookup_item_type(ecx.tcx, m.def_id);
+    encode_bounds_and_type(ebml_w, ecx, &pty);
 
     let elem = ast_map::PathName(m.ident.name);
     encode_path(ebml_w, impl_path.chain(Some(elem).move_iter()));
@@ -785,7 +785,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
     }
 
     for &ast_method in ast_method_opt.iter() {
-        let any_types = !tpt.generics.types.is_empty();
+        let any_types = !pty.generics.types.is_empty();
         if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
             encode_inlined_item(ecx, ebml_w,
                                 IIMethodRef(local_def(parent_id), false,
@@ -1218,8 +1218,8 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                                   fn_style_static_method_family(
                                       method_ty.fty.fn_style));
 
-                    let tpt = ty::lookup_item_type(tcx, method_def_id);
-                    encode_bounds_and_type(ebml_w, ecx, &tpt);
+                    let pty = ty::lookup_item_type(tcx, method_def_id);
+                    encode_bounds_and_type(ebml_w, ecx, &pty);
                 }
 
                 _ => {
@@ -1242,8 +1242,8 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                     // this.
                     if method_ty.explicit_self != SelfStatic {
                         // FIXME: I feel like there is something funny going on.
-                        let tpt = ty::lookup_item_type(tcx, method_def_id);
-                        encode_bounds_and_type(ebml_w, ecx, &tpt);
+                        let pty = ty::lookup_item_type(tcx, method_def_id);
+                        encode_bounds_and_type(ebml_w, ecx, &pty);
                     }
                     encode_method_sort(ebml_w, 'p');
                     encode_inlined_item(ecx, ebml_w,
index 8cb975182a033181745a0eb77ce9a2ab5cb83760..31a3057e8a644c37c6896b9e1a830fb3207f5440 100644 (file)
@@ -839,9 +839,9 @@ trait ebml_writer_helpers {
     fn emit_type_param_def(&mut self,
                            ecx: &e::EncodeContext,
                            type_param_def: &ty::TypeParameterDef);
-    fn emit_tpbt(&mut self,
-                 ecx: &e::EncodeContext,
-                 tpbt: ty::ty_param_bounds_and_ty);
+    fn emit_polytype(&mut self,
+                     ecx: &e::EncodeContext,
+                     pty: ty::Polytype);
     fn emit_substs(&mut self, ecx: &e::EncodeContext, substs: &subst::Substs);
     fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustment);
 }
@@ -865,26 +865,26 @@ fn emit_type_param_def(&mut self,
         });
     }
 
-    fn emit_tpbt(&mut self,
+    fn emit_polytype(&mut self,
                  ecx: &e::EncodeContext,
-                 tpbt: ty::ty_param_bounds_and_ty) {
-        self.emit_struct("ty_param_bounds_and_ty", 2, |this| {
+                 pty: ty::Polytype) {
+        self.emit_struct("Polytype", 2, |this| {
             this.emit_struct_field("generics", 0, |this| {
                 this.emit_struct("Generics", 2, |this| {
                     this.emit_struct_field("types", 0, |this| {
                         Ok(encode_vec_per_param_space(
-                            this, &tpbt.generics.types,
+                            this, &pty.generics.types,
                             |this, def| this.emit_type_param_def(ecx, def)))
                     });
                     this.emit_struct_field("regions", 1, |this| {
                         Ok(encode_vec_per_param_space(
-                            this, &tpbt.generics.regions,
+                            this, &pty.generics.regions,
                             |this, def| def.encode(this).unwrap()))
                     })
                 })
             });
             this.emit_struct_field("ty", 1, |this| {
-                Ok(this.emit_ty(ecx, tpbt.ty))
+                Ok(this.emit_ty(ecx, pty.ty))
             })
         });
     }
@@ -1030,11 +1030,11 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
     }
 
     let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
-    for &tpbt in tcx.tcache.borrow().find(&lid).iter() {
+    for &pty in tcx.tcache.borrow().find(&lid).iter() {
         ebml_w.tag(c::tag_table_tcache, |ebml_w| {
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val, |ebml_w| {
-                ebml_w.emit_tpbt(ecx, tpbt.clone());
+                ebml_w.emit_polytype(ecx, pty.clone());
             })
         })
     }
@@ -1142,8 +1142,8 @@ trait ebml_decoder_decoder_helpers {
     fn read_tys(&mut self, xcx: &ExtendedDecodeContext) -> Vec<ty::t>;
     fn read_type_param_def(&mut self, xcx: &ExtendedDecodeContext)
                            -> ty::TypeParameterDef;
-    fn read_ty_param_bounds_and_ty(&mut self, xcx: &ExtendedDecodeContext)
-                                -> ty::ty_param_bounds_and_ty;
+    fn read_polytype(&mut self, xcx: &ExtendedDecodeContext)
+                     -> ty::Polytype;
     fn read_substs(&mut self, xcx: &ExtendedDecodeContext) -> subst::Substs;
     fn read_auto_adjustment(&mut self, xcx: &ExtendedDecodeContext) -> ty::AutoAdjustment;
     fn convert_def_id(&mut self,
@@ -1245,10 +1245,10 @@ fn read_type_param_def(&mut self, xcx: &ExtendedDecodeContext)
         }).unwrap()
     }
 
-    fn read_ty_param_bounds_and_ty(&mut self, xcx: &ExtendedDecodeContext)
-                                   -> ty::ty_param_bounds_and_ty {
-        self.read_struct("ty_param_bounds_and_ty", 2, |this| {
-            Ok(ty::ty_param_bounds_and_ty {
+    fn read_polytype(&mut self, xcx: &ExtendedDecodeContext)
+                                   -> ty::Polytype {
+        self.read_struct("Polytype", 2, |this| {
+            Ok(ty::Polytype {
                 generics: this.read_struct_field("generics", 0, |this| {
                     this.read_struct("Generics", 2, |this| {
                         Ok(ty::Generics {
@@ -1408,9 +1408,9 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
                         dcx.tcx.freevars.borrow_mut().insert(id, fv_info);
                     }
                     c::tag_table_tcache => {
-                        let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx);
+                        let pty = val_dsr.read_polytype(xcx);
                         let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
-                        dcx.tcx.tcache.borrow_mut().insert(lid, tpbt);
+                        dcx.tcx.tcache.borrow_mut().insert(lid, pty);
                     }
                     c::tag_table_param_defs => {
                         let bounds = val_dsr.read_type_param_def(xcx);
index b550cb2bb68e42cceb1f63fbef149a29f5f8a3ab..09a9273dba73a2d4d37f3435b56cfc8aeb8a03f5 100644 (file)
@@ -282,21 +282,27 @@ fn missing_constructor(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Optio
 }
 
 fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec<ctor> {
+    // This produces a list of all vector constructors that we would expect to appear
+    // in an exhaustive set of patterns. Because such a list would normally be infinite,
+    // we narrow it down to only those constructors that actually appear in the inspected
+    // column, plus, any that are missing and not covered by a pattern with a destructured slice.
     fn vec_constructors(m: &Matrix) -> Vec<ctor> {
         let max_vec_len = m.iter().map(|r| match r.get(0).node {
             PatVec(ref before, _, ref after) => before.len() + after.len(),
             _ => 0u
         }).max().unwrap_or(0u);
-        let contains_slice = m.iter().any(|r| match r.get(0).node {
-            PatVec(_, ref slice, _) => slice.is_some(),
-            _ => false
-        });
-        let lengths = iter::range_inclusive(0u, if contains_slice {
-            max_vec_len
-        } else {
-            max_vec_len + 1
-        });
-        lengths.map(|len| vec(len)).collect()
+        let min_vec_len_with_slice = m.iter().map(|r| match r.get(0).node {
+            PatVec(ref before, Some(_), ref after) => before.len() + after.len(),
+            _ => max_vec_len + 1
+        }).min().unwrap_or(max_vec_len + 1);
+        let other_lengths = m.iter().map(|r| match r.get(0).node {
+            PatVec(ref before, _, ref after) => before.len() + after.len(),
+            _ => 0u
+        }).filter(|&len| len > min_vec_len_with_slice);
+        iter::range_inclusive(0u, min_vec_len_with_slice)
+            .chain(other_lengths)
+            .map(|len| vec(len))
+            .collect()
     }
 
     match ty::get(left_ty).sty {
index c2a19bb43c8337ab3895ad7f19e354896360d05b..c2fad75d6b89b490ffd488b365fc2f6680827467 100644 (file)
@@ -721,7 +721,7 @@ fn check_while_true_expr(cx: &Context, e: &ast::Expr) {
 impl<'a> AstConv for Context<'a>{
     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
 
-    fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
+    fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
         ty::lookup_item_type(self.tcx, id)
     }
 
index 5b9c89f6250931f4f8a8713263bebcaeb776e1e4..5fae1635bee8e491dc458670c6856a41a0aa6213 100644 (file)
@@ -1200,8 +1200,6 @@ fn score(p: &ast::Pat) -> uint {
 pub enum branch_kind { no_branch, single, switch, compare, compare_vec_len, }
 
 // Compiles a comparison between two things.
-//
-// NB: This must produce an i1, not a Rust bool (i8).
 fn compare_values<'a>(
                   cx: &'a Block<'a>,
                   lhs: ValueRef,
@@ -1218,11 +1216,7 @@ fn compare_str<'a>(cx: &'a Block<'a>,
                            format!("comparison of `{}`",
                                    cx.ty_to_str(rhs_t)).as_slice(),
                            StrEqFnLangItem);
-        let result = callee::trans_lang_call(cx, did, [lhs, rhs], None);
-        Result {
-            bcx: result.bcx,
-            val: bool_to_i1(result.bcx, result.val)
-        }
+        callee::trans_lang_call(cx, did, [lhs, rhs], None)
     }
 
     let _icx = push_ctxt("compare_values");
@@ -1243,11 +1237,7 @@ fn compare_str<'a>(cx: &'a Block<'a>,
                                    format!("comparison of `{}`",
                                            cx.ty_to_str(rhs_t)).as_slice(),
                                    UniqStrEqFnLangItem);
-                let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None);
-                Result {
-                    bcx: result.bcx,
-                    val: bool_to_i1(result.bcx, result.val)
-                }
+                callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None)
             }
             _ => cx.sess().bug("only strings supported in compare_values"),
         },
index 35795cc9f23ee4d9f926ed7d6f0ff1cd9c041374..da49c7764ce535604d2fc38093007a2419ea5a51 100644 (file)
@@ -501,7 +501,6 @@ pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
 // Used only for creating scalar comparison glue.
 pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, }
 
-// NB: This produces an i1, not a Rust bool (i8).
 pub fn compare_scalar_types<'a>(
                             cx: &'a Block<'a>,
                             lhs: ValueRef,
@@ -1815,6 +1814,13 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
             }
             _ => {}
         }
+
+        match ty::get(ret_ty).sty {
+            ty::ty_bool => {
+                attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::ZExtAttribute as u64));
+            }
+            _ => {}
+        }
     }
 
     for (idx, &t) in fn_sig.inputs.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
@@ -1828,6 +1834,9 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
                 attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
                 attrs.push((idx, lib::llvm::NonNullAttribute as u64));
             }
+            ty::ty_bool => {
+                attrs.push((idx, lib::llvm::ZExtAttribute as u64));
+            }
             // `~` pointer parameters never alias because ownership is transferred
             ty::ty_uniq(_) => {
                 attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
index ee2c6454aeedbc6c71f1dc98ac6b4d01d7dcfcbd..01bef64ebba642bf1fa0347de358191b179049eb 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(non_uppercase_pattern_statics)]
 
 use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
-use lib::llvm::StructRetAttribute;
+use lib::llvm::{StructRetAttribute, ZExtAttribute};
 use middle::trans::cabi::{FnType, ArgType};
 use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
@@ -85,7 +85,8 @@ fn ty_size(ty: Type) -> uint {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        return ArgType::direct(ty, None, None, None);
+        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        return ArgType::direct(ty, None, None, attr);
     }
     let size = ty_size(ty);
     if size <= 4 {
@@ -103,7 +104,8 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
 
 fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        return ArgType::direct(ty, None, None, None);
+        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        return ArgType::direct(ty, None, None, attr);
     }
     let align = ty_align(ty);
     let size = ty_size(ty);
index 395bc637aada086672c156641fa65d04a158ce2e..60db609e59ed184cc9b7eac69e711be04643296f 100644 (file)
@@ -13,7 +13,7 @@
 use libc::c_uint;
 use std::cmp;
 use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
-use lib::llvm::StructRetAttribute;
+use lib::llvm::{StructRetAttribute, ZExtAttribute};
 use middle::trans::context::CrateContext;
 use middle::trans::cabi::*;
 use middle::trans::type_::Type;
@@ -83,9 +83,10 @@ fn ty_size(ty: Type) -> uint {
     }
 }
 
-fn classify_ret_ty(ty: Type) -> ArgType {
+fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        ArgType::direct(ty, None, None, None)
+        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::indirect(ty, Some(StructRetAttribute))
     }
@@ -101,7 +102,8 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType {
     *offset += align_up_to(size, align * 8) / 8;
 
     if is_reg_ty(ty) {
-        ArgType::direct(ty, None, None, None)
+        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::direct(
             ty,
@@ -160,7 +162,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
                         rty: Type,
                         ret_def: bool) -> FnType {
     let ret_ty = if ret_def {
-        classify_ret_ty(rty)
+        classify_ret_ty(ccx, rty)
     } else {
         ArgType::direct(Type::void(ccx), None, None, None)
     };
index d10f6b72820d29c68b77c9e21e29edb009062728..5fffdf08646b9824b9f8b1846fbe9041002bdcd2 100644 (file)
@@ -59,7 +59,8 @@ enum Strategy { RetValue(Type), RetPointer }
             }
         }
     } else {
-        ret_ty = ArgType::direct(rty, None, None, None);
+        let attr = if rty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        ret_ty = ArgType::direct(rty, None, None, attr);
     }
 
     for &t in atys.iter() {
@@ -72,7 +73,10 @@ enum Strategy { RetValue(Type), RetPointer }
                     ArgType::indirect(t, Some(ByValAttribute))
                 }
             }
-            _ => ArgType::direct(t, None, None, None),
+            _ => {
+                let attr = if t == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+                ArgType::direct(t, None, None, attr)
+            }
         };
         arg_tys.push(ty);
     }
index 9f98cf57c09b581de1df33fa28d8c529ff66a771..b2cd9d256dd43c4ea9845a3a74cf84d658433166 100644 (file)
@@ -15,7 +15,7 @@
 
 use lib::llvm::{llvm, Integer, Pointer, Float, Double};
 use lib::llvm::{Struct, Array, Attribute};
-use lib::llvm::{StructRetAttribute, ByValAttribute};
+use lib::llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
 use middle::trans::cabi::*;
 use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
@@ -337,12 +337,12 @@ pub fn compute_abi_info(ccx: &CrateContext,
     fn x86_64_ty(ccx: &CrateContext,
                  ty: Type,
                  is_mem_cls: |cls: &[RegClass]| -> bool,
-                 attr: Attribute)
+                 ind_attr: Attribute)
                  -> ArgType {
         if !ty.is_reg_ty() {
             let cls = classify_ty(ty);
             if is_mem_cls(cls.as_slice()) {
-                ArgType::indirect(ty, Some(attr))
+                ArgType::indirect(ty, Some(ind_attr))
             } else {
                 ArgType::direct(ty,
                                 Some(llreg_ty(ccx, cls.as_slice())),
@@ -350,7 +350,8 @@ fn x86_64_ty(ccx: &CrateContext,
                                 None)
             }
         } else {
-            ArgType::direct(ty, None, None, None)
+            let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+            ArgType::direct(ty, None, None, attr)
         }
     }
 
index d7509866e08862687c60b03c0857edd44ba0aba6..a1923022e7b176dad7326b7000356453f8e6b033 100644 (file)
@@ -818,11 +818,6 @@ pub fn find_vtable(tcx: &ty::ctxt,
     param_bounds.get(n_bound).clone()
 }
 
-// Casts a Rust bool value to an i1.
-pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
-    build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(bcx.ccx(), false))
-}
-
 pub fn langcall(bcx: &Block,
                 span: Option<Span>,
                 msg: &str,
index 338821537e8c6d098a095a6f63120dd6ccdf6c8d..527ce5dfaae4591d62285d229780ae8137279736 100644 (file)
@@ -399,18 +399,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                 let (dv, _dt) = const_deref(cx, te, ty, true);
                 dv
               }
-              ast::UnNot    => {
-                match ty::get(ty).sty {
-                    ty::ty_bool => {
-                        // Somewhat questionable, but I believe this is
-                        // correct.
-                        let te = llvm::LLVMConstTrunc(te, Type::i1(cx).to_ref());
-                        let te = llvm::LLVMConstNot(te);
-                        llvm::LLVMConstZExt(te, Type::bool(cx).to_ref())
-                    }
-                    _ => llvm::LLVMConstNot(te),
-                }
-              }
+              ast::UnNot    => llvm::LLVMConstNot(te),
               ast::UnNeg    => {
                 if is_float { llvm::LLVMConstFNeg(te) }
                 else        { llvm::LLVMConstNeg(te) }
index 158a7d6cf7ab91a61a8026a27719e865cad3469d..440aa36b28cbd2e9e8cb864b0bc9aa044fa27150 100644 (file)
@@ -525,8 +525,6 @@ fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
 
     if type_is_zero_size(bcx.ccx(), ty) {
         C_undef(type_of::type_of(bcx.ccx(), ty))
-    } else if ty::type_is_bool(ty) {
-        LoadRangeAssert(bcx, llptr, 0, 2, lib::llvm::False)
     } else if ty::type_is_char(ty) {
         // a char is a unicode codepoint, and so takes values from 0
         // to 0x10FFFF inclusive only.
@@ -652,8 +650,7 @@ pub fn to_llscalarish<'a>(self, bcx: &'a Block<'a>) -> ValueRef {
 
     pub fn to_llbool<'a>(self, bcx: &'a Block<'a>) -> ValueRef {
         assert!(ty::type_is_bool(self.ty) || ty::type_is_bot(self.ty))
-        let cond_val = self.to_llscalarish(bcx);
-        bool_to_i1(bcx, cond_val)
+        self.to_llscalarish(bcx)
     }
 }
 
index 9c957eec90acdef6fb9f8aeb814a21307aab627c..9af5c7aa792358e4021ee7ec2c6c8ffbd6260ce2 100644 (file)
@@ -1147,11 +1147,7 @@ fn trans_unary<'a>(bcx: &'a Block<'a>,
             let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
             let llresult = if ty::type_is_bool(un_ty) {
                 let val = datum.to_llscalarish(bcx);
-                let llcond = ICmp(bcx,
-                                  lib::llvm::IntEQ,
-                                  val,
-                                  C_bool(ccx, false));
-                Select(bcx, llcond, C_bool(ccx, true), C_bool(ccx, false))
+                Xor(bcx, val, C_bool(ccx, true))
             } else {
                 // Note: `Not` is bitwise, not suitable for logical not.
                 Not(bcx, datum.to_llscalarish(bcx))
@@ -1325,9 +1321,7 @@ fn trans_eager_binop<'a>(
         if ty::type_is_bot(rhs_t) {
             C_bool(bcx.ccx(), false)
         } else if ty::type_is_scalar(rhs_t) {
-            let cmpr = base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op);
-            bcx = cmpr.bcx;
-            ZExt(bcx, cmpr.val, Type::i8(bcx.ccx()))
+            unpack_result!(bcx, base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op))
         } else if is_simd {
             base::compare_simd_types(bcx, lhs, rhs, intype, ty::simd_size(tcx, lhs_t), op)
         } else {
@@ -1369,10 +1363,9 @@ fn trans_lazy_binop<'a>(
     let join = fcx.new_id_block("join", binop_expr.id);
     let before_rhs = fcx.new_id_block("before_rhs", b.id);
 
-    let lhs_i1 = bool_to_i1(past_lhs, lhs);
     match op {
-      lazy_and => CondBr(past_lhs, lhs_i1, before_rhs.llbb, join.llbb),
-      lazy_or => CondBr(past_lhs, lhs_i1, join.llbb, before_rhs.llbb)
+      lazy_and => CondBr(past_lhs, lhs, before_rhs.llbb, join.llbb),
+      lazy_or => CondBr(past_lhs, lhs, join.llbb, before_rhs.llbb)
     }
 
     let DatumBlock {bcx: past_rhs, datum: rhs} = trans(before_rhs, b);
index b43b47573b95fa143c230789b96ef4b9a02ed9bd..fcd6c7e293ea26994f3fb183a9b54dcbd65d1612 100644 (file)
@@ -11,7 +11,7 @@
 
 use back::{link};
 use lib::llvm::llvm;
-use lib::llvm::{ValueRef, CallConv, StructRetAttribute, Linkage};
+use lib::llvm::{ValueRef, CallConv, Linkage};
 use lib;
 use middle::weak_lang_items;
 use middle::trans::base::push_ctxt;
@@ -373,18 +373,41 @@ 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`.
+    // any attributes with ABI implications directly to the call instruction.
     let mut attrs = Vec::new();
-    if fn_type.ret_ty.is_indirect() {
-        attrs.push((1, lib::llvm::StructRetAttribute as u64));
 
+    // Add attributes that are always applicable, independent of the concrete foreign ABI
+    if fn_type.ret_ty.is_indirect() {
         // 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 attributes that depend on the concrete foreign ABI
+    let mut arg_idx = if fn_type.ret_ty.is_indirect() { 1 } else { 0 };
+    match fn_type.ret_ty.attr {
+        Some(attr) => attrs.push((arg_idx, attr as u64)),
+        _ => ()
+    }
+
+    arg_idx += 1;
+    for arg_ty in fn_type.arg_tys.iter() {
+        if arg_ty.is_ignore() {
+            continue;
+        }
+        // skip padding
+        if arg_ty.pad.is_some() { arg_idx += 1; }
+
+        match arg_ty.attr {
+            Some(attr) => attrs.push((arg_idx, attr as u64)),
+            _ => {}
+        }
+
+        arg_idx += 1;
+    }
+
     let llforeign_retval = CallWithConv(bcx,
                                         llfn,
                                         llargs_foreign.as_slice(),
@@ -934,22 +957,17 @@ pub fn lltype_for_foreign_fn(ccx: &CrateContext, ty: ty::t) -> Type {
 
 fn add_argument_attributes(tys: &ForeignTypes,
                            llfn: ValueRef) {
-    let mut i = 0;
-
-    if tys.fn_ty.ret_ty.is_indirect() {
-        match tys.fn_ty.ret_ty.attr {
-            Some(attr) => {
-                let llarg = get_param(llfn, i);
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, attr as c_uint);
-                }
-            }
-            None => {}
-        }
+    let mut i = if tys.fn_ty.ret_ty.is_indirect() { 1 } else { 0 };
 
-        i += 1;
+    match tys.fn_ty.ret_ty.attr {
+        Some(attr) => unsafe {
+            llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64);
+        },
+        None => {}
     }
 
+    i += 1;
+
     for &arg_ty in tys.fn_ty.arg_tys.iter() {
         if arg_ty.is_ignore() {
             continue;
@@ -958,12 +976,9 @@ fn add_argument_attributes(tys: &ForeignTypes,
         if arg_ty.pad.is_some() { i += 1; }
 
         match arg_ty.attr {
-            Some(attr) => {
-                let llarg = get_param(llfn, i);
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, attr as c_uint);
-                }
-            }
+            Some(attr) => unsafe {
+                llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64);
+            },
             None => ()
         }
 
index 648a2c335e6860f0121e49840b5272e37953c1bf..bc0c88ceee95fc5866159c067f70773851ad51f5 100644 (file)
@@ -96,19 +96,13 @@ fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) {
         let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
         let llfn = bcx.ccx().get_intrinsic(&name);
 
-        // convert `i1` to a `bool`, and write to the out parameter
         let val = Call(bcx, llfn, [a, b], []);
-        let result = ExtractValue(bcx, val, 0);
-        let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx()));
-        let ret = C_undef(type_of::type_of(bcx.ccx(), t));
-        let ret = InsertValue(bcx, ret, result, 0);
-        let ret = InsertValue(bcx, ret, overflow, 1);
 
         if type_is_immediate(bcx.ccx(), t) {
-            Ret(bcx, ret);
+            Ret(bcx, val);
         } else {
             let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
-            Store(bcx, ret, retptr);
+            Store(bcx, val, retptr);
             RetVoid(bcx);
         }
     }
@@ -235,11 +229,15 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
                     lib::llvm::SequentiallyConsistent =>
                         lib::llvm::SequentiallyConsistent,
                 };
-                let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
+                let res = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
                                         get_param(decl, first_real_arg + 1u),
                                         get_param(decl, first_real_arg + 2u),
                                         order, strongest_failure_ordering);
-                Ret(bcx, old);
+                if unsafe { lib::llvm::llvm::LLVMVersionMinor() >= 5 } {
+                    Ret(bcx, ExtractValue(bcx, res, 0));
+                } else {
+                    Ret(bcx, res);
+                }
             }
             "load" => {
                 let old = AtomicLoad(bcx, get_param(decl, first_real_arg),
index 506817629565e37dc9dad7539219c4e350dfc8f1..59903324e10eaaf2c5c6b2061eb59df0ff6e659d 100644 (file)
@@ -107,7 +107,6 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
                                                          mth_idx,
                                                          v),
             ArgVals(args), None));
-        let result = bool_to_i1(bcx, result);
         let next_bcx = fcx.new_temp_block("next");
         CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb);
         self.bcx = next_bcx
index 5d58500f761a4581044d0af023814b4c5a4391ee..75f884aac34cf28f58e46ac0eaa0d45ca18a26db 100644 (file)
@@ -93,7 +93,7 @@ pub fn f128(ccx: &CrateContext) -> Type {
     }
 
     pub fn bool(ccx: &CrateContext) -> Type {
-        Type::i8(ccx)
+        Type::i1(ccx)
     }
 
     pub fn char(ccx: &CrateContext) -> Type {
index c5e84b8e0c8f01736bce5e0348e970132193fa87..3ef2f7a0480dc7b09ecf18e90ae758f3882c5f34 100644 (file)
@@ -1026,21 +1026,16 @@ pub struct ParameterEnvironment {
 
 /// A polytype.
 ///
-/// - `bounds`: The list of bounds for each type parameter.  The length of the
-///   list also tells you how many type parameters there are.
-///
-/// - `rp`: true if the type is region-parameterized.  Types can have at
-///   most one region parameter, always called `&self`.
-///
-/// - `ty`: the base type.  May have reference to the (unsubstituted) bound
-///   region `&self` or to (unsubstituted) ty_param types
+/// - `generics`: the set of type parameters and their bounds
+/// - `ty`: the base types, which may reference the parameters defined
+///   in `generics`
 #[deriving(Clone)]
-pub struct ty_param_bounds_and_ty {
+pub struct Polytype {
     pub generics: Generics,
     pub ty: t
 }
 
-/// As `ty_param_bounds_and_ty` but for a trait ref.
+/// As `Polytype` but for a trait ref.
 pub struct TraitDef {
     pub generics: Generics,
     pub bounds: BuiltinBounds,
@@ -1054,12 +1049,7 @@ pub struct ItemSubsts {
     pub substs: Substs,
 }
 
-pub struct ty_param_substs_and_ty {
-    pub substs: Substs,
-    pub ty: ty::t
-}
-
-pub type type_cache = RefCell<DefIdMap<ty_param_bounds_and_ty>>;
+pub type type_cache = RefCell<DefIdMap<Polytype>>;
 
 pub type node_type_table = RefCell<HashMap<uint,t>>;
 
@@ -3848,7 +3838,7 @@ pub fn enum_variant_with_id(cx: &ctxt,
 // the type cache. Returns the type parameters and type.
 pub fn lookup_item_type(cx: &ctxt,
                         did: ast::DefId)
-                     -> ty_param_bounds_and_ty {
+                     -> Polytype {
     lookup_locally_or_in_crate_store(
         "tcache", did, &mut *cx.tcache.borrow_mut(),
         || csearch::get_type(cx, did))
@@ -3946,7 +3936,7 @@ pub fn lookup_field_type(tcx: &ctxt,
     } else {
         let mut tcache = tcx.tcache.borrow_mut();
         match tcache.find(&id) {
-           Some(&ty_param_bounds_and_ty {ty, ..}) => ty,
+           Some(&Polytype {ty, ..}) => ty,
            None => {
                let tpt = csearch::get_field_type(tcx, struct_id, id);
                tcache.insert(id, tpt.clone());
index 2488d2da779b30c1b61cd8345d43c29fb11180bc..c90d9af9b78eb962ba4b974c6e9a8f7958d8104b 100644 (file)
@@ -15,6 +15,7 @@
 use middle::ty;
 use middle::typeck;
 use std::rc::Rc;
+use syntax::ast;
 use syntax::owned_slice::OwnedSlice;
 use util::ppaux::Repr;
 
@@ -449,10 +450,23 @@ fn fold_ty(&mut self, ty: ty::t) -> ty::t {
 ///////////////////////////////////////////////////////////////////////////
 // Region folder
 
+/// Folds over the substructure of a type, visiting its component
+/// types and all regions that occur *free* within it.
+///
+/// That is, `ty::t` can contain function or method types that bind
+/// regions at the call site (`ReLateBound`), and occurrences of
+/// regions (aka "lifetimes") that are bound within a type are not
+/// visited by this folder; only regions that occur free will be
+/// visited by `fld_r`.
+///
+/// (The distinction between "free" and "bound" is represented by
+/// keeping track of each `FnSig` in the lexical context of the
+/// current position of the fold.)
 pub struct RegionFolder<'a> {
     tcx: &'a ty::ctxt,
     fld_t: |ty::t|: 'a -> ty::t,
     fld_r: |ty::Region|: 'a -> ty::Region,
+    within_binder_ids: Vec<ast::NodeId>,
 }
 
 impl<'a> RegionFolder<'a> {
@@ -463,7 +477,8 @@ pub fn general(tcx: &'a ty::ctxt,
         RegionFolder {
             tcx: tcx,
             fld_t: fld_t,
-            fld_r: fld_r
+            fld_r: fld_r,
+            within_binder_ids: vec![],
         }
     }
 
@@ -474,22 +489,53 @@ fn noop(t: ty::t) -> ty::t { t }
         RegionFolder {
             tcx: tcx,
             fld_t: noop,
-            fld_r: fld_r
+            fld_r: fld_r,
+            within_binder_ids: vec![],
         }
     }
 }
 
+/// If `ty` has `FnSig` (i.e. closure or fn), return its binder_id;
+/// else None.
+fn opt_binder_id_of_function(t: ty::t) -> Option<ast::NodeId> {
+    match ty::get(t).sty {
+        ty::ty_closure(ref f) => Some(f.sig.binder_id),
+        ty::ty_bare_fn(ref f) => Some(f.sig.binder_id),
+        _                     => None,
+    }
+}
+
 impl<'a> TypeFolder for RegionFolder<'a> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
 
     fn fold_ty(&mut self, ty: ty::t) -> ty::t {
         debug!("RegionFolder.fold_ty({})", ty.repr(self.tcx()));
+        let opt_binder_id = opt_binder_id_of_function(ty);
+        match opt_binder_id {
+            Some(binder_id) => self.within_binder_ids.push(binder_id),
+            None => {}
+        }
+
         let t1 = super_fold_ty(self, ty);
-        (self.fld_t)(t1)
+        let ret = (self.fld_t)(t1);
+
+        if opt_binder_id.is_some() {
+            self.within_binder_ids.pop();
+        }
+
+        ret
     }
 
     fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        debug!("RegionFolder.fold_region({})", r.repr(self.tcx()));
-        (self.fld_r)(r)
+        match r {
+            ty::ReLateBound(binder_id, _) if self.within_binder_ids.contains(&binder_id) => {
+                debug!("RegionFolder.fold_region({}) skipped bound region", r.repr(self.tcx()));
+                r
+            }
+            _ => {
+                debug!("RegionFolder.fold_region({}) folding free region", r.repr(self.tcx()));
+                (self.fld_r)(r)
+            }
+        }
     }
 }
index 7ca8a74ae636c4ef18bb27a959adb2e8ca5424dc..4bf32d15e6424fc1a4a0e725259eb5b02ebcb0c4 100644 (file)
 use middle::def;
 use middle::lang_items::FnMutTraitLangItem;
 use rl = middle::resolve_lifetime;
-use middle::subst::{Subst, Substs};
-use middle::subst;
-use middle::ty::ty_param_substs_and_ty;
+use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
 use middle::ty;
+use middle::typeck::TypeAndSubsts;
 use middle::typeck::lookup_def_tcx;
 use middle::typeck::rscope::RegionScope;
 use middle::typeck::rscope;
@@ -71,7 +70,7 @@
 
 pub trait AstConv {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt;
-    fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty;
+    fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype;
     fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef>;
 
     // what type should we use when a type is omitted?
@@ -154,7 +153,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     rscope: &RS,
     decl_generics: &ty::Generics,
     self_ty: Option<ty::t>,
-    path: &ast::Path) -> subst::Substs
+    path: &ast::Path) -> Substs
 {
     /*!
      * Given a path `path` that refers to an item `I` with the
@@ -172,13 +171,13 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     // Note: in the case of traits, the self parameter is also
     // defined, but we don't currently create a `type_param_def` for
     // `Self` because it is implicit.
-    assert!(decl_generics.regions.all(|d| d.space == subst::TypeSpace));
-    assert!(decl_generics.types.all(|d| d.space != subst::FnSpace));
+    assert!(decl_generics.regions.all(|d| d.space == TypeSpace));
+    assert!(decl_generics.types.all(|d| d.space != FnSpace));
 
     // If the type is parameterized by the this region, then replace this
     // region with the current anon region binding (in other words,
     // whatever & would get replaced with).
-    let expected_num_region_params = decl_generics.regions.len(subst::TypeSpace);
+    let expected_num_region_params = decl_generics.regions.len(TypeSpace);
     let supplied_num_region_params = path.segments.last().unwrap().lifetimes.len();
     let regions = if expected_num_region_params == supplied_num_region_params {
         path.segments.last().unwrap().lifetimes.iter().map(
@@ -204,7 +203,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     };
 
     // Convert the type parameters supplied by the user.
-    let ty_param_defs = decl_generics.types.get_vec(subst::TypeSpace);
+    let ty_param_defs = decl_generics.types.get_vec(TypeSpace);
     let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
     let formal_ty_param_count = ty_param_defs.len();
     let required_ty_param_count = ty_param_defs.iter()
@@ -246,7 +245,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
                             .map(|a_t| ast_ty_to_ty(this, rscope, &**a_t))
                             .collect();
 
-    let mut substs = subst::Substs::new_type(tps, regions);
+    let mut substs = Substs::new_type(tps, regions);
 
     match self_ty {
         None => {
@@ -258,14 +257,14 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
             // "declared" (in other words, this should be a
             // trait-ref).
             assert!(decl_generics.types.get_self().is_some());
-            substs.types.push(subst::SelfSpace, ty);
+            substs.types.push(SelfSpace, ty);
         }
     }
 
     for param in ty_param_defs.slice_from(supplied_ty_param_count).iter() {
         let default = param.default.unwrap();
         let default = default.subst_spanned(tcx, &substs, Some(path.span));
-        substs.types.push(subst::TypeSpace, default);
+        substs.types.push(TypeSpace, default);
     }
 
     substs
@@ -289,17 +288,17 @@ pub fn ast_path_to_ty<AC:AstConv,RS:RegionScope>(
         rscope: &RS,
         did: ast::DefId,
         path: &ast::Path)
-     -> ty_param_substs_and_ty
+     -> TypeAndSubsts
 {
     let tcx = this.tcx();
-    let ty::ty_param_bounds_and_ty {
+    let ty::Polytype {
         generics: generics,
         ty: decl_ty
     } = this.get_item_ty(did);
 
     let substs = ast_path_substs(this, rscope, &generics, None, path);
     let ty = decl_ty.subst(tcx, &substs);
-    ty_param_substs_and_ty { substs: substs, ty: ty }
+    TypeAndSubsts { substs: substs, ty: ty }
 }
 
 pub static NO_REGIONS: uint = 1;
@@ -547,11 +546,11 @@ pub fn trait_ref_for_unboxed_function<AC:AstConv,
     let output_type = ast_ty_to_ty(this,
                                    rscope,
                                    &*unboxed_function.decl.output);
-    let mut substs = subst::Substs::new_type(vec!(input_tuple, output_type),
+    let mut substs = Substs::new_type(vec!(input_tuple, output_type),
                                              Vec::new());
 
     match self_ty {
-        Some(s) => substs.types.push(subst::SelfSpace, s),
+        Some(s) => substs.types.push(SelfSpace, s),
         None => ()
     }
 
index e198653165a61a5e1216ae67cd66ee83a7e9e766..67437da44c5d612d4ab6e76318e9bae24f48a9b1 100644 (file)
@@ -133,10 +133,10 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
             match v_def.variant_def_ids() {
                 Some((enm, var)) => {
                     // Assign the pattern the type of the *enum*, not the variant.
-                    let enum_tpt = ty::lookup_item_type(tcx, enm);
+                    let enum_pty = ty::lookup_item_type(tcx, enm);
                     instantiate_path(pcx.fcx,
                                      path,
-                                     enum_tpt,
+                                     enum_pty,
                                      v_def,
                                      pat.span,
                                      pat.id);
@@ -190,16 +190,16 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
             let s_def_id = s_def.def_id();
 
             // Assign the pattern the type of the struct.
-            let ctor_tpt = ty::lookup_item_type(tcx, s_def_id);
-            let struct_tpt = if ty::is_fn_ty(ctor_tpt.ty) {
-                ty::ty_param_bounds_and_ty {ty: ty::ty_fn_ret(ctor_tpt.ty),
-                                        ..ctor_tpt}
+            let ctor_pty = ty::lookup_item_type(tcx, s_def_id);
+            let struct_pty = if ty::is_fn_ty(ctor_pty.ty) {
+                ty::Polytype {ty: ty::ty_fn_ret(ctor_pty.ty),
+                              ..ctor_pty}
             } else {
-                ctor_tpt
+                ctor_pty
             };
             instantiate_path(pcx.fcx,
                              path,
-                             struct_tpt,
+                             struct_pty,
                              s_def,
                              pat.span,
                              pat.id);
@@ -478,9 +478,9 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
       ast::PatEnum(..) |
       ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
         let const_did = tcx.def_map.borrow().get_copy(&pat.id).def_id();
-        let const_tpt = ty::lookup_item_type(tcx, const_did);
-        demand::suptype(fcx, pat.span, expected, const_tpt.ty);
-        fcx.write_ty(pat.id, const_tpt.ty);
+        let const_pty = ty::lookup_item_type(tcx, const_did);
+        demand::suptype(fcx, pat.span, expected, const_pty.ty);
+        fcx.write_ty(pat.id, const_pty.ty);
       }
       ast::PatIdent(bm, ref name, sub) if pat_is_binding(&tcx.def_map, pat) => {
         let typ = fcx.local_ty(pat.span, pat.id);
@@ -726,22 +726,38 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
 }
 
 // Helper function to check gc, box and & patterns
-pub fn check_pointer_pat(pcx: &pat_ctxt,
-                         pointer_kind: PointerKind,
-                         inner: &ast::Pat,
-                         pat_id: ast::NodeId,
-                         span: Span,
-                         expected: ty::t) {
+fn check_pointer_pat(pcx: &pat_ctxt,
+                     pointer_kind: PointerKind,
+                     inner: &ast::Pat,
+                     pat_id: ast::NodeId,
+                     span: Span,
+                     expected: ty::t) {
     let fcx = pcx.fcx;
+    let tcx = fcx.ccx.tcx;
     let check_inner: |ty::t| = |e_inner| {
-        check_pat(pcx, inner, e_inner);
-        fcx.write_ty(pat_id, expected);
+        match ty::get(e_inner).sty {
+            ty::ty_trait(_) if pat_is_binding(&tcx.def_map, inner) => {
+                // This is "x = SomeTrait" being reduced from
+                // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
+                check_pat(pcx, inner, ty::mk_err());
+                tcx.sess.span_err(
+                    span,
+                    format!("type `{}` cannot be dereferenced",
+                            fcx.infcx().ty_to_str(expected)).as_slice());
+                fcx.write_error(pat_id);
+            }
+            _ => {
+                check_pat(pcx, inner, e_inner);
+                fcx.write_ty(pat_id, expected);
+            }
+        }
     };
+
     match *structure_of(fcx, span, expected) {
-        ty::ty_uniq(e_inner) if pointer_kind == Send && !ty::type_is_trait(e_inner) => {
+        ty::ty_uniq(e_inner) if pointer_kind == Send => {
             check_inner(e_inner);
         }
-        ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed && !ty::type_is_trait(e_inner.ty) => {
+        ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
             check_inner(e_inner.ty);
         }
         _ => {
index fafc84d2b10f08fce2b97a8559ef541d954551b9..4270ff1e7952d450967f652e4d4f29f616789059 100644 (file)
@@ -93,6 +93,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
 use middle::typeck::{MethodStatic, MethodObject};
 use middle::typeck::{param_index};
 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
+use middle::typeck::TypeAndSubsts;
 use util::common::indenter;
 use util::ppaux;
 use util::ppaux::Repr;
@@ -688,7 +689,7 @@ fn push_candidates_from_impl(&mut self,
         // variables for each parameter:
         let span = self.self_expr.map_or(self.span, |e| e.span);
         let vcx = self.fcx.vtable_context();
-        let ty::ty_param_substs_and_ty {
+        let TypeAndSubsts {
             substs: impl_substs,
             ty: impl_ty
         } = impl_self_ty(&vcx, span, impl_did);
index 7b16248c2e6a2f2518e59896a37b6c73dd0ccae9..1c5cfc45afdb80061d77729245512533794b4ad2 100644 (file)
@@ -85,7 +85,7 @@
 use middle::subst;
 use middle::subst::{Subst, Substs, VecPerParamSpace, ParamSpace};
 use middle::ty::{FnSig, VariantInfo};
-use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
+use middle::ty::{Polytype};
 use middle::ty::{ParamTy, Disr, ExprTyProvider};
 use middle::ty;
 use middle::ty_fold::TypeFolder;
 use middle::typeck::no_params;
 use middle::typeck::{require_same_types, vtable_map};
 use middle::typeck::{MethodCall, MethodMap};
+use middle::typeck::{TypeAndSubsts};
 use middle::lang_items::TypeIdLangItem;
 use util::common::{block_query, indenter, loop_query};
 use util::ppaux;
@@ -644,20 +645,20 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
                             it.id);
       }
       ast::ItemFn(ref decl, _, _, _, ref body) => {
-        let fn_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
+        let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
 
         let param_env = ty::construct_parameter_environment(ccx.tcx,
-                                                            &fn_tpt.generics,
+                                                            &fn_pty.generics,
                                                             body.id);
 
-        check_bare_fn(ccx, &**decl, &**body, it.id, fn_tpt.ty, param_env);
+        check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
       }
       ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
         debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
 
-        let impl_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
+        let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
         for m in ms.iter() {
-            check_method_body(ccx, &impl_tpt.generics, &**m);
+            check_method_body(ccx, &impl_pty.generics, &**m);
         }
 
         match *opt_trait_ref {
@@ -669,7 +670,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
                                              ast_trait_ref,
                                              &*impl_trait_ref,
                                              ms.as_slice());
-                vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, &*impl_trait_ref);
+                vtable::resolve_impl(ccx.tcx, it, &impl_pty.generics, &*impl_trait_ref);
             }
             None => { }
         }
@@ -693,8 +694,8 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
         check_struct(ccx, it.id, it.span);
       }
       ast::ItemTy(ref t, ref generics) => {
-        let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);
-        check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty);
+        let pty_ty = ty::node_id_to_type(ccx.tcx, it.id);
+        check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
       }
       ast::ItemForeignMod(ref m) => {
         if m.abi == abi::RustIntrinsic {
@@ -703,8 +704,8 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
             }
         } else {
             for item in m.items.iter() {
-                let tpt = ty::lookup_item_type(ccx.tcx, local_def(item.id));
-                if !tpt.generics.types.is_empty() {
+                let pty = ty::lookup_item_type(ccx.tcx, local_def(item.id));
+                if !pty.generics.types.is_empty() {
                     ccx.tcx.sess.span_err(item.span, "foreign items may not have type parameters");
                 }
 
@@ -1048,7 +1049,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
 impl<'a> AstConv for FnCtxt<'a> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.ccx.tcx }
 
-    fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
+    fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
         ty::lookup_item_type(self.tcx(), id)
     }
 
@@ -1791,7 +1792,7 @@ fn check_expr_with_lvalue_pref(fcx: &FnCtxt, expr: &ast::Expr,
 pub fn impl_self_ty(vcx: &VtableContext,
                     span: Span, // (potential) receiver for this impl
                     did: ast::DefId)
-                 -> ty_param_substs_and_ty {
+                    -> TypeAndSubsts {
     let tcx = vcx.tcx();
 
     let ity = ty::lookup_item_type(tcx, did);
@@ -1805,7 +1806,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
     let substs = subst::Substs::new_type(tps, rps);
     let substd_ty = raw_ty.subst(tcx, &substs);
 
-    ty_param_substs_and_ty { substs: substs, ty: substd_ty }
+    TypeAndSubsts { substs: substs, ty: substd_ty }
 }
 
 // Only for fields! Returns <none> for methods>
@@ -2651,7 +2652,7 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
                     let error = if vst == ast::ExprVstoreSlice {
                         "`&\"string\"` has been removed; use `\"string\"` instead"
                     } else {
-                        "`~\"string\"` has been removed; use `\"string\".to_string()` instead"
+                        "`box \"string\"` has been removed; use `\"string\".to_string()` instead"
                     };
                     tcx.sess.span_err(expr.span, error);
                     ty::mk_err()
@@ -2855,8 +2856,8 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
       }
       ast::ExprPath(ref pth) => {
         let defn = lookup_def(fcx, pth.span, id);
-        let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
-        instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
+        let pty = polytype_for_def(fcx, expr.span, defn);
+        instantiate_path(fcx, pth, pty, defn, expr.span, expr.id);
       }
       ast::ExprInlineAsm(ref ia) => {
           for &(_, ref input) in ia.inputs.iter() {
@@ -3751,10 +3752,10 @@ pub fn lookup_def(fcx: &FnCtxt, sp: Span, id: ast::NodeId) -> def::Def {
 }
 
 // Returns the type parameter count and the type for the given definition.
-pub fn ty_param_bounds_and_ty_for_def(fcx: &FnCtxt,
-                                      sp: Span,
-                                      defn: def::Def)
-                                   -> ty_param_bounds_and_ty {
+pub fn polytype_for_def(fcx: &FnCtxt,
+                        sp: Span,
+                        defn: def::Def)
+                        -> Polytype {
     match defn {
       def::DefArg(nid, _) | def::DefLocal(nid, _) |
       def::DefBinding(nid, _) => {
@@ -3767,7 +3768,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: &FnCtxt,
         return ty::lookup_item_type(fcx.ccx.tcx, id);
       }
       def::DefUpvar(_, inner, _, _) => {
-        return ty_param_bounds_and_ty_for_def(fcx, sp, *inner);
+        return polytype_for_def(fcx, sp, *inner);
       }
       def::DefTrait(_) |
       def::DefTy(_) |
@@ -3803,7 +3804,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: &FnCtxt,
 // number of type parameters and type.
 pub fn instantiate_path(fcx: &FnCtxt,
                         path: &ast::Path,
-                        polytype: ty_param_bounds_and_ty,
+                        polytype: Polytype,
                         def: def::Def,
                         span: Span,
                         node_id: ast::NodeId) {
index 6ac6cdce8590d32ad33927870a2c21c508c5f7f3..7e118291f345dd297aeb6d7bd8298f10359cafa9 100644 (file)
@@ -23,6 +23,7 @@
 use middle::typeck::{vtable_static, vtable_param, vtable_error};
 use middle::typeck::{param_index};
 use middle::typeck::MethodCall;
+use middle::typeck::TypeAndSubsts;
 use middle::subst;
 use middle::subst::{Subst, VecPerParamSpace};
 use util::common::indenter;
@@ -353,7 +354,7 @@ fn search_for_vtable(vcx: &VtableContext,
         // FIXME: document a bit more what this means
         //
         // FIXME(#5781) this should be mk_eqty not mk_subty
-        let ty::ty_param_substs_and_ty {
+        let TypeAndSubsts {
             substs: substs,
             ty: for_ty
         } = impl_self_ty(vcx, span, impl_did);
index b12e3b614d1be1dd9da7aa0d1244600390b519d4..cbd1479ef0930310acea44ac74c15d2f9ec1ba44 100644 (file)
@@ -23,7 +23,7 @@
 use middle::ty::{ImplContainer, lookup_item_type};
 use middle::ty::{t, ty_bool, ty_char, ty_bot, ty_box, ty_enum, ty_err};
 use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil};
-use middle::ty::{ty_param, ty_param_bounds_and_ty, ty_ptr};
+use middle::ty::{ty_param, Polytype, ty_ptr};
 use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
 use middle::ty::{ty_uint, ty_uniq, ty_bare_fn, ty_closure};
 use middle::ty::type_is_ty_var;
@@ -378,7 +378,7 @@ fn instantiate_default_methods(&self,
             // construct the polytype for the method based on the
             // method_ty.  it will have all the generics from the
             // impl, plus its own.
-            let new_polytype = ty::ty_param_bounds_and_ty {
+            let new_polytype = ty::Polytype {
                 generics: new_method_ty.generics.clone(),
                 ty: ty::mk_bare_fn(tcx, new_method_ty.fty.clone())
             };
@@ -487,8 +487,8 @@ fn iter_impls_of_trait_local(&self, trait_def_id: DefId, f: |DefId|) {
     }
 
     fn polytypes_unify(&self,
-                       polytype_a: ty_param_bounds_and_ty,
-                       polytype_b: ty_param_bounds_and_ty)
+                       polytype_a: Polytype,
+                       polytype_b: Polytype)
                        -> bool {
         let universally_quantified_a =
             self.universally_quantify_polytype(polytype_a);
@@ -503,7 +503,7 @@ fn polytypes_unify(&self,
 
     // Converts a polytype to a monotype by replacing all parameters with
     // type variables. Returns the monotype and the type variables created.
-    fn universally_quantify_polytype(&self, polytype: ty_param_bounds_and_ty)
+    fn universally_quantify_polytype(&self, polytype: Polytype)
                                      -> UniversalQuantificationResult
     {
         let substitutions =
@@ -526,7 +526,7 @@ fn can_unify_universally_quantified<'a>(&self,
     }
 
     fn get_self_type_for_implementation(&self, impl_did: DefId)
-                                        -> ty_param_bounds_and_ty {
+                                        -> Polytype {
         self.crate_context.tcx.tcache.borrow().get_copy(&impl_did)
     }
 
@@ -748,7 +748,7 @@ pub fn make_substs_for_receiver_types(tcx: &ty::ctxt,
 
 fn subst_receiver_types_in_method_ty(tcx: &ty::ctxt,
                                      impl_id: ast::DefId,
-                                     impl_poly_type: &ty::ty_param_bounds_and_ty,
+                                     impl_poly_type: &ty::Polytype,
                                      trait_ref: &ty::TraitRef,
                                      new_def_id: ast::DefId,
                                      method: &ty::Method,
index 55969b79b5241472860ccb652a7eea67a0fcb1fc..bf88ec5c438f28a62e3d52f61327a2b1dbb2b6af 100644 (file)
@@ -24,9 +24,9 @@
 that they are generic types that may have type parameters (more
 mathematically phrased, they are universally quantified over a set of
 type parameters).  Polytypes are represented by an instance of
-`ty::ty_param_bounds_and_ty`.  This combines the core type along with
-a list of the bounds for each parameter.  Type parameters themselves
-are represented as `ty_param()` instances.
+`ty::Polytype`.  This combines the core type along with a list of the
+bounds for each parameter.  Type parameters themselves are represented
+as `ty_param()` instances.
 
 */
 
@@ -38,7 +38,7 @@
 use middle::subst;
 use middle::subst::{Substs};
 use middle::ty::{ImplContainer, MethodContainer, TraitContainer};
-use middle::ty::{ty_param_bounds_and_ty};
+use middle::ty::{Polytype};
 use middle::ty;
 use middle::typeck::astconv::{AstConv, ty_of_arg};
 use middle::typeck::astconv::{ast_ty_to_ty};
@@ -84,7 +84,7 @@ fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
 pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
     fn collect_intrinsic_type(ccx: &CrateCtxt,
                               lang_item: ast::DefId) {
-        let ty::ty_param_bounds_and_ty { ty: ty, .. } =
+        let ty::Polytype { ty: ty, .. } =
             ccx.get_item_ty(lang_item);
         ccx.tcx.intrinsic_defs.borrow_mut().insert(lang_item, ty);
     }
@@ -113,7 +113,7 @@ fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &ast::Ty) -> ty::t {
 impl<'a> AstConv for CrateCtxt<'a> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
 
-    fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
+    fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
         if id.krate != ast::LOCAL_CRATE {
             return csearch::get_type(self.tcx, id)
         }
@@ -167,12 +167,12 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
             }
 
             ast::StructVariantKind(struct_def) => {
-                let tpt = ty_param_bounds_and_ty {
+                let pty = Polytype {
                     generics: ty_generics_for_type(ccx, generics),
                     ty: enum_ty
                 };
 
-                convert_struct(ccx, &*struct_def, tpt, variant.node.id);
+                convert_struct(ccx, &*struct_def, pty, variant.node.id);
 
                 let input_tys: Vec<_> = struct_def.fields.iter().map(
                     |f| ty::node_id_to_type(ccx.tcx, f.node.id)).collect();
@@ -180,12 +180,12 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
             }
         };
 
-        let tpt = ty_param_bounds_and_ty {
+        let pty = Polytype {
             generics: ty_generics_for_type(ccx, generics),
             ty: result_ty
         };
 
-        tcx.tcache.borrow_mut().insert(local_def(variant.node.id), tpt);
+        tcx.tcache.borrow_mut().insert(local_def(variant.node.id), pty);
 
         write_ty_to_tcx(tcx, variant.node.id, result_ty);
     }
@@ -251,7 +251,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
     fn make_static_method_ty(ccx: &CrateCtxt, m: &ty::Method) {
         ccx.tcx.tcache.borrow_mut().insert(
             m.def_id,
-            ty_param_bounds_and_ty {
+            Polytype {
                 generics: m.generics.clone(),
                 ty: ty::mk_bare_fn(ccx.tcx, m.fty.clone()) });
     }
@@ -295,7 +295,7 @@ pub fn convert_field(ccx: &CrateCtxt,
     write_ty_to_tcx(ccx.tcx, v.node.id, tt);
     /* add the field to the tcache */
     ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id),
-                                       ty::ty_param_bounds_and_ty {
+                                       ty::Polytype {
                                            generics: struct_generics.clone(),
                                            ty: tt
                                        });
@@ -347,7 +347,7 @@ fn convert_methods(ccx: &CrateCtxt,
                 fty.repr(ccx.tcx));
         tcx.tcache.borrow_mut().insert(
             local_def(m.id),
-            ty_param_bounds_and_ty {
+            Polytype {
                 generics: mty.generics.clone(),
                 ty: fty
             });
@@ -422,10 +422,10 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
         ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
         ast::ItemEnum(ref enum_definition, ref generics) => {
             ensure_no_ty_param_bounds(ccx, it.span, generics, "enumeration");
-            let tpt = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, tpt.ty);
+            let pty = ty_of_item(ccx, it);
+            write_ty_to_tcx(tcx, it.id, pty.ty);
             get_enum_variant_types(ccx,
-                                   tpt.ty,
+                                   pty.ty,
                                    enum_definition.variants.as_slice(),
                                    generics);
         },
@@ -435,7 +435,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
             write_ty_to_tcx(tcx, it.id, selfty);
 
             tcx.tcache.borrow_mut().insert(local_def(it.id),
-                                ty_param_bounds_and_ty {
+                                Polytype {
                                     generics: ty_generics.clone(),
                                     ty: selfty});
 
@@ -484,10 +484,10 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
             ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");
 
             // Write the class type.
-            let tpt = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, tpt.ty);
+            let pty = ty_of_item(ccx, it);
+            write_ty_to_tcx(tcx, it.id, pty.ty);
 
-            tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
+            tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
 
             // Write the super-struct type, if it exists.
             match struct_def.super_struct {
@@ -498,38 +498,38 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                 _ => {},
             }
 
-            convert_struct(ccx, &*struct_def, tpt, it.id);
+            convert_struct(ccx, &*struct_def, pty, it.id);
         },
         ast::ItemTy(_, ref generics) => {
             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
-            let tpt = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, tpt.ty);
+            let pty = ty_of_item(ccx, it);
+            write_ty_to_tcx(tcx, it.id, pty.ty);
         },
         ast::ItemFn(_, _, abi, ref generics, _) => {
             ensure_generics_abi(ccx, it.span, abi, generics);
-            let tpt = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, tpt.ty);
+            let pty = ty_of_item(ccx, it);
+            write_ty_to_tcx(tcx, it.id, pty.ty);
         },
         _ => {
             // This call populates the type cache with the converted type
             // of the item in passing. All we have to do here is to write
             // it into the node type table.
-            let tpt = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, tpt.ty);
+            let pty = ty_of_item(ccx, it);
+            write_ty_to_tcx(tcx, it.id, pty.ty);
         },
     }
 }
 
 pub fn convert_struct(ccx: &CrateCtxt,
                       struct_def: &ast::StructDef,
-                      tpt: ty::ty_param_bounds_and_ty,
+                      pty: ty::Polytype,
                       id: ast::NodeId) {
     let tcx = ccx.tcx;
 
     // Write the type of each of the members and check for duplicate fields.
     let mut seen_fields: HashMap<ast::Name, Span> = HashMap::new();
     let field_tys = struct_def.fields.iter().map(|f| {
-        let result = convert_field(ccx, &tpt.generics, f, local_def(id));
+        let result = convert_field(ccx, &pty.generics, f, local_def(id));
 
         if result.name != special_idents::unnamed_field.name {
             let dup = match seen_fields.find(&result.name) {
@@ -589,7 +589,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
     };
     tcx.superstructs.borrow_mut().insert(local_def(id), super_struct);
 
-    let substs = mk_item_substs(ccx, &tpt.generics);
+    let substs = mk_item_substs(ccx, &pty.generics);
     let selfty = ty::mk_struct(tcx, local_def(id), substs);
 
     // If this struct is enum-like or tuple-like, create the type of its
@@ -601,7 +601,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
                 // Enum-like.
                 write_ty_to_tcx(tcx, ctor_id, selfty);
 
-                tcx.tcache.borrow_mut().insert(local_def(ctor_id), tpt);
+                tcx.tcache.borrow_mut().insert(local_def(ctor_id), pty);
             } else if struct_def.fields.get(0).node.kind.is_unnamed() {
                 // Tuple-like.
                 let inputs: Vec<_> = struct_def.fields.iter().map(
@@ -613,8 +613,8 @@ pub fn convert_struct(ccx: &CrateCtxt,
                                                 selfty);
                 write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
                 tcx.tcache.borrow_mut().insert(local_def(ctor_id),
-                                  ty_param_bounds_and_ty {
-                    generics: tpt.generics,
+                                  Polytype {
+                    generics: pty.generics,
                     ty: ctor_fn_ty
                 });
             }
@@ -633,10 +633,10 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::ForeignItem) {
     // convenient way to extract the ABI. - ndm
     let abi = ccx.tcx.map.get_foreign_abi(i.id);
 
-    let tpt = ty_of_foreign_item(ccx, i, abi);
-    write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
+    let pty = ty_of_foreign_item(ccx, i, abi);
+    write_ty_to_tcx(ccx.tcx, i.id, pty.ty);
 
-    ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), tpt);
+    ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), pty);
 }
 
 pub fn instantiate_trait_ref(ccx: &CrateCtxt,
@@ -814,20 +814,20 @@ fn ensure_supertraits(ccx: &CrateCtxt,
 }
 
 pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
-                  -> ty::ty_param_bounds_and_ty {
+                  -> ty::Polytype {
     let def_id = local_def(it.id);
     let tcx = ccx.tcx;
     match tcx.tcache.borrow().find(&def_id) {
-        Some(tpt) => return tpt.clone(),
+        Some(pty) => return pty.clone(),
         _ => {}
     }
     match it.node {
         ast::ItemStatic(t, _, _) => {
             let typ = ccx.to_ty(&ExplicitRscope, &*t);
-            let tpt = no_params(typ);
+            let pty = no_params(typ);
 
-            tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
-            return tpt;
+            tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+            return pty;
         }
         ast::ItemFn(decl, fn_style, abi, ref generics, _) => {
             let ty_generics = ty_generics_for_fn_or_method(ccx, generics,
@@ -837,47 +837,47 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
                                               fn_style,
                                               abi,
                                               &*decl);
-            let tpt = ty_param_bounds_and_ty {
+            let pty = Polytype {
                 generics: ty_generics,
                 ty: ty::mk_bare_fn(ccx.tcx, tofd)
             };
             debug!("type of {} (id {}) is {}",
                     token::get_ident(it.ident),
                     it.id,
-                    ppaux::ty_to_str(tcx, tpt.ty));
+                    ppaux::ty_to_str(tcx, pty.ty));
 
-            ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
-            return tpt;
+            ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+            return pty;
         }
         ast::ItemTy(t, ref generics) => {
             match tcx.tcache.borrow_mut().find(&local_def(it.id)) {
-                Some(tpt) => return tpt.clone(),
+                Some(pty) => return pty.clone(),
                 None => { }
             }
 
-            let tpt = {
+            let pty = {
                 let ty = ccx.to_ty(&ExplicitRscope, &*t);
-                ty_param_bounds_and_ty {
+                Polytype {
                     generics: ty_generics_for_type(ccx, generics),
                     ty: ty
                 }
             };
 
-            tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
-            return tpt;
+            tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+            return pty;
         }
         ast::ItemEnum(_, ref generics) => {
             // Create a new generic polytype.
             let ty_generics = ty_generics_for_type(ccx, generics);
             let substs = mk_item_substs(ccx, &ty_generics);
             let t = ty::mk_enum(tcx, local_def(it.id), substs);
-            let tpt = ty_param_bounds_and_ty {
+            let pty = Polytype {
                 generics: ty_generics,
                 ty: t
             };
 
-            tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
-            return tpt;
+            tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+            return pty;
         }
         ast::ItemTrait(..) => {
             tcx.sess.span_bug(it.span, "invoked ty_of_item on trait");
@@ -886,13 +886,13 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
             let ty_generics = ty_generics_for_type(ccx, generics);
             let substs = mk_item_substs(ccx, &ty_generics);
             let t = ty::mk_struct(tcx, local_def(it.id), substs);
-            let tpt = ty_param_bounds_and_ty {
+            let pty = Polytype {
                 generics: ty_generics,
                 ty: t
             };
 
-            tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
-            return tpt;
+            tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
+            return pty;
         }
         ast::ItemImpl(..) | ast::ItemMod(_) |
         ast::ItemForeignMod(_) | ast::ItemMac(_) => fail!(),
@@ -901,7 +901,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
 
 pub fn ty_of_foreign_item(ccx: &CrateCtxt,
                           it: &ast::ForeignItem,
-                          abi: abi::Abi) -> ty::ty_param_bounds_and_ty
+                          abi: abi::Abi) -> ty::Polytype
 {
     match it.node {
         ast::ForeignItemFn(fn_decl, ref generics) => {
@@ -912,7 +912,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
                                   abi)
         }
         ast::ForeignItemStatic(t, _) => {
-            ty::ty_param_bounds_and_ty {
+            ty::Polytype {
                 generics: ty::Generics::empty(),
                 ty: ast_ty_to_ty(ccx, &ExplicitRscope, &*t)
             }
@@ -1158,7 +1158,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
                              def_id: ast::DefId,
                              ast_generics: &ast::Generics,
                              abi: abi::Abi)
-                          -> ty::ty_param_bounds_and_ty {
+                          -> ty::Polytype {
 
     for i in decl.inputs.iter() {
         match (*i).pat.node {
@@ -1190,13 +1190,13 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
                             output: output_ty,
                             variadic: decl.variadic}
         });
-    let tpt = ty_param_bounds_and_ty {
+    let pty = Polytype {
         generics: ty_generics_for_fn_or_method,
         ty: t_fn
     };
 
-    ccx.tcx.tcache.borrow_mut().insert(def_id, tpt.clone());
-    return tpt;
+    ccx.tcx.tcache.borrow_mut().insert(def_id, pty.clone());
+    return pty;
 }
 
 pub fn mk_item_substs(ccx: &CrateCtxt,
index 40d9543e669dff32210a8cf7c7205754135102e0..a5bdea72da2302f1e9906fde9326260b32413c88 100644 (file)
@@ -1052,7 +1052,7 @@ fn rebuild_arg_ty_or_output(&self,
                     };
                     match a_def {
                         def::DefTy(did) | def::DefStruct(did) => {
-                            let ty::ty_param_bounds_and_ty {
+                            let ty::Polytype {
                                 generics: generics,
                                 ty: _
                             } = ty::lookup_item_type(self.tcx, did);
index bc2768ce214eb9f35380e96f14b6123da76a4050..e159d0d00c82caa624073cc8d32a69cd518d63a0 100644 (file)
@@ -176,6 +176,11 @@ pub enum ExprAdjustment {
     AutoObject
 }
 
+pub struct TypeAndSubsts {
+    pub substs: subst::Substs,
+    pub ty: ty::t,
+}
+
 impl MethodCall {
     pub fn expr(id: ast::NodeId) -> MethodCall {
         MethodCall {
@@ -302,8 +307,8 @@ pub fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
     lookup_def_tcx(ccx.tcx, sp, id)
 }
 
-pub fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty {
-    ty::ty_param_bounds_and_ty {
+pub fn no_params(t: ty::t) -> ty::Polytype {
+    ty::Polytype {
         generics: ty::Generics {types: VecPerParamSpace::empty(),
                                 regions: VecPerParamSpace::empty()},
         ty: t
index 6e9ee92c0a35e812b798eb9e18b96644ecfe0e6b..6aeae544746d8425644ad11eb93042c3a0845cc6 100644 (file)
@@ -748,9 +748,9 @@ fn repr(&self, tcx: &ctxt) -> String {
     }
 }
 
-impl Repr for ty::ty_param_bounds_and_ty {
+impl Repr for ty::Polytype {
     fn repr(&self, tcx: &ctxt) -> String {
-        format!("ty_param_bounds_and_ty {{generics: {}, ty: {}}}",
+        format!("Polytype {{generics: {}, ty: {}}}",
                 self.generics.repr(tcx),
                 self.ty.repr(tcx))
     }
index fa8d341e05de2b60174427a60be1fc7637016479..0439306ffdeac10750a3c1c570667f86a9c28fab 100644 (file)
@@ -71,7 +71,7 @@ fn main() {
     let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()};
     let mut m = io::MemWriter::new();
     {
-        let mut encoder = json::Encoder::new(&mut m as &mut std::io::Writer);
+        let mut encoder = json::Encoder::new(&mut m as &mut Writer);
         match to_encode_object.encode(&mut encoder) {
             Ok(()) => (),
             Err(e) => fail!("json encoding error: {}", e)
index 5eca5361835e36e7295f5d5f66f6ffde1df300c8..ec3d93708331c0b6e47e73348ef5b4cf0c1305f3 100644 (file)
@@ -59,11 +59,13 @@ pub struct MemWriter {
 
 impl MemWriter {
     /// Create a new `MemWriter`.
+    #[inline]
     pub fn new() -> MemWriter {
         MemWriter::with_capacity(128)
     }
     /// Create a new `MemWriter`, allocating at least `n` bytes for
     /// the internal buffer.
+    #[inline]
     pub fn with_capacity(n: uint) -> MemWriter {
         MemWriter { buf: Vec::with_capacity(n), pos: 0 }
     }
@@ -73,13 +75,16 @@ pub fn with_capacity(n: uint) -> MemWriter {
     ///
     /// No method is exposed for acquiring a mutable reference to the buffer
     /// because it could corrupt the state of this `MemWriter`.
+    #[inline]
     pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
 
     /// Unwraps this `MemWriter`, returning the underlying buffer
+    #[inline]
     pub fn unwrap(self) -> Vec<u8> { self.buf }
 }
 
 impl Writer for MemWriter {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         // Make sure the internal buffer is as least as big as where we
         // currently are
@@ -112,7 +117,10 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
 }
 
 impl Seek for MemWriter {
+    #[inline]
     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+    #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
         self.pos = new as uint;
@@ -140,6 +148,7 @@ pub struct MemReader {
 impl MemReader {
     /// Creates a new `MemReader` which will read the buffer given. The buffer
     /// can be re-acquired through `unwrap`
+    #[inline]
     pub fn new(buf: Vec<u8>) -> MemReader {
         MemReader {
             buf: buf,
@@ -150,6 +159,7 @@ pub fn new(buf: Vec<u8>) -> MemReader {
     /// Tests whether this reader has read all bytes in its buffer.
     ///
     /// If `true`, then this will no longer return bytes from `read`.
+    #[inline]
     pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
 
     /// Acquires an immutable reference to the underlying buffer of this
@@ -157,13 +167,16 @@ pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
     ///
     /// No method is exposed for acquiring a mutable reference to the buffer
     /// because it could corrupt the state of this `MemReader`.
+    #[inline]
     pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
 
     /// Unwraps this `MemReader`, returning the underlying buffer
+    #[inline]
     pub fn unwrap(self) -> Vec<u8> { self.buf }
 }
 
 impl Reader for MemReader {
+    #[inline]
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
 
@@ -182,7 +195,10 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
 }
 
 impl Seek for MemReader {
+    #[inline]
     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+    #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
         self.pos = new as uint;
@@ -191,6 +207,7 @@ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
 }
 
 impl Buffer for MemReader {
+    #[inline]
     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos < self.buf.len() {
             Ok(self.buf.slice_from(self.pos))
@@ -198,6 +215,8 @@ fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
             Err(io::standard_error(io::EndOfFile))
         }
     }
+
+    #[inline]
     fn consume(&mut self, amt: uint) { self.pos += amt; }
 }
 
@@ -227,6 +246,7 @@ pub struct BufWriter<'a> {
 impl<'a> BufWriter<'a> {
     /// Creates a new `BufWriter` which will wrap the specified buffer. The
     /// writer initially starts at position 0.
+    #[inline]
     pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
         BufWriter {
             buf: buf,
@@ -236,6 +256,7 @@ pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
 }
 
 impl<'a> Writer for BufWriter<'a> {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         // return an error if the entire write does not fit in the buffer
         let max_size = self.buf.len();
@@ -254,7 +275,10 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
 }
 
 impl<'a> Seek for BufWriter<'a> {
+    #[inline]
     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+    #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
         self.pos = new as uint;
@@ -282,6 +306,7 @@ pub struct BufReader<'a> {
 
 impl<'a> BufReader<'a> {
     /// Creates a new buffered reader which will read the specified buffer
+    #[inline]
     pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
         BufReader {
             buf: buf,
@@ -292,10 +317,12 @@ pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
     /// Tests whether this reader has read all bytes in its buffer.
     ///
     /// If `true`, then this will no longer return bytes from `read`.
+    #[inline]
     pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
 }
 
 impl<'a> Reader for BufReader<'a> {
+    #[inline]
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
 
@@ -314,7 +341,10 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
 }
 
 impl<'a> Seek for BufReader<'a> {
+    #[inline]
     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+
+    #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
         self.pos = new as uint;
@@ -323,6 +353,7 @@ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
 }
 
 impl<'a> Buffer for BufReader<'a> {
+    #[inline]
     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos < self.buf.len() {
             Ok(self.buf.slice_from(self.pos))
@@ -330,15 +361,19 @@ fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
             Err(io::standard_error(io::EndOfFile))
         }
     }
+
+    #[inline]
     fn consume(&mut self, amt: uint) { self.pos += amt; }
 }
 
 #[cfg(test)]
 mod test {
+    extern crate test;
     use prelude::*;
     use super::*;
     use io::*;
     use io;
+    use self::test::Bencher;
     use str::StrSlice;
 
     #[test]
@@ -571,4 +606,59 @@ fn io_read_at_least() {
         assert!(r.read_at_least(buf.len(), buf).is_err());
         assert_eq!(buf.as_slice(), &[7, 8, 6]);
     }
+
+    #[bench]
+    fn bench_mem_writer(b: &mut Bencher) {
+        b.iter(|| {
+            let mut wr = MemWriter::new();
+            for _i in range(0, 10) {
+                wr.write([5, .. 10]).unwrap();
+            }
+            assert_eq!(wr.unwrap().as_slice(), [5, .. 100].as_slice());
+        });
+    }
+
+    #[bench]
+    fn bench_mem_reader(b: &mut Bencher) {
+        b.iter(|| {
+            let buf = Vec::from_slice([5 as u8, ..100]);
+            {
+                let mut rdr = MemReader::new(buf);
+                for _i in range(0, 10) {
+                    let mut buf = [0 as u8, .. 10];
+                    rdr.read(buf).unwrap();
+                    assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
+                }
+            }
+        });
+    }
+
+    #[bench]
+    fn bench_buf_writer(b: &mut Bencher) {
+        b.iter(|| {
+            let mut buf = [0 as u8, ..100];
+            {
+                let mut wr = BufWriter::new(buf);
+                for _i in range(0, 10) {
+                    wr.write([5, .. 10]).unwrap();
+                }
+            }
+            assert_eq!(buf.as_slice(), [5, .. 100].as_slice());
+        });
+    }
+
+    #[bench]
+    fn bench_buf_reader(b: &mut Bencher) {
+        b.iter(|| {
+            let buf = [5 as u8, ..100];
+            {
+                let mut rdr = BufReader::new(buf);
+                for _i in range(0, 10) {
+                    let mut buf = [0 as u8, .. 10];
+                    rdr.read(buf).unwrap();
+                    assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
+                }
+            }
+        });
+    }
 }
index d9755cdce1a4fbf1099fac36b541f4fef3f9ca57..1d6ad7c31e2fd5ff29c3ce7501ed057658b41411 100644 (file)
@@ -1084,6 +1084,7 @@ fn write(&mut self, bytes: &[u8]) -> fmt::Result {
     /// If other encodings are desired, it is recommended to compose this stream
     /// with another performing the conversion, or to use `write` with a
     /// converted byte-array instead.
+    #[inline]
     fn write_str(&mut self, s: &str) -> IoResult<()> {
         self.write(s.as_bytes())
     }
@@ -1095,11 +1096,13 @@ fn write_str(&mut self, s: &str) -> IoResult<()> {
     ///
     /// If other encodings or line ending flavors are desired, it is recommended
     /// that the `write` method is used specifically instead.
+    #[inline]
     fn write_line(&mut self, s: &str) -> IoResult<()> {
         self.write_str(s).and_then(|()| self.write(['\n' as u8]))
     }
 
     /// Write a single char, encoded as UTF-8.
+    #[inline]
     fn write_char(&mut self, c: char) -> IoResult<()> {
         let mut buf = [0u8, ..4];
         let n = c.encode_utf8(buf.as_mut_slice());
@@ -1107,66 +1110,79 @@ fn write_char(&mut self, c: char) -> IoResult<()> {
     }
 
     /// Write the result of passing n through `int::to_str_bytes`.
+    #[inline]
     fn write_int(&mut self, n: int) -> IoResult<()> {
         write!(self, "{:d}", n)
     }
 
     /// Write the result of passing n through `uint::to_str_bytes`.
+    #[inline]
     fn write_uint(&mut self, n: uint) -> IoResult<()> {
         write!(self, "{:u}", n)
     }
 
     /// Write a little-endian uint (number of bytes depends on system).
+    #[inline]
     fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
     }
 
     /// Write a little-endian int (number of bytes depends on system).
+    #[inline]
     fn write_le_int(&mut self, n: int) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian uint (number of bytes depends on system).
+    #[inline]
     fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian int (number of bytes depends on system).
+    #[inline]
     fn write_be_int(&mut self, n: int) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian u64 (8 bytes).
+    #[inline]
     fn write_be_u64(&mut self, n: u64) -> IoResult<()> {
         extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
     }
 
     /// Write a big-endian u32 (4 bytes).
+    #[inline]
     fn write_be_u32(&mut self, n: u32) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a big-endian u16 (2 bytes).
+    #[inline]
     fn write_be_u16(&mut self, n: u16) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a big-endian i64 (8 bytes).
+    #[inline]
     fn write_be_i64(&mut self, n: i64) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
     }
 
     /// Write a big-endian i32 (4 bytes).
+    #[inline]
     fn write_be_i32(&mut self, n: i32) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a big-endian i16 (2 bytes).
+    #[inline]
     fn write_be_i16(&mut self, n: i16) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
+    #[inline]
     fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
         unsafe {
             self.write_be_u64(transmute(f))
@@ -1174,6 +1190,7 @@ fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
     }
 
     /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
+    #[inline]
     fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
         unsafe {
             self.write_be_u32(transmute(f))
@@ -1181,37 +1198,44 @@ fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
     }
 
     /// Write a little-endian u64 (8 bytes).
+    #[inline]
     fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
         extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
     }
 
     /// Write a little-endian u32 (4 bytes).
+    #[inline]
     fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a little-endian u16 (2 bytes).
+    #[inline]
     fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a little-endian i64 (8 bytes).
+    #[inline]
     fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
     }
 
     /// Write a little-endian i32 (4 bytes).
+    #[inline]
     fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a little-endian i16 (2 bytes).
+    #[inline]
     fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a little-endian IEEE754 double-precision floating-point
     /// (8 bytes).
+    #[inline]
     fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
         unsafe {
             self.write_le_u64(transmute(f))
@@ -1220,6 +1244,7 @@ fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
 
     /// Write a little-endian IEEE754 single-precision floating-point
     /// (4 bytes).
+    #[inline]
     fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
         unsafe {
             self.write_le_u32(transmute(f))
@@ -1227,11 +1252,13 @@ fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
     }
 
     /// Write a u8 (1 byte).
+    #[inline]
     fn write_u8(&mut self, n: u8) -> IoResult<()> {
         self.write([n])
     }
 
     /// Write an i8 (1 byte).
+    #[inline]
     fn write_i8(&mut self, n: i8) -> IoResult<()> {
         self.write([n as u8])
     }
@@ -1240,18 +1267,25 @@ fn write_i8(&mut self, n: i8) -> IoResult<()> {
     ///
     /// This is useful to allow applying wrappers while still
     /// retaining ownership of the original value.
+    #[inline]
     fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
         RefWriter { inner: self }
     }
 }
 
 impl Writer for Box<Writer> {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
+
+    #[inline]
     fn flush(&mut self) -> IoResult<()> { self.flush() }
 }
 
 impl<'a> Writer for &'a mut Writer {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
+
+    #[inline]
     fn flush(&mut self) -> IoResult<()> { self.flush() }
 }
 
@@ -1285,7 +1319,10 @@ pub struct RefWriter<'a, W> {
 }
 
 impl<'a, W: Writer> Writer for RefWriter<'a, W> {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
+
+    #[inline]
     fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
 }
 
index 0a894645cf120539876e9eb4eb0d7b572dfa9d14..1bba09755d95892bc826c558630e93803b0a4ee6 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 0a894645cf120539876e9eb4eb0d7b572dfa9d14
+Subproject commit 1bba09755d95892bc826c558630e93803b0a4ee6
index 4d5b95155cabb5dd8fdfc62e5d072d7dcdb26eef..c755cf67caa9f6b52dad2e8007673b6fc1bd8f94 100644 (file)
@@ -199,3 +199,21 @@ void
 rust_dbg_static_mut_check_four() {
     assert(rust_dbg_static_mut == 4);
 }
+
+struct S {
+    uint64_t x;
+    uint64_t y;
+    uint64_t z;
+};
+
+uint64_t get_x(struct S s) {
+    return s.x;
+}
+
+uint64_t get_y(struct S s) {
+    return s.y;
+}
+
+uint64_t get_z(struct S s) {
+    return s.z;
+}
index f42844b9f19d2612e3b7873ab5a344b62556e6c4..a1a88d1b14d45d8a9d97cce938dc4ceff0497de1 100644 (file)
@@ -659,7 +659,7 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
 extern "C" void*
 LLVMRustOpenArchive(char *path) {
     std::unique_ptr<MemoryBuffer> buf;
-    error_code err = MemoryBuffer::getFile(path, buf);
+    std::error_code err = MemoryBuffer::getFile(path, buf);
     if (err) {
         LLVMRustSetLastError(err.message().c_str());
         return NULL;
@@ -694,14 +694,18 @@ LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
 #if LLVM_VERSION_MINOR >= 5
     Archive::child_iterator child = ar->child_begin(),
                               end = ar->child_end();
+    for (; child != end; ++child) {
+        ErrorOr<StringRef> name_or_err = child->getName();
+        if (name_or_err.getError()) continue;
+        StringRef sect_name = name_or_err.get();
 #else
     Archive::child_iterator child = ar->begin_children(),
                               end = ar->end_children();
-#endif
     for (; child != end; ++child) {
         StringRef sect_name;
         error_code err = child->getName(sect_name);
         if (err) continue;
+#endif
         if (sect_name.trim(" ") == name) {
             StringRef buf = child->getBuffer();
             *size = buf.size();
@@ -757,7 +761,11 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
 extern "C" int
 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
     StringRef ret;
+#if LLVM_VERSION_MINOR >= 5
+    if (std::error_code ec = (*unwrap(SI))->getName(ret))
+#else
     if (error_code ec = (*unwrap(SI))->getName(ret))
+#endif
       report_fatal_error(ec.message());
     *ptr = ret.data();
     return ret.size();
index 4e599ad115db36dc9e66602a112073caae7ce50d..1bd3434b46eca59bdeae275dcb79edef06acdf67 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-05-20
+2014-06-20.2
diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs
new file mode 100644 (file)
index 0000000..671bf45
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2012-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.
+
+// The regression test for #15031 to make sure destructuring trait
+// reference work properly.
+
+trait T {}
+impl T for int {}
+
+fn main() {
+    // For an expression of the form:
+    //
+    //      let &...&x = &..&SomeTrait;
+    //
+    // Say we have n `&` at the left hand and m `&` right hand, then:
+    // if n < m, we are golden;
+    // if n == m, it's a derefing non-derefable type error;
+    // if n > m, it's a type mismatch error.
+
+    // n < m
+    let &x = &(&1 as &T);
+    let &x = &&(&1 as &T);
+    let &&x = &&(&1 as &T);
+
+    // n == m
+    let &x = &1 as &T;      //~ ERROR cannot be dereferenced
+    let &&x = &(&1 as &T);  //~ ERROR cannot be dereferenced
+    let box x = box 1 as Box<T>; //~ ERROR cannot be dereferenced
+
+    // n > m
+    let &&x = &1 as &T;     //~ ERROR found an `&`-pointer pattern
+    let &&&x = &(&1 as &T); //~ ERROR found an `&`-pointer pattern
+    let box box x = box 1 as Box<T>;    //~ ERROR found a box pattern
+}
index ffac6b499f4c1f9add5542404f1807081c1c44ca..edd6932aec6f0d3900614ad11699aced0a25fb3f 100644 (file)
@@ -17,7 +17,7 @@ pub enum TraitWrapper {
 
 fn get_tw_map<'lt>(tw: &'lt TraitWrapper) -> &'lt MyTrait {
     match *tw {
-        A(box ref map) => map, //~ ERROR found a box pattern
+        A(box ref map) => map, //~ ERROR cannot be dereferenced
     }
 }
 
diff --git a/src/test/run-pass/foreign-fn-with-byval.rs b/src/test/run-pass/foreign-fn-with-byval.rs
new file mode 100644 (file)
index 0000000..6a26ec4
--- /dev/null
@@ -0,0 +1,36 @@
+// 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.
+
+pub struct S {
+    x: u64,
+    y: u64,
+    z: u64,
+}
+
+#[link(name = "rust_test_helpers")]
+extern {
+    pub fn get_x(x: S) -> u64;
+    pub fn get_y(x: S) -> u64;
+    pub fn get_z(x: S) -> u64;
+}
+
+#[inline(never)]
+fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 {
+    unsafe {
+        func(s)
+    }
+}
+
+fn main() {
+    let s = S { x: 1, y: 2, z: 3 };
+    assert_eq!(s.x, indirect_call(get_x, s));
+    assert_eq!(s.y, indirect_call(get_y, s));
+    assert_eq!(s.z, indirect_call(get_z, s));
+}
diff --git a/src/test/run-pass/issue-15080.rs b/src/test/run-pass/issue-15080.rs
new file mode 100644 (file)
index 0000000..b12f0c6
--- /dev/null
@@ -0,0 +1,30 @@
+// 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 main() {
+    let mut x = &[1, 2, 3, 4];
+
+    let mut result = vec!();
+    loop {
+        x = match x {
+            [1, n, 3, ..rest] => {
+                result.push(n);
+                rest
+            }
+            [n, ..rest] => {
+                result.push(n);
+                rest
+            }
+            [] =>
+                break
+        }
+    }
+    assert!(result.as_slice() == [2, 4]);
+}
index 175f774bdfde01720577c9a17c2881ffe56a04ff..11143ba0c842341e34e5883e45e0c798db616e92 100644 (file)
@@ -68,9 +68,17 @@ fn d() {
     assert_eq!(branch, 1);
 }
 
+fn e() {
+    match &[1, 2, 3] {
+        [1, 2] => (),
+        [..] => ()
+    }
+}
+
 pub fn main() {
     a();
     b();
     c();
     d();
+    e();
 }