]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #14880 : SimonSapin/rust/byte-literals, r=alexcrichton
authorbors <bors@rust-lang.org>
Wed, 18 Jun 2014 02:06:37 +0000 (02:06 +0000)
committerbors <bors@rust-lang.org>
Wed, 18 Jun 2014 02:06:37 +0000 (02:06 +0000)
See #14646 (tracking issue) and rust-lang/rfcs#69.

This does not close the tracking issue, as the `bytes!()` macro still needs to be removed. It will be later, after a snapshot is made with the changes in this PR, so that the new syntax can be used when bootstrapping the compiler.

38 files changed:
src/doc/rust.md
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/kind.rs
src/librustc/middle/lint.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/reachable.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/inline.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/type_of.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/regionck.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/util/ppaux.rs
src/libserialize/json.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/ext/format.rs
src/libsyntax/parse/mod.rs
src/test/auxiliary/xcrate_address_insignificant.rs
src/test/auxiliary/xcrate_static_addresses.rs

index 97757a53e4c1ce3a54eb0207ce61aec6bc7e8d99..cc41b8edfbf8d888a63a32e0a249e2eda6d0ec32 100644 (file)
@@ -1888,8 +1888,6 @@ type int8_t = i8;
 
 ### Static-only attributes
 
-- `address_insignificant` - references to this static may alias with
-  references to other statics, potentially of unrelated type.
 - `thread_local` - on a `static mut`, this signals that the value of this
   static may change depending on the current thread. The exact consequences of
   this are implementation-defined.
@@ -2200,13 +2198,22 @@ These types help drive the compiler's analysis
 ### Inline attributes
 
 The inline attribute is used to suggest to the compiler to perform an inline
-expansion and place a copy of the function in the caller rather than generating
-code to call the function where it is defined.
+expansion and place a copy of the function or static in the caller rather than
+generating code to call the function or access the static where it is defined.
 
 The compiler automatically inlines functions based on internal heuristics.
 Incorrectly inlining functions can actually making the program slower, so it
 should be used with care.
 
+Immutable statics are always considered inlineable
+unless marked with `#[inline(never)]`.
+It is undefined
+whether two different inlineable statics
+have the same memory address.
+In other words,
+the compiler is free
+to collapse duplicate inlineable statics together.
+
 `#[inline]` and `#[inline(always)]` always causes the function to be serialized
 into crate metadata to allow cross-crate inlining.
 
index 6a60f91a1ae4f18114d4b5fb638258f373df5fb8..4897117431bbdbc96ae13d9151e81013ac3c2632 100644 (file)
@@ -346,10 +346,9 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         assert_eq!(next(st), '[');
         let def = parse_def(st, NominalType, |x,y| conv(x,y));
         let substs = parse_substs(st, |x,y| conv(x,y));
-        let store = parse_trait_store(st, |x,y| conv(x,y));
         let bounds = parse_bounds(st, |x,y| conv(x,y));
         assert_eq!(next(st), ']');
-        return ty::mk_trait(st.tcx, def, substs, store, bounds.builtin_bounds);
+        return ty::mk_trait(st.tcx, def, substs, bounds.builtin_bounds);
       }
       'p' => {
         let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
index 830178ee880829c2021a53902c9680d642d816f3..e1fa4abefdd06512ac5af26b14320320998dc238 100644 (file)
@@ -232,12 +232,10 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
         ty::ty_trait(box ty::TyTrait {
                 def_id,
                 ref substs,
-                store,
                 bounds
             }) => {
             mywrite!(w, "x[{}|", (cx.ds)(def_id));
             enc_substs(w, cx, substs);
-            enc_trait_store(w, cx, store);
             let bounds = ty::ParamBounds {builtin_bounds: bounds,
                                           trait_bounds: Vec::new()};
             enc_bounds(w, cx, &bounds);
index 1a3cb166750142546bcb1d3196cbd16820ec7211..970ae36238bd6f915477818da8121bfe46e4a31d 100644 (file)
@@ -361,9 +361,12 @@ fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) {
 fn check_trait_cast(cx: &mut Context, source_ty: ty::t, target_ty: ty::t, span: Span) {
     check_cast_for_escaping_regions(cx, source_ty, target_ty, span);
     match ty::get(target_ty).sty {
-        ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
-            check_trait_cast_bounds(cx, span, source_ty, bounds);
-        }
+        ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ ty, .. }) => match ty::get(ty).sty {
+            ty::ty_trait(box ty::TyTrait { bounds, .. }) => {
+                check_trait_cast_bounds(cx, span, source_ty, bounds);
+            }
+            _ => {}
+        },
         _ => {}
     }
 }
@@ -530,9 +533,8 @@ pub fn check_cast_for_escaping_regions(
 {
     // Determine what type we are casting to; if it is not a trait, then no
     // worries.
-    match ty::get(target_ty).sty {
-        ty::ty_trait(..) => {}
-        _ => { return; }
+    if !ty::type_is_trait(target_ty) {
+        return;
     }
 
     // Collect up the regions that appear in the target type.  We want to
index 4c11693e7a673b70df22c378280c2d39c8f69f03..bf42f76f1a2769853ddeb928313d3b96bdd86813 100644 (file)
@@ -981,9 +981,6 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
                     n_box += 1;
                 }
                 ty::ty_uniq(_) |
-                ty::ty_trait(box ty::TyTrait {
-                    store: ty::UniqTraitStore, ..
-                }) |
                 ty::ty_closure(box ty::ClosureTy {
                     store: ty::UniqTraitStore,
                     ..
@@ -1088,7 +1085,6 @@ fn check_unused_attribute(cx: &Context, attr: &ast::Attribute) {
 
         // FIXME: #14406 these are processed in trans, which happens after the
         // lint pass
-        "address_insignificant",
         "cold",
         "inline",
         "link",
index 9b5930cf9ada30cc5361ba8a93cc1dd182537fda..8224557f860072a7685b9bcfb06c1991efdb1b0a 100644 (file)
@@ -174,7 +174,6 @@ pub enum deref_kind {
 pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
     match ty::get(t).sty {
         ty::ty_uniq(_) |
-        ty::ty_trait(box ty::TyTrait { store: ty::UniqTraitStore, .. }) |
         ty::ty_closure(box ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
             Some(deref_ptr(OwnedPtr))
         }
@@ -183,13 +182,6 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
             let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
             Some(deref_ptr(BorrowedPtr(kind, r)))
         }
-        ty::ty_trait(box ty::TyTrait {
-                store: ty::RegionTraitStore(r, mutbl),
-                ..
-            }) => {
-            let kind = ty::BorrowKind::from_mutbl(mutbl);
-            Some(deref_ptr(BorrowedPtr(kind, r)))
-        }
 
         ty::ty_closure(box ty::ClosureTy {
                 store: ty::RegionTraitStore(r, _),
index d9b5dff3bb0ceb47328f724ec02ee3c03beb5739..682dcb2b709f396ff8bdfb1b8a61689002137838 100644 (file)
@@ -26,7 +26,9 @@
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{is_local};
+use syntax::ast_util::is_local;
+use syntax::ast_util;
+use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone};
 use syntax::attr;
 use syntax::visit::Visitor;
 use syntax::visit;
 // Returns true if the given set of attributes contains the `#[inline]`
 // attribute.
 fn attributes_specify_inlining(attrs: &[ast::Attribute]) -> bool {
-    attr::contains_name(attrs, "inline")
+    match attr::find_inline_attr(attrs) {
+        InlineNone | InlineNever => false,
+        InlineAlways | InlineHint => true,
+    }
 }
 
 // Returns true if the given set of generics implies that the item it's
@@ -118,8 +123,8 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
                         match def {
                             // If this path leads to a static, then we may have
                             // to do some work to figure out whether the static
-                            // is indeed reachable (address_insignificant
-                            // statics are *never* reachable).
+                            // is indeed reachable. (Inlineable statics are
+                            // never reachable.)
                             def::DefStatic(..) => {
                                 self.worklist.push(def_id.node);
                             }
@@ -281,9 +286,10 @@ fn propagate_node(&mut self, node: &ast_map::Node,
 
                     // Statics with insignificant addresses are not reachable
                     // because they're inlined specially into all other crates.
-                    ast::ItemStatic(_, _, ref init) => {
-                        if attr::contains_name(item.attrs.as_slice(),
-                                               "address_insignificant") {
+                    ast::ItemStatic(_, mutbl, ref init) => {
+                        if !ast_util::static_has_significant_address(
+                                mutbl,
+                                item.attrs.as_slice()) {
                             self.reachable_symbols.remove(&search_item);
                         }
                         visit::walk_expr(self, &**init, ());
index 1b530ea34249193b3018b9e2dc66c8837295f267..9f4b11116dbb74717cbc27e984c576fada5e63c3 100644 (file)
@@ -292,12 +292,11 @@ fn is_zerolen(&self, cx: &CrateContext) -> bool {
     fn find_ptr(&self) -> Option<uint> {
         self.tys.iter().position(|&ty| {
             match ty::get(ty).sty {
-                ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
-                    ty::ty_vec(_, None) | ty::ty_str => false,
+                ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
+                    ty::ty_vec(_, None) | ty::ty_str| ty::ty_trait(..) => false,
                     _ => true,
                 },
-                ty::ty_uniq(..) | ty::ty_box(..) |
-                ty::ty_bare_fn(..) => true,
+                ty::ty_box(..) | ty::ty_bare_fn(..) => true,
                 // Is that everything?  Would closures or slices qualify?
                 _ => false
             }
index 998e8500b994d519287146ec0288c7c4fbf76c81..35795cc9f23ee4d9f926ed7d6f0ff1cd9c041374 100644 (file)
@@ -1794,6 +1794,9 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
         match ty::get(ret_ty).sty {
             // `~` pointer return values never alias because ownership
             // is transferred
+            ty::ty_uniq(it)  if match ty::get(it).sty {
+                ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
+            } => {}
             ty::ty_uniq(_) => {
                 attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NoAliasAttribute as u64));
             }
@@ -1803,9 +1806,9 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
         // We can also mark the return value as `nonnull` in certain cases
         match ty::get(ret_ty).sty {
             // These are not really pointers but pairs, (pointer, len)
-            ty::ty_rptr(_, ty::mt { ty: it, .. }) |
+            ty::ty_uniq(it) |
             ty::ty_rptr(_, ty::mt { ty: it, .. }) if match ty::get(it).sty {
-                ty::ty_str | ty::ty_vec(..) => true, _ => false
+                ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
             } => {}
             ty::ty_uniq(_) | ty::ty_rptr(_, _) => {
                 attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NonNullAttribute as u64));
@@ -1994,7 +1997,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             let sym = exported_name(ccx, id, ty, i.attrs.as_slice());
 
             let v = match i.node {
-                ast::ItemStatic(_, _, ref expr) => {
+                ast::ItemStatic(_, mutbl, ref expr) => {
                     // If this static came from an external crate, then
                     // we need to get the symbol from csearch instead of
                     // using the current crate's name/version
@@ -2029,20 +2032,16 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
                         // Apply the `unnamed_addr` attribute if
                         // requested
-                        if attr::contains_name(i.attrs.as_slice(),
-                                               "address_insignificant") {
-                            if ccx.reachable.contains(&id) {
-                                ccx.sess().span_bug(i.span,
-                                    "insignificant static is reachable");
-                            }
+                        if !ast_util::static_has_significant_address(
+                                mutbl,
+                                i.attrs.as_slice()) {
                             lib::llvm::SetUnnamedAddr(g, true);
 
                             // This is a curious case where we must make
                             // all of these statics inlineable. If a
-                            // global is tagged as
-                            // address_insignificant, then LLVM won't
-                            // coalesce globals unless they have an
-                            // internal linkage type. This means that
+                            // global is not tagged as `#[inline(never)]`,
+                            // then LLVM won't coalesce globals unless they
+                            // have an internal linkage type. This means that
                             // external crates cannot use this global.
                             // This is a problem for things like inner
                             // statics in generic functions, because the
@@ -2050,7 +2049,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                             // crate and then attempt to link to the
                             // static in the original crate, only to
                             // find that it's not there. On the other
-                            // side of inlininig, the crates knows to
+                            // side of inlining, the crates knows to
                             // not declare this static as
                             // available_externally (because it isn't)
                             inlineable = true;
index 565ec7d8247106256fe7ba4935d388815d67141e..d7509866e08862687c60b03c0857edd44ba0aba6 100644 (file)
@@ -67,7 +67,7 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
         ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
         type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
         ty::type_is_simd(tcx, ty);
-    if simple {
+    if simple && !ty::type_is_trait(ty) {
         return true;
     }
     match ty::get(ty).sty {
index f5e66a527e7fbcf4c89d6388a640e3fde98f70e4..338821537e8c6d098a095a6f63120dd6ccdf6c8d 100644 (file)
@@ -144,7 +144,9 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
             let dv = match ty::get(t).sty {
                 ty::ty_ptr(mt) | ty::ty_rptr(_, mt) => {
                     match ty::get(mt.ty).sty {
-                        ty::ty_vec(_, None) | ty::ty_str => cx.sess().bug("unexpected slice"),
+                        ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => {
+                            cx.sess().bug("unexpected unsized type")
+                        }
                         _ => const_deref_ptr(cx, v),
                     }
                 }
index 1142b67fdbfad55dadcb7e8ee79c69c73b7e0757..158a7d6cf7ab91a61a8026a27719e865cad3469d 100644 (file)
@@ -157,9 +157,7 @@ pub fn appropriate_rvalue_mode(ccx: &CrateContext, ty: ty::t) -> RvalueMode {
      * on whether type is immediate or not.
      */
 
-    if type_is_zero_size(ccx, ty) {
-        ByValue
-    } else if type_is_immediate(ccx, ty) {
+    if type_is_immediate(ccx, ty) {
         ByValue
     } else {
         ByRef
index b934f23abb48c5f17444afe79a0529807c58b35e..d05e9954cf45793ac429668cd54ae46314925638 100644 (file)
@@ -285,8 +285,8 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
         // unique ptr (~)       -> {~ :pointee-uid:}
         // @-ptr (@)            -> {@ :pointee-uid:}
         // sized vec ([T, ..x]) -> {[:size:] :element-uid:}
-        // vec slice (&[T])     -> {&<mut> [] :element-uid:}
-        // trait (~ | &[mut] T) -> {:sigil: trait_:svh: / :node-id:_<(:param-uid:),*> }
+        // unsized vec ([T])    -> {[] :element-uid:}
+        // trait (T)            -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
         // closure              -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
         //                             :return-type-uid: : (:bounds:)*}
         // function             -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
@@ -361,18 +361,12 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
                 unique_type_id.push_str(inner_type_id.as_slice());
             },
-            ty::ty_vec(ty::mt { ty: inner_type, mutbl }, optional_length) => {
+            ty::ty_vec(ty::mt { ty: inner_type, .. }, optional_length) => {
                 match optional_length {
                     Some(len) => {
                         unique_type_id.push_str(format!("[{}]", len).as_slice());
                     }
                     None => {
-                        unique_type_id.push_char('&');
-
-                        if mutbl == ast::MutMutable {
-                           unique_type_id.push_str("mut");
-                        }
-
                         unique_type_id.push_str("[]");
                     }
                 };
@@ -382,12 +376,6 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
                 unique_type_id.push_str(inner_type_id.as_slice());
             },
             ty::ty_trait(ref trait_data) => {
-                match trait_data.store {
-                    ty::UniqTraitStore => unique_type_id.push_char('~'),
-                    ty::RegionTraitStore(_, ast::MutMutable) => unique_type_id.push_str("&mut"),
-                    ty::RegionTraitStore(_, ast::MutImmutable) => unique_type_id.push_char('&'),
-                };
-
                 unique_type_id.push_str("trait ");
 
                 from_def_id_and_substs(self,
@@ -2901,6 +2889,16 @@ macro_rules! return_if_created_in_meantime(
                     let i8_t = ty::mk_i8();
                     heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
                 }
+                ty::ty_trait(box ty::TyTrait {
+                        def_id,
+                        ref substs,
+                        ref bounds
+                    }) => {
+                    MetadataCreationResult::new(
+                        trait_metadata(cx, def_id, t, substs, ty::UniqTraitStore,
+                                       bounds, unique_type_id),
+                    false)
+                }
                 _ => {
                     let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span);
                     return_if_created_in_meantime!();
@@ -2917,6 +2915,17 @@ macro_rules! return_if_created_in_meantime(
                 ty::ty_str => {
                     vec_slice_metadata(cx, t, ty::mk_i8(), unique_type_id, usage_site_span)
                 }
+                ty::ty_trait(box ty::TyTrait {
+                        def_id,
+                        ref substs,
+                        ref bounds
+                    }) => {
+                    MetadataCreationResult::new(
+                        trait_metadata(cx, def_id, t, substs,
+                                       ty::RegionTraitStore(ty::ReStatic, mt.mutbl),
+                                       bounds, unique_type_id),
+                    false)
+                }
                 _ => {
                     let pointee = type_metadata(cx, mt.ty, usage_site_span);
                     return_if_created_in_meantime!();
@@ -2930,16 +2939,6 @@ macro_rules! return_if_created_in_meantime(
         ty::ty_closure(ref closurety) => {
             subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
         }
-        ty::ty_trait(box ty::TyTrait {
-                def_id,
-                ref substs,
-                store,
-                ref bounds
-            }) => {
-            MetadataCreationResult::new(
-                trait_metadata(cx, def_id, t, substs, store, bounds, unique_type_id),
-                false)
-        }
         ty::ty_struct(def_id, ref substs) => {
             prepare_struct_metadata(cx,
                                     t,
index 01ba6113c0d518902e43689904367b354db96a1d..42c7a71bab84dbda7bc4f9b3b454d9eeb3baf7c0 100644 (file)
@@ -769,15 +769,12 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
         }
         ast::ExprCast(ref val, _) => {
             // DPS output mode means this is a trait cast:
-            match ty::get(node_id_type(bcx, expr.id)).sty {
-                ty::ty_trait(..) => {
-                    let datum = unpack_datum!(bcx, trans(bcx, &**val));
-                    meth::trans_trait_cast(bcx, datum, expr.id, dest)
-                }
-                _ => {
-                    bcx.tcx().sess.span_bug(expr.span,
-                                            "expr_cast of non-trait");
-                }
+            if ty::type_is_trait(node_id_type(bcx, expr.id)) {
+                let datum = unpack_datum!(bcx, trans(bcx, &**val));
+                meth::trans_trait_cast(bcx, datum, expr.id, dest)
+            } else {
+                bcx.tcx().sess.span_bug(expr.span,
+                                        "expr_cast of non-trait");
             }
         }
         ast::ExprAssignOp(op, ref dst, ref src) => {
@@ -1578,7 +1575,7 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind {
         ty::ty_float(..)   => cast_float,
         ty::ty_ptr(..)     => cast_pointer,
         ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty{
-            ty::ty_vec(_, None) | ty::ty_str => cast_other,
+            ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => cast_other,
             _ => cast_pointer,
         },
         ty::ty_bare_fn(..) => cast_pointer,
@@ -1794,8 +1791,8 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
     let r = match ty::get(datum.ty).sty {
         ty::ty_uniq(content_ty) => {
             match ty::get(content_ty).sty {
-                ty::ty_vec(_, None) | ty::ty_str
-                    => bcx.tcx().sess.span_bug(expr.span, "unexpected ~[T]"),
+                ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..)
+                    => bcx.tcx().sess.span_bug(expr.span, "unexpected unsized box"),
                 _ => deref_owned_pointer(bcx, expr, datum, content_ty),
             }
         }
@@ -1812,8 +1809,8 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
         ty::ty_ptr(ty::mt { ty: content_ty, .. }) |
         ty::ty_rptr(_, ty::mt { ty: content_ty, .. }) => {
             match ty::get(content_ty).sty {
-                ty::ty_vec(_, None) | ty::ty_str
-                    => bcx.tcx().sess.span_bug(expr.span, "unexpected &[T]"),
+                ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..)
+                    => bcx.tcx().sess.span_bug(expr.span, "unexpected unsized reference"),
                 _ => {
                     assert!(!ty::type_needs_drop(bcx.tcx(), datum.ty));
 
index ef9bf4eebe24b0d11239d0a0d35b4be218dad747..7024ea4b3756907b0af8a544311a928e9ad7540a 100644 (file)
@@ -100,7 +100,7 @@ pub fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
 
         ty::ty_uniq(typ) if !ty::type_needs_drop(tcx, typ) => {
             match ty::get(typ).sty {
-                ty::ty_vec(_, None) | ty::ty_str => t,
+                ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => t,
                 _ => {
                     let llty = sizing_type_of(ccx, typ);
                     // `Box<ZeroSizeType>` does not allocate.
@@ -295,10 +295,10 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
             decr_refcnt_maybe_free(bcx, v0, body_ty)
         }
         ty::ty_uniq(content_ty) => {
-            let llbox = Load(bcx, v0);
-            let not_null = IsNotNull(bcx, llbox);
             match ty::get(content_ty).sty {
                 ty::ty_vec(mt, None) => {
+                    let llbox = Load(bcx, v0);
+                    let not_null = IsNotNull(bcx, llbox);
                     with_cond(bcx, not_null, |bcx| {
                         let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, mt.ty);
                         // FIXME: #13994: the old `Box<[T]>` will not support sized deallocation
@@ -306,6 +306,8 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                     })
                 }
                 ty::ty_str => {
+                    let llbox = Load(bcx, v0);
+                    let not_null = IsNotNull(bcx, llbox);
                     with_cond(bcx, not_null, |bcx| {
                         let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
                         let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, unit_ty);
@@ -313,7 +315,22 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                         trans_exchange_free(bcx, llbox, 0, 8)
                     })
                 }
+                ty::ty_trait(..) => {
+                    let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
+                    // Only drop the value when it is non-null
+                    with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
+                        let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
+                        let dtor = Load(bcx, dtor_ptr);
+                        Call(bcx,
+                             dtor,
+                             [PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
+                             []);
+                        bcx
+                    })
+                }
                 _ => {
+                    let llbox = Load(bcx, v0);
+                    let not_null = IsNotNull(bcx, llbox);
                     with_cond(bcx, not_null, |bcx| {
                         let bcx = drop_ty(bcx, llbox, content_ty);
                         trans_exchange_free_ty(bcx, llbox, content_ty)
@@ -336,16 +353,6 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 }
             }
         }
-        ty::ty_trait(box ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
-            let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
-            // Only drop the value when it is non-null
-            with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
-                let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
-                let dtor = Load(bcx, dtor_ptr);
-                Call(bcx, dtor, [PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))], []);
-                bcx
-            })
-        }
         ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => {
             let box_cell_v = GEPi(bcx, v0, [0u, abi::fn_field_box]);
             let env = Load(bcx, box_cell_v);
index 095645f4d6b679ee33281c5cef5ac9ee6c7ae25b..2ebbc2f5340b79a1cbcc602fce831da84cb9e9b8 100644 (file)
@@ -17,7 +17,7 @@
 
 use syntax::ast;
 use syntax::ast_util::local_def;
-use syntax::attr;
+use syntax::ast_util;
 
 pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
     -> ast::DefId {
@@ -62,12 +62,13 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             // however, so we use the available_externally linkage which llvm
             // provides
             match item.node {
-                ast::ItemStatic(..) => {
+                ast::ItemStatic(_, mutbl, _) => {
                     let g = get_item_val(ccx, item.id);
                     // see the comment in get_item_val() as to why this check is
                     // performed here.
-                    if !attr::contains_name(item.attrs.as_slice(),
-                                            "address_insignificant") {
+                    if ast_util::static_has_significant_address(
+                            mutbl,
+                            item.attrs.as_slice()) {
                         SetLinkage(g, AvailableExternallyLinkage);
                     }
                 }
index f67fc57bb44073eb0c2cad07c06beab351c62ac1..506817629565e37dc9dad7539219c4e350dfc8f1 100644 (file)
@@ -157,7 +157,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
               let extra = extra.append(self.c_mt(mt).as_slice());
               self.visit("evec_fixed", extra.as_slice())
           }
-          ty::ty_vec(..) | ty::ty_str => fail!("unexpected unsized type"),
+          ty::ty_vec(..) | ty::ty_str | ty::ty_trait(..) => fail!("unexpected unsized type"),
           // Should remove mt from box and uniq.
           ty::ty_box(typ) => {
               let extra = self.c_mt(&ty::mt {
@@ -174,6 +174,13 @@ pub fn visit_ty(&mut self, t: ty::t) {
                       self.visit("evec_uniq", extra.as_slice())
                   }
                   ty::ty_str => self.visit("estr_uniq", &[]),
+                  ty::ty_trait(..) => {
+                      let extra = [
+                          self.c_slice(token::intern_and_get_ident(
+                                  ty_to_str(tcx, t).as_slice()))
+                      ];
+                      self.visit("trait", extra);
+                  }
                   _ => {
                       let extra = self.c_mt(&ty::mt {
                           ty: typ,
@@ -196,6 +203,13 @@ pub fn visit_ty(&mut self, t: ty::t) {
                                  extra.as_slice())
                   }
                   ty::ty_str => self.visit("estr_slice", &[]),
+                  ty::ty_trait(..) => {
+                      let extra = [
+                          self.c_slice(token::intern_and_get_ident(
+                                  ty_to_str(tcx, t).as_slice()))
+                      ];
+                      self.visit("trait", extra);
+                  }
                   _ => {
                       let extra = self.c_mt(mt);
                       self.visit("rptr", extra.as_slice())
@@ -351,14 +365,6 @@ pub fn visit_ty(&mut self, t: ty::t) {
             })
           }
 
-          ty::ty_trait(..) => {
-              let extra = [
-                  self.c_slice(token::intern_and_get_ident(
-                          ty_to_str(tcx, t).as_slice()))
-              ];
-              self.visit("trait", extra);
-          }
-
           // Miscellaneous extra types
           ty::ty_infer(_) => self.leaf("infer"),
           ty::ty_err => self.leaf("err"),
index 4701a9e3225005c331be3d82bb80ea5f6867ad22..31bf6cb0110a489699e189359b86db04a765ded9 100644 (file)
@@ -116,20 +116,25 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_float(t) => Type::float_from_ty(cx, t),
 
         ty::ty_box(..) |
-        ty::ty_uniq(..) |
         ty::ty_ptr(..) => Type::i8p(cx),
+        ty::ty_uniq(ty) => {
+            match ty::get(ty).sty {
+                ty::ty_trait(..) => Type::opaque_trait(cx),
+                _ => Type::i8p(cx),
+            }
+        }
         ty::ty_rptr(_, mt) => {
             match ty::get(mt.ty).sty {
                 ty::ty_vec(_, None) | ty::ty_str => {
                     Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false)
                 }
+                ty::ty_trait(..) => Type::opaque_trait(cx),
                 _ => Type::i8p(cx),
             }
         }
 
         ty::ty_bare_fn(..) => Type::i8p(cx),
         ty::ty_closure(..) => Type::struct_(cx, [Type::i8p(cx), Type::i8p(cx)], false),
-        ty::ty_trait(..) => Type::opaque_trait(cx),
 
         ty::ty_vec(mt, Some(size)) => {
             Type::array(&sizing_type_of(cx, mt.ty), size as u64)
@@ -152,7 +157,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         }
 
         ty::ty_infer(..) | ty::ty_param(..) |
-        ty::ty_err(..) | ty::ty_vec(_, None) | ty::ty_str => {
+        ty::ty_err(..) | ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => {
             cx.sess().bug(format!("fictitious type {:?} in sizing_type_of()",
                                   ty::get(t).sty).as_slice())
         }
@@ -215,6 +220,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
           match ty::get(typ).sty {
               ty::ty_vec(mt, None) => Type::vec(cx, &type_of(cx, mt.ty)).ptr_to(),
               ty::ty_str => Type::vec(cx, &Type::i8(cx)).ptr_to(),
+              ty::ty_trait(..) => Type::opaque_trait(cx),
               _ => type_of(cx, typ).ptr_to(),
           }
       }
@@ -230,6 +236,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
                   // This means we get a nicer name in the output
                   cx.tn.find_type("str_slice").unwrap()
               }
+              ty::ty_trait(..) => Type::opaque_trait(cx),
               _ => type_of(cx, mt.ty).ptr_to(),
           }
       }
@@ -245,7 +252,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
           let fn_ty = type_of_fn_from_ty(cx, t).ptr_to();
           Type::struct_(cx, [fn_ty, Type::i8p(cx)], false)
       }
-      ty::ty_trait(..) => Type::opaque_trait(cx),
       ty::ty_tup(..) => {
           let repr = adt::represent_type(cx, t);
           adt::type_of(cx, &*repr)
@@ -268,6 +274,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
 
       ty::ty_vec(_, None) => cx.sess().bug("type_of with unsized ty_vec"),
       ty::ty_str => cx.sess().bug("type_of with unsized (bare) ty_str"),
+      ty::ty_trait(..) => cx.sess().bug("type_of with unsized ty_trait"),
       ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
       ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
       ty::ty_err(..) => cx.sess().bug("type_of with ty_err")
index 3ac1027221b6191b4563760296d8aa4549fe9d48..ac1b6ca591becaafdb65f5ec42cbe0ac2b4993a0 100644 (file)
@@ -742,7 +742,6 @@ pub enum sty {
 pub struct TyTrait {
     pub def_id: DefId,
     pub substs: Substs,
-    pub store: TraitStore,
     pub bounds: BuiltinBounds
 }
 
@@ -1196,14 +1195,8 @@ fn sflags(substs: &Substs) -> uint {
       &ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
           flags |= sflags(substs);
       }
-      &ty_trait(box ty::TyTrait { ref substs, store, .. }) => {
+      &ty_trait(box ty::TyTrait { ref substs, .. }) => {
           flags |= sflags(substs);
-          match store {
-              RegionTraitStore(r, _) => {
-                    flags |= rflags(r);
-                }
-              _ => {}
-          }
       }
       &ty_box(tt) | &ty_uniq(tt) => {
         flags |= get(tt).flags
@@ -1434,14 +1427,12 @@ pub fn mk_ctor_fn(cx: &ctxt,
 pub fn mk_trait(cx: &ctxt,
                 did: ast::DefId,
                 substs: Substs,
-                store: TraitStore,
                 bounds: BuiltinBounds)
              -> t {
     // take a copy of substs so that we own the vectors inside
     let inner = box TyTrait {
         def_id: did,
         substs: substs,
-        store: store,
         bounds: bounds
     };
     mk_t(cx, ty_trait(inner))
@@ -1577,9 +1568,9 @@ fn type_is_slice(ty:t) -> bool {
 
 pub fn type_is_structural(ty: t) -> bool {
     match get(ty).sty {
-      ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_trait(..) |
+      ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) |
       ty_vec(_, Some(_)) => true,
-      _ => type_is_slice(ty)
+      _ => type_is_slice(ty) | type_is_trait(ty)
     }
 }
 
@@ -1635,7 +1626,7 @@ pub fn type_is_region_ptr(ty: t) -> bool {
         ty_rptr(_, mt) => match get(mt.ty).sty {
             // FIXME(nrc, DST) slices weren't regarded as rptrs, so we preserve this
             // odd behaviour for now. (But ~[] were unique. I have no idea why).
-            ty_vec(_, None) | ty_str => false,
+            ty_vec(_, None) | ty_str | ty_trait(..) => false,
             _ => true
         },
         _ => false
@@ -1651,7 +1642,10 @@ pub fn type_is_unsafe_ptr(ty: t) -> bool {
 
 pub fn type_is_unique(ty: t) -> bool {
     match get(ty).sty {
-        ty_uniq(_) => true,
+        ty_uniq(_) => match get(ty).sty {
+            ty_trait(..) => false,
+            _ => true
+        },
         _ => false
     }
 }
@@ -2060,8 +2054,8 @@ fn tc_ty(cx: &ctxt,
                 }
             }
 
-            ty_trait(box ty::TyTrait { store, bounds, .. }) => {
-                object_contents(cx, store, bounds)
+            ty_trait(box ty::TyTrait { bounds, .. }) => {
+                object_contents(cx, bounds)
             }
 
             ty_ptr(ref mt) => {
@@ -2185,7 +2179,16 @@ fn borrowed_contents(region: ty::Region,
     fn closure_contents(cx: &ctxt, cty: &ClosureTy) -> TypeContents {
         // Closure contents are just like trait contents, but with potentially
         // even more stuff.
-        let st = object_contents(cx, cty.store, cty.bounds);
+        let st = object_contents(cx, cty.bounds);
+
+        let st = match cty.store {
+            UniqTraitStore => {
+                st.owned_pointer()
+            }
+            RegionTraitStore(r, mutbl) => {
+                st.reference(borrowed_contents(r, mutbl))
+            }
+        };
 
         // This also prohibits "@once fn" from being copied, which allows it to
         // be called. Neither way really makes much sense.
@@ -2198,20 +2201,10 @@ fn closure_contents(cx: &ctxt, cty: &ClosureTy) -> TypeContents {
     }
 
     fn object_contents(cx: &ctxt,
-                       store: TraitStore,
                        bounds: BuiltinBounds)
                        -> TypeContents {
         // These are the type contents of the (opaque) interior
-        let contents = kind_bounds_to_contents(cx, bounds, []);
-
-        match store {
-            UniqTraitStore => {
-                contents.owned_pointer()
-            }
-            RegionTraitStore(r, mutbl) => {
-                contents.reference(borrowed_contents(r, mutbl))
-            }
-        }
+        kind_bounds_to_contents(cx, bounds, [])
     }
 
     fn kind_bounds_to_contents(cx: &ctxt,
@@ -2470,6 +2463,10 @@ fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
 
 pub fn type_is_trait(ty: t) -> bool {
     match get(ty).sty {
+        ty_uniq(ty) | ty_rptr(_, mt { ty, ..}) => match get(ty).sty {
+            ty_trait(..) => true,
+            _ => false
+        },
         ty_trait(..) => true,
         _ => false
     }
@@ -2559,7 +2556,7 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
     match get(t).sty {
         ty_box(typ) | ty_uniq(typ) => match get(typ).sty {
             // Don't deref ~[] etc., might need to generalise this to all DST.
-            ty_vec(_, None) | ty_str => None,
+            ty_vec(_, None) | ty_str | ty_trait(..) => None,
             _ => Some(mt {
                 ty: typ,
                 mutbl: ast::MutImmutable,
@@ -2567,7 +2564,7 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
         },
         ty_rptr(_, mt) => match get(mt.ty).sty {
             // Don't deref &[], might need to generalise this to all DST.
-            ty_vec(_, None) | ty_str => None,
+            ty_vec(_, None) | ty_str | ty_trait(..) => None,
             _ => Some(mt),
         },
         ty_ptr(mt) if explicit => Some(mt),
@@ -2888,7 +2885,19 @@ pub fn adjust_ty(cx: &ctxt,
                 }
 
                 AutoObject(store, bounds, def_id, ref substs) => {
-                    mk_trait(cx, def_id, substs.clone(), store, bounds)
+
+                    let tr = mk_trait(cx, def_id, substs.clone(), bounds);
+                    match store {
+                        UniqTraitStore => {
+                            mk_uniq(cx, tr)
+                        }
+                        RegionTraitStore(r, m) => {
+                            mk_rptr(cx, r, mt {
+                                ty: tr,
+                                mutbl: m
+                            })
+                        }
+                    }
                 }
             }
         }
@@ -2926,10 +2935,20 @@ fn borrow_vec(cx: &ctxt,
     fn borrow_obj(cx: &ctxt, span: Span, r: Region,
                   m: ast::Mutability, ty: ty::t) -> ty::t {
         match get(ty).sty {
-            ty_trait(box ty::TyTrait {def_id, ref substs, bounds, .. }) => {
-                ty::mk_trait(cx, def_id, substs.clone(),
-                             RegionTraitStore(r, m), bounds)
-            }
+            ty_uniq(t) | ty_rptr(_, mt{ty: t, ..}) => match get(t).sty {
+                ty_trait(box ty::TyTrait {def_id, ref substs, bounds, .. }) => {
+                    mk_rptr(cx, r, mt {
+                        ty: ty::mk_trait(cx, def_id, substs.clone(), bounds),
+                        mutbl: m
+                    })
+                }
+                _ => {
+                    cx.sess.span_bug(
+                        span,
+                        format!("borrow-trait-obj associated with bad sty: {:?}",
+                                get(ty).sty).as_slice());
+                }
+            },
             ref s => {
                 cx.sess.span_bug(
                     span,
@@ -4264,11 +4283,11 @@ pub fn visitor_object_ty(tcx: &ctxt,
     let substs = Substs::empty();
     let trait_ref = Rc::new(TraitRef { def_id: trait_lang_item, substs: substs });
     Ok((trait_ref.clone(),
-        mk_trait(tcx,
-                 trait_ref.def_id,
-                 trait_ref.substs.clone(),
-                 RegionTraitStore(region, ast::MutMutable),
-                 empty_builtin_bounds())))
+        mk_rptr(tcx, region, mt {mutbl: ast::MutMutable,
+                                 ty: mk_trait(tcx,
+                                              trait_ref.def_id,
+                                              trait_ref.substs.clone(),
+                                              empty_builtin_bounds()) })))
 }
 
 pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
@@ -4562,17 +4581,9 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
                     }
                 }
             }
-            ty_trait(box ty::TyTrait { def_id: d, store, bounds, .. }) => {
+            ty_trait(box ty::TyTrait { def_id: d, bounds, .. }) => {
                 byte!(17);
                 did(&mut state, d);
-                match store {
-                    UniqTraitStore => byte!(0),
-                    RegionTraitStore(r, m) => {
-                        byte!(1)
-                        region(&mut state, r);
-                        hash!(m);
-                    }
-                }
                 hash!(bounds);
             }
             ty_struct(d, _) => {
index e5fbe9df98f228228e3c39829d25b913ce8746be..2488d2da779b30c1b61cd8345d43c29fb11180bc 100644 (file)
@@ -364,13 +364,11 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_trait(box ty::TyTrait {
                 def_id,
                 ref substs,
-                store,
                 bounds
             }) => {
             ty::ty_trait(box ty::TyTrait {
                 def_id: def_id,
                 substs: substs.fold_with(this),
-                store: store.fold_with(this),
                 bounds: bounds
             })
         }
index f380004fb081e7cccf564928794eed18c9396812..7ca8a74ae636c4ef18bb27a959adb2e8ca5424dc 100644 (file)
@@ -584,10 +584,25 @@ fn mk_pointer<AC:AstConv,
             return constr(ty::mk_vec(tcx, mt, None));
         }
         ast::TyUnboxedFn(ref unboxed_function) => {
-            let trait_store = match ptr_ty {
-                Uniq => ty::UniqTraitStore,
+            let ty::TraitRef {
+                def_id,
+                substs
+            } = trait_ref_for_unboxed_function(this,
+                                               rscope,
+                                               &**unboxed_function,
+                                               None);
+            let tr = ty::mk_trait(this.tcx(),
+                                  def_id,
+                                  substs,
+                                  ty::empty_builtin_bounds());
+            match ptr_ty {
+                Uniq => {
+                    return ty::mk_uniq(this.tcx(), tr);
+                }
                 RPtr(r) => {
-                    ty::RegionTraitStore(r, a_seq_ty.mutbl)
+                    return ty::mk_rptr(this.tcx(),
+                                       r,
+                                       ty::mt {mutbl: a_seq_ty.mutbl, ty: tr});
                 }
                 _ => {
                     tcx.sess.span_err(
@@ -596,19 +611,8 @@ fn mk_pointer<AC:AstConv,
                          forms of casting-to-trait");
                     return ty::mk_err();
                 }
-            };
-            let ty::TraitRef {
-                def_id,
-                substs
-            } = trait_ref_for_unboxed_function(this,
-                                               rscope,
-                                               &**unboxed_function,
-                                               None);
-            return ty::mk_trait(this.tcx(),
-                                def_id,
-                                substs,
-                                trait_store,
-                                ty::empty_builtin_bounds());
+
+            }
         }
         ast::TyPath(ref path, ref bounds, id) => {
             // Note that the "bounds must be empty if path is not a trait"
@@ -651,11 +655,20 @@ fn mk_pointer<AC:AstConv,
                                                      path.span,
                                                      bounds,
                                                      trait_store);
-                    return ty::mk_trait(tcx,
-                                        result.def_id,
-                                        result.substs.clone(),
-                                        trait_store,
-                                        bounds);
+                    let tr = ty::mk_trait(tcx,
+                                          result.def_id,
+                                          result.substs.clone(),
+                                          bounds);
+                    // We could just match on ptr_ty, but we need to pass a trait
+                    // store to conv_builtin_bounds, so mathc twice for now.
+                    return match trait_store {
+                        ty::UniqTraitStore => {
+                            return ty::mk_uniq(tcx, tr);
+                        }
+                        ty::RegionTraitStore(r, m) => {
+                            return ty::mk_rptr(tcx, r, ty::mt{mutbl: m, ty: tr});
+                        }
+                    }
                 }
                 _ => {}
             }
index 3933c30d5c98b787f892d26ef2b71026e423f4b0..edb77e04b30786825ab507c5a5af0a9e58747cd2 100644 (file)
@@ -725,10 +725,10 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
         fcx.write_ty(pat_id, expected);
     };
     match *structure_of(fcx, span, expected) {
-        ty::ty_uniq(e_inner) if pointer_kind == Send => {
+        ty::ty_uniq(e_inner) if pointer_kind == Send && !ty::type_is_trait(e_inner) => {
             check_inner(e_inner);
         }
-        ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
+        ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed && !ty::type_is_trait(e_inner.ty) => {
             check_inner(e_inner.ty);
         }
         _ => {
index 864de344db2cdd12ccdd42ef0db2c24a6824fbcb..fafc84d2b10f08fce2b97a8559ef541d954551b9 100644 (file)
@@ -277,14 +277,14 @@ fn construct_transformed_self_ty_for_object(
             match ty::get(transformed_self_ty).sty {
                 ty::ty_rptr(r, mt) => { // must be SelfRegion
                     let r = r.subst(tcx, rcvr_substs); // handle Early-Bound lifetime
-                    ty::mk_trait(tcx, trait_def_id, obj_substs,
-                                 RegionTraitStore(r, mt.mutbl),
-                                 ty::empty_builtin_bounds())
+                    let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
+                                          ty::empty_builtin_bounds());
+                    ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: mt.mutbl })
                 }
                 ty::ty_uniq(_) => { // must be SelfUniq
-                    ty::mk_trait(tcx, trait_def_id, obj_substs,
-                                 UniqTraitStore,
-                                 ty::empty_builtin_bounds())
+                    let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
+                                          ty::empty_builtin_bounds());
+                    ty::mk_uniq(tcx, tr)
                 }
                 _ => {
                     tcx.sess.span_bug(span,
@@ -433,10 +433,13 @@ fn push_inherent_candidates(&mut self, self_ty: ty::t) {
         let span = self.self_expr.map_or(self.span, |e| e.span);
         check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
             match get(self_ty).sty {
-                ty_trait(box TyTrait { def_id, ref substs, .. }) => {
-                    self.push_inherent_candidates_from_object(def_id, substs);
-                    self.push_inherent_impl_candidates_for_type(def_id);
-                }
+                ty_uniq(ty) | ty_rptr(_, mt {ty, ..}) => match get(ty).sty{
+                    ty_trait(box TyTrait { def_id, ref substs, .. }) => {
+                        self.push_inherent_candidates_from_object(def_id, substs);
+                        self.push_inherent_impl_candidates_for_type(def_id);
+                    }
+                    _ => {}
+                },
                 ty_enum(did, _) | ty_struct(did, _) => {
                     if self.check_traits == CheckTraitsAndInherentMethods {
                         self.push_inherent_impl_candidates_for_type(did);
@@ -774,6 +777,7 @@ fn consider_reborrow(&self,
                 let (extra_derefs, auto) = match ty::get(self_mt.ty).sty {
                     ty::ty_vec(_, None) => (0, ty::AutoBorrowVec(region, self_mt.mutbl)),
                     ty::ty_str => (0, ty::AutoBorrowVec(region, self_mt.mutbl)),
+                    ty::ty_trait(..) => (0, ty::AutoBorrowObj(region, self_mt.mutbl)),
                     _ => (1, ty::AutoPtr(region, self_mt.mutbl)),
                 };
                 (ty::mk_rptr(tcx, region, self_mt),
@@ -781,18 +785,6 @@ fn consider_reborrow(&self,
                      autoderefs: autoderefs + extra_derefs,
                      autoref: Some(auto)})
             }
-
-            ty::ty_trait(box ty::TyTrait {
-                def_id, ref substs, store: ty::RegionTraitStore(_, mutbl), bounds
-            }) => {
-                let region =
-                    self.infcx().next_region_var(infer::Autoref(self.span));
-                (ty::mk_trait(tcx, def_id, substs.clone(),
-                              ty::RegionTraitStore(region, mutbl), bounds),
-                 ty::AutoDerefRef {
-                     autoderefs: autoderefs,
-                     autoref: Some(ty::AutoBorrowObj(region, mutbl))})
-            }
             _ => {
                 (self_ty,
                  ty::AutoDerefRef {
@@ -862,6 +854,26 @@ fn auto_slice_str(&self, autoderefs: uint) -> Option<MethodCallee> {
             })
     }
 
+    // Coerce Box/&Trait instances to &Trait.
+    fn auto_slice_trait(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
+        match ty::get(ty).sty {
+            ty_trait(box ty::TyTrait {
+                    def_id: trt_did,
+                    substs: ref trt_substs,
+                    bounds: b,
+                    .. }) => {
+                let tcx = self.tcx();
+                self.search_for_some_kind_of_autorefd_method(
+                    AutoBorrowObj, autoderefs, [MutImmutable, MutMutable],
+                    |m, r| {
+                        let tr = ty::mk_trait(tcx, trt_did, trt_substs.clone(), b);
+                        ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: m })
+                    })
+            }
+            _ => fail!("Expected ty_trait in auto_slice_trait")
+        }
+    }
+
     fn search_for_autosliced_method(&self,
                                     self_ty: ty::t,
                                     autoderefs: uint)
@@ -871,38 +883,23 @@ fn search_for_autosliced_method(&self,
          * `~[]` to `&[]`.
          */
 
-        let tcx = self.tcx();
-        debug!("search_for_autosliced_method {}", ppaux::ty_to_str(tcx, self_ty));
+        debug!("search_for_autosliced_method {}", ppaux::ty_to_str(self.tcx(), self_ty));
 
         let sty = ty::get(self_ty).sty.clone();
         match sty {
             ty_rptr(_, mt) => match ty::get(mt.ty).sty {
                 ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
+                ty_trait(..) => self.auto_slice_trait(mt.ty, autoderefs),
                 _ => None
             },
             ty_uniq(t) => match ty::get(t).sty {
                 ty_vec(mt, None) => self.auto_slice_vec(mt, autoderefs),
                 ty_str => self.auto_slice_str(autoderefs),
+                ty_trait(..) => self.auto_slice_trait(t, autoderefs),
                 _ => None
             },
             ty_vec(mt, Some(_)) => self.auto_slice_vec(mt, autoderefs),
 
-            ty_trait(box ty::TyTrait {
-                    def_id: trt_did,
-                    substs: trt_substs,
-                    bounds: b,
-                    ..
-                }) => {
-                // Coerce Box/&Trait instances to &Trait.
-
-                self.search_for_some_kind_of_autorefd_method(
-                    AutoBorrowObj, autoderefs, [MutImmutable, MutMutable],
-                    |m, r| {
-                        ty::mk_trait(tcx, trt_did, trt_substs.clone(),
-                                     RegionTraitStore(r, m), b)
-                    })
-            }
-
             ty_closure(..) => {
                 // This case should probably be handled similarly to
                 // Trait instances.
@@ -1313,17 +1310,15 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                     ty::ty_rptr(_, mt) => {
                         match ty::get(mt.ty).sty {
                             ty::ty_vec(_, None) | ty::ty_str => false,
+                            ty::ty_trait(box ty::TyTrait { def_id: self_did, .. }) => {
+                                mutability_matches(mt.mutbl, m) &&
+                                rcvr_matches_object(self_did, candidate)
+                            }
                             _ => mutability_matches(mt.mutbl, m) &&
                                  rcvr_matches_ty(self.fcx, mt.ty, candidate),
                         }
                     }
 
-                    ty::ty_trait(box ty::TyTrait {
-                        def_id: self_did, store: RegionTraitStore(_, self_m), ..
-                    }) => {
-                        mutability_matches(self_m, m) &&
-                        rcvr_matches_object(self_did, candidate)
-                    }
 
                     _ => false
                 }
@@ -1335,16 +1330,13 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                     ty::ty_uniq(typ) => {
                         match ty::get(typ).sty {
                             ty::ty_vec(_, None) | ty::ty_str => false,
+                            ty::ty_trait(box ty::TyTrait { def_id: self_did, .. }) => {
+                                rcvr_matches_object(self_did, candidate)
+                            }
                             _ => rcvr_matches_ty(self.fcx, typ, candidate),
                         }
                     }
 
-                    ty::ty_trait(box ty::TyTrait {
-                        def_id: self_did, store: UniqTraitStore, ..
-                    }) => {
-                        rcvr_matches_object(self_did, candidate)
-                    }
-
                     _ => false
                 }
             }
index 2516a00ff7655359d7269c6798c7d06fac7c0a60..9615372bef19b9ac2d9060722ced8f2d0029aa40 100644 (file)
@@ -3022,7 +3022,7 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
         else {
             match ty::get(t_1).sty {
                 // This will be looked up later on
-                ty::ty_trait(..) => (),
+                _ if ty::type_is_trait(t_1) => {},
 
                 _ => {
                     if ty::type_is_nil(t_e) {
index e8d507c8b4add36573dd368db83c79276185e31c..1069f0a67a2900e0636cd89f41ec0d4d24e37760 100644 (file)
@@ -546,15 +546,18 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             // explaining how it goes about doing that.
             let target_ty = rcx.resolve_node_type(expr.id);
             match ty::get(target_ty).sty {
-                ty::ty_trait(box ty::TyTrait {
-                    store: ty::RegionTraitStore(trait_region, _), ..
-                }) => {
-                    let source_ty = rcx.resolve_expr_type_adjusted(&**source);
-                    constrain_regions_in_type(
-                        rcx,
-                        trait_region,
-                        infer::RelateObjectBound(expr.span),
-                        source_ty);
+                ty::ty_rptr(trait_region, ty::mt{ty, ..}) => {
+                    match ty::get(ty).sty {
+                        ty::ty_trait(..) => {
+                            let source_ty = rcx.resolve_expr_type_adjusted(&**source);
+                            constrain_regions_in_type(
+                                rcx,
+                                trait_region,
+                                infer::RelateObjectBound(expr.span),
+                                source_ty);
+                        }
+                        _ => {}
+                    }
                 }
                 _ => ()
             }
index 7d2b9d9aa869747466e0547e3146d8122cef6726..fe79dabc3f8de8e8c4877ae6548dbaa64a860322 100644 (file)
@@ -302,6 +302,7 @@ fn search_for_vtable(vcx: &VtableContext,
                      trait_ref: Rc<ty::TraitRef>,
                      is_early: bool)
                      -> Option<vtable_origin> {
+    debug!("nrc - search_for_vtable");
     let tcx = vcx.tcx();
 
     let mut found = Vec::new();
@@ -464,7 +465,6 @@ fn fixup_substs(vcx: &VtableContext,
     // use a dummy type just to package up the substs that need fixing up
     let t = ty::mk_trait(tcx,
                          id, substs,
-                         ty::RegionTraitStore(ty::ReStatic, ast::MutImmutable),
                          ty::empty_builtin_bounds());
     fixup_ty(vcx, span, t, is_early).map(|t_f| {
         match ty::get(t_f).sty {
@@ -518,43 +518,50 @@ fn insert_vtables(fcx: &FnCtxt, vtable_key: MethodCall, vtables: vtable_res) {
 }
 
 pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
+    fn mutability_allowed(a_mutbl: ast::Mutability,
+                          b_mutbl: ast::Mutability) -> bool {
+        a_mutbl == b_mutbl ||
+        (a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
+    }
+
     debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
            ex.id, is_early, expr_to_str(ex));
     let _indent = indenter();
 
     let cx = fcx.ccx;
     let resolve_object_cast = |src: &ast::Expr, target_ty: ty::t| {
-      match ty::get(target_ty).sty {
-          // Bounds of type's contents are not checked here, but in kind.rs.
-          ty::ty_trait(box ty::TyTrait {
-              def_id: target_def_id, substs: ref target_substs, store, ..
-          }) => {
-              fn mutability_allowed(a_mutbl: ast::Mutability,
-                                    b_mutbl: ast::Mutability) -> bool {
-                  a_mutbl == b_mutbl ||
-                  (a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
-              }
-              // Look up vtables for the type we're casting to,
-              // passing in the source and target type.  The source
-              // must be a pointer type suitable to the object sigil,
-              // e.g.: `&x as &Trait` or `box x as Box<Trait>`
-              let ty = structurally_resolved_type(fcx, ex.span,
-                                                  fcx.expr_ty(src));
-              match (&ty::get(ty).sty, store) {
-                  (&ty::ty_rptr(_, mt), ty::RegionTraitStore(_, mutbl))
-                    if !mutability_allowed(mt.mutbl, mutbl) => {
+      // Look up vtables for the type we're casting to,
+      // passing in the source and target type.  The source
+      // must be a pointer type suitable to the object sigil,
+      // e.g.: `&x as &Trait` or `box x as Box<Trait>`
+      // Bounds of type's contents are not checked here, but in kind.rs.
+      let src_ty = structurally_resolved_type(fcx, ex.span,
+                                              fcx.expr_ty(src));
+      match (&ty::get(target_ty).sty, &ty::get(src_ty).sty) {
+          (&ty::ty_rptr(_, ty::mt{ty, mutbl}), &ty::ty_rptr(_, mt))
+            if !mutability_allowed(mt.mutbl, mutbl) => {
+              match ty::get(ty).sty {
+                  ty::ty_trait(..) => {
                       fcx.tcx()
                          .sess
                          .span_err(ex.span, "types differ in mutability");
                   }
+                  _ => {}
+              }
+          }
 
-                  (&ty::ty_uniq(..), ty::UniqTraitStore) |
-                  (&ty::ty_rptr(..), ty::RegionTraitStore(..)) => {
-                    let typ = match &ty::get(ty).sty {
-                        &ty::ty_box(typ) | &ty::ty_uniq(typ) => typ,
-                        &ty::ty_rptr(_, mt) => mt.ty,
-                        _ => fail!("shouldn't get here"),
-                    };
+          (&ty::ty_uniq(ty), &ty::ty_uniq(..) ) |
+          (&ty::ty_rptr(_, ty::mt{ty, ..}), &ty::ty_rptr(..)) => {
+              match ty::get(ty).sty {
+                  ty::ty_trait(box ty::TyTrait {
+                      def_id: target_def_id, substs: ref target_substs, ..
+                  }) => {
+                      debug!("nrc correct path");
+                      let typ = match &ty::get(src_ty).sty {
+                          &ty::ty_uniq(typ) => typ,
+                          &ty::ty_rptr(_, mt) => mt.ty,
+                          _ => fail!("shouldn't get here"),
+                      };
 
                       let vcx = fcx.vtable_context();
 
@@ -594,38 +601,49 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
 
                       // Now, if this is &trait, we need to link the
                       // regions.
-                      match (&ty::get(ty).sty, store) {
-                          (&ty::ty_rptr(ra, _),
-                           ty::RegionTraitStore(rb, _)) => {
+                      match (&ty::get(src_ty).sty, &ty::get(target_ty).sty) {
+                          (&ty::ty_rptr(ra, _), &ty::ty_rptr(rb, _)) => {
+                              debug!("nrc - make subr");
                               infer::mk_subr(fcx.infcx(),
                                              false,
-                                             infer::RelateObjectBound(
-                                                 ex.span),
+                                             infer::RelateObjectBound(ex.span),
                                              rb,
                                              ra);
                           }
                           _ => {}
                       }
                   }
+                  _ => {}
+              }
+          }
 
-                  (_, ty::UniqTraitStore) => {
+          (&ty::ty_uniq(ty), _) => {
+              match ty::get(ty).sty {
+                  ty::ty_trait(..) => {
                       fcx.ccx.tcx.sess.span_err(
                           ex.span,
                           format!("can only cast an boxed pointer \
                                    to a boxed object, not a {}",
-                               ty::ty_sort_str(fcx.tcx(), ty)).as_slice());
+                               ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
                   }
+                  _ => {}
+              }
 
-                  (_, ty::RegionTraitStore(..)) => {
+          }
+          (&ty::ty_rptr(_, ty::mt{ty, ..}), _) => {
+              match ty::get(ty).sty {
+                  ty::ty_trait(..) => {
                       fcx.ccx.tcx.sess.span_err(
                           ex.span,
                           format!("can only cast an &-pointer \
                                    to an &-object, not a {}",
-                                  ty::ty_sort_str(fcx.tcx(), ty)).as_slice());
+                                  ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
                   }
+                  _ => {}
               }
           }
-          _ => { /* not a cast to a trait; ignore */ }
+
+          _ => {}
       }
     };
     match ex.node {
@@ -716,9 +734,17 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                            ex.repr(fcx.tcx()),
                            is_early);
 
-                    let object_ty = ty::mk_trait(cx.tcx, def_id,
-                                                 substs.clone(),
-                                                 store, bounds);
+                    let trait_ty = ty::mk_trait(cx.tcx,
+                                                def_id,
+                                                substs.clone(),
+                                                bounds);
+                    let object_ty = match store {
+                        ty::UniqTraitStore => ty::mk_uniq(cx.tcx, trait_ty),
+                        ty::RegionTraitStore(r, m) => {
+                            ty::mk_rptr(cx.tcx, r, ty::mt {ty: trait_ty, mutbl: m})
+                        }
+                    };
+
                     resolve_object_cast(ex, object_ty);
                 }
                 AutoAddEnv(..) => {}
index 04bf939ceb8d147387e11ac675cfb9b83192b81c..b12e3b614d1be1dd9da7aa0d1244600390b519d4 100644 (file)
@@ -74,10 +74,16 @@ fn get_base_type(inference_context: &InferCtxt,
     }
 
     match get(resolved_type).sty {
-        ty_enum(..) | ty_trait(..) | ty_struct(..) => {
+        ty_enum(..) | ty_struct(..) => {
             debug!("(getting base type) found base type");
             Some(resolved_type)
         }
+        // FIXME(14865) I would prefere to use `_` here, but that causes a
+        // compiler error.
+        ty_uniq(_) | ty_rptr(_, _) | ty_trait(..) if ty::type_is_trait(resolved_type) => {
+            debug!("(getting base type) found base type (trait)");
+            Some(resolved_type)
+        }
 
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
         ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) |
@@ -87,6 +93,7 @@ fn get_base_type(inference_context: &InferCtxt,
                    get(original_type).sty);
             None
         }
+        ty_trait(..) => fail!("should have been caught")
     }
 }
 
@@ -108,18 +115,10 @@ fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
                     found_nominal = true;
                 }
             }
-            ty_trait(box ty::TyTrait { def_id, ref store, .. }) => {
+            ty_trait(box ty::TyTrait { def_id, .. }) => {
                 if def_id.krate == ast::LOCAL_CRATE {
                     found_nominal = true;
                 }
-                if *store == ty::UniqTraitStore {
-                    match tcx.lang_items.owned_box() {
-                        Some(did) if did.krate == ast::LOCAL_CRATE => {
-                            found_nominal = true;
-                        }
-                        _ => {}
-                    }
-                }
             }
             ty_uniq(..) => {
                 match tcx.lang_items.owned_box() {
@@ -150,16 +149,22 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
                         original_type: t)
                         -> Option<DefId> {
     match get_base_type(inference_context, span, original_type) {
-        None => {
-            return None;
-        }
+        None => None,
         Some(base_type) => {
             match get(base_type).sty {
                 ty_enum(def_id, _) |
-                ty_struct(def_id, _) |
-                ty_trait(box ty::TyTrait { def_id, .. }) => {
-                    return Some(def_id);
+                ty_struct(def_id, _) => {
+                    Some(def_id)
                 }
+                ty_rptr(_, ty::mt {ty, ..}) | ty_uniq(ty) => match ty::get(ty).sty {
+                    ty_trait(box ty::TyTrait { def_id, .. }) => {
+                        Some(def_id)
+                    }
+                    _ => {
+                        fail!("get_base_type() returned a type that wasn't an \
+                               enum, struct, or trait");
+                    }
+                },
                 _ => {
                     fail!("get_base_type() returned a type that wasn't an \
                            enum, struct, or trait");
index c03c7386fb3310648220bba50aa1b8902bf527b5..0568542472b791c161b17a9761cf5e15dde2c4f1 100644 (file)
@@ -100,7 +100,7 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
         // Note: does not attempt to resolve type variables we encounter.
         // See above for details.
         match ty::get(b).sty {
-            ty::ty_rptr(_, mt_b) => {
+            ty::ty_rptr(r_b, mt_b) => {
                 match ty::get(mt_b.ty).sty {
                     ty::ty_vec(mt_b, None) => {
                         return self.unpack_actual_value(a, |sty_a| {
@@ -113,6 +113,28 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
                             self.coerce_borrowed_string(a, sty_a, b)
                         });
                     }
+
+                    ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => {
+                        let result = self.unpack_actual_value(a, |sty_a| {
+                            match *sty_a {
+                                ty::ty_rptr(_, mt_a) => match ty::get(mt_a.ty).sty {
+                                    ty::ty_trait(..) => {
+                                        self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
+                                    }
+                                    _ => self.coerce_object(a, sty_a, b, def_id, substs,
+                                                            ty::RegionTraitStore(r_b, mt_b.mutbl),
+                                                            bounds)
+                                },
+                                _ => self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
+                            }
+                        });
+
+                        match result {
+                            Ok(t) => return Ok(t),
+                            Err(..) => {}
+                        }
+                    }
+
                     _ => {
                         return self.unpack_actual_value(a, |sty_a| {
                             self.coerce_borrowed_pointer(a, sty_a, b, mt_b)
@@ -121,6 +143,31 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
                 };
             }
 
+            ty::ty_uniq(t_b) => {
+                match ty::get(t_b).sty {
+                    ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => {
+                        let result = self.unpack_actual_value(a, |sty_a| {
+                            match *sty_a {
+                                ty::ty_uniq(t_a) => match ty::get(t_a).sty {
+                                    ty::ty_trait(..) => {
+                                        Err(ty::terr_mismatch)
+                                    }
+                                    _ => self.coerce_object(a, sty_a, b, def_id, substs,
+                                                            ty::UniqTraitStore, bounds)
+                                },
+                                _ => Err(ty::terr_mismatch)
+                            }
+                        });
+
+                        match result {
+                            Ok(t) => return Ok(t),
+                            Err(..) => {}
+                        }
+                    }
+                    _ => {}
+                }
+            }
+
             ty::ty_closure(box ty::ClosureTy {
                     store: ty::RegionTraitStore(..),
                     ..
@@ -136,44 +183,6 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
                 });
             }
 
-            ty::ty_trait(box ty::TyTrait {
-                def_id, ref substs, store: ty::UniqTraitStore, bounds
-            }) => {
-                let result = self.unpack_actual_value(a, |sty_a| {
-                    match *sty_a {
-                        ty::ty_uniq(..) => {
-                            self.coerce_object(a, sty_a, b, def_id, substs,
-                                               ty::UniqTraitStore, bounds)
-                        }
-                        _ => Err(ty::terr_mismatch)
-                    }
-                });
-
-                match result {
-                    Ok(t) => return Ok(t),
-                    Err(..) => {}
-                }
-            }
-
-            ty::ty_trait(box ty::TyTrait {
-                def_id, ref substs, store: ty::RegionTraitStore(region, m), bounds
-            }) => {
-                let result = self.unpack_actual_value(a, |sty_a| {
-                    match *sty_a {
-                        ty::ty_rptr(..) => {
-                            self.coerce_object(a, sty_a, b, def_id, substs,
-                                               ty::RegionTraitStore(region, m), bounds)
-                        }
-                        _ => self.coerce_borrowed_object(a, sty_a, b, m)
-                    }
-                });
-
-                match result {
-                    Ok(t) => return Ok(t),
-                    Err(..) => {}
-                }
-            }
-
             _ => {}
         }
 
@@ -335,15 +344,20 @@ fn coerce_borrowed_object(&self,
         let r_a = self.get_ref().infcx.next_region_var(coercion);
 
         let a_borrowed = match *sty_a {
-            ty::ty_trait(box ty::TyTrait {
-                    def_id,
-                    ref substs,
-                    bounds,
-                    ..
-                }) => {
-                ty::mk_trait(tcx, def_id, substs.clone(),
-                             ty::RegionTraitStore(r_a, b_mutbl), bounds)
-            }
+            ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
+                ty::ty_trait(box ty::TyTrait {
+                        def_id,
+                        ref substs,
+                        bounds,
+                        ..
+                    }) => {
+                    let tr = ty::mk_trait(tcx, def_id, substs.clone(), bounds);
+                    ty::mk_rptr(tcx, r_a, ty::mt{ mutbl: b_mutbl, ty: tr })
+                }
+                _ => {
+                    return self.subtype(a, b);
+                }
+            },
             _ => {
                 return self.subtype(a, b);
             }
index ac6851518083dcfd7a6fb34be94fd053676e519f..cc898ab9c66926fef84d69a6e4ac594c2b45d666 100644 (file)
@@ -378,17 +378,19 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
     // so, for example, &T and &[U] should not unify. In fact the only thing
     // &[U] should unify with is &[T]. We preserve that behaviour with this
     // check.
-    fn check_ptr_to_vec<C:Combine>(this: &C,
-                                   a: ty::t,
-                                   b: ty::t,
-                                   a_inner: ty::t,
-                                   b_inner: ty::t,
-                                   result: ty::t) -> cres<ty::t> {
+    fn check_ptr_to_unsized<C:Combine>(this: &C,
+                                       a: ty::t,
+                                       b: ty::t,
+                                       a_inner: ty::t,
+                                       b_inner: ty::t,
+                                       result: ty::t) -> cres<ty::t> {
         match (&ty::get(a_inner).sty, &ty::get(b_inner).sty) {
             (&ty::ty_vec(_, None), &ty::ty_vec(_, None)) |
-            (&ty::ty_str, &ty::ty_str) => Ok(result),
+            (&ty::ty_str, &ty::ty_str) |
+            (&ty::ty_trait(..), &ty::ty_trait(..)) => Ok(result),
             (&ty::ty_vec(_, None), _) | (_, &ty::ty_vec(_, None)) |
-            (&ty::ty_str, _) | (_, &ty::ty_str)
+            (&ty::ty_str, _) | (_, &ty::ty_str) |
+            (&ty::ty_trait(..), _) | (_, &ty::ty_trait(..))
                 => Err(ty::terr_sorts(expected_found(this, a, b))),
             _ => Ok(result),
         }
@@ -478,12 +480,10 @@ fn check_ptr_to_vec<C:Combine>(this: &C,
       if a_.def_id == b_.def_id => {
           debug!("Trying to match traits {:?} and {:?}", a, b);
           let substs = if_ok!(this.substs(a_.def_id, &a_.substs, &b_.substs));
-          let s = if_ok!(this.trait_stores(ty::terr_trait, a_.store, b_.store));
           let bounds = if_ok!(this.bounds(a_.bounds, b_.bounds));
           Ok(ty::mk_trait(tcx,
                           a_.def_id,
                           substs.clone(),
-                          s,
                           bounds))
       }
 
@@ -499,18 +499,28 @@ fn check_ptr_to_vec<C:Combine>(this: &C,
 
       (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
             let typ = if_ok!(this.tys(a_inner, b_inner));
-            check_ptr_to_vec(this, a, b, a_inner, b_inner, ty::mk_uniq(tcx, typ))
+            check_ptr_to_unsized(this, a, b, a_inner, b_inner, ty::mk_uniq(tcx, typ))
       }
 
       (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => {
             let mt = if_ok!(this.mts(a_mt, b_mt));
-            check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_ptr(tcx, mt))
+            check_ptr_to_unsized(this, a, b, a_mt.ty, b_mt.ty, ty::mk_ptr(tcx, mt))
       }
 
       (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
             let r = if_ok!(this.contraregions(a_r, b_r));
-            let mt = if_ok!(this.mts(a_mt, b_mt));
-            check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_rptr(tcx, r, mt))
+            // FIXME(14985)  If we have mutable references to trait objects, we
+            // used to use covariant subtyping. I have preserved this behaviour,
+            // even though it is probably incorrect. So don't go down the usual
+            // path which would require invariance.
+            let mt = match (&ty::get(a_mt.ty).sty, &ty::get(b_mt.ty).sty) {
+                (&ty::ty_trait(..), &ty::ty_trait(..)) if a_mt.mutbl == b_mt.mutbl => {
+                    let ty = if_ok!(this.tys(a_mt.ty, b_mt.ty));
+                    ty::mt { ty: ty, mutbl: a_mt.mutbl }
+                }
+                _ => if_ok!(this.mts(a_mt, b_mt))
+            };
+            check_ptr_to_unsized(this, a, b, a_mt.ty, b_mt.ty, ty::mk_rptr(tcx, r, mt))
       }
 
       (&ty::ty_vec(ref a_mt, sz_a), &ty::ty_vec(ref b_mt, sz_b)) => {
index f43ee1e8aabaac2c2929ef278d052b6fd27a17c8..7a7dbaa549a5cff0b515814be3b9a17925c8b1e5 100644 (file)
@@ -694,7 +694,6 @@ pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
         let dummy0 = ty::mk_trait(self.tcx,
                                   trait_ref.def_id,
                                   trait_ref.substs.clone(),
-                                  ty::UniqTraitStore,
                                   ty::empty_builtin_bounds());
         let dummy1 = self.resolve_type_vars_if_possible(dummy0);
         match ty::get(dummy1).sty {
index ac8ca05f8d0162935091903d113a38967eefc4c9..6e9ee92c0a35e812b798eb9e18b96644ecfe0e6b 100644 (file)
@@ -390,7 +390,7 @@ fn push_sig_to_str(cx: &ctxt,
           parameterized(cx, base.as_slice(), substs, &generics)
       }
       ty_trait(box ty::TyTrait {
-          def_id: did, ref substs, store, ref bounds
+          def_id: did, ref substs, ref bounds
       }) => {
           let base = ty::item_path_str(cx, did);
           let trait_def = ty::lookup_trait_def(cx, did);
@@ -398,8 +398,7 @@ fn push_sig_to_str(cx: &ctxt,
                                  substs, &trait_def.generics);
           let bound_sep = if bounds.is_empty() { "" } else { ":" };
           let bound_str = bounds.repr(cx);
-          format!("{}{}{}{}",
-                  trait_store_to_str(cx, store),
+          format!("{}{}{}",
                   ty,
                   bound_sep,
                   bound_str)
index 6ea7cde3b27dae96d845e7ae386863dc728c0b13..fa8d341e05de2b60174427a60be1fc7637016479 100644 (file)
@@ -233,7 +233,7 @@ fn main() {
 use std::fmt;
 use std::io::MemWriter;
 use std::io;
-use std::mem::swap;
+use std::mem::{swap,transmute};
 use std::num;
 use std::str::ScalarValue;
 use std::str;
@@ -369,10 +369,11 @@ pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
     pub fn buffer_encode<T:Encodable<Encoder<'a>, io::IoError>>(to_encode_object: &T) -> Vec<u8>  {
        //Serialize the object in a string using a writer
         let mut m = MemWriter::new();
-        {
+        // FIXME(14302) remove the transmute and unsafe block.
+        unsafe {
             let mut encoder = Encoder::new(&mut m as &mut io::Writer);
             // MemWriter never Errs
-            let _ = to_encode_object.encode(&mut encoder);
+            let _ = to_encode_object.encode(transmute(&mut encoder));
         }
         m.unwrap()
     }
@@ -543,8 +544,11 @@ fn emit_map_elt_key(&mut self,
         // ref #12967, make sure to wrap a key in double quotes,
         // in the event that its of a type that omits them (eg numbers)
         let mut buf = MemWriter::new();
-        let mut check_encoder = Encoder::new(&mut buf);
-        try!(f(&mut check_encoder));
+        // FIXME(14302) remove the transmute and unsafe block.
+        unsafe {
+            let mut check_encoder = Encoder::new(&mut buf);
+            try!(f(transmute(&mut check_encoder)));
+        }
         let buf = buf.unwrap();
         let out = from_utf8(buf.as_slice()).unwrap();
         let needs_wrapping = out.char_at(0) != '"' &&
@@ -778,8 +782,11 @@ fn emit_map_elt_key(&mut self,
         // ref #12967, make sure to wrap a key in double quotes,
         // in the event that its of a type that omits them (eg numbers)
         let mut buf = MemWriter::new();
-        let mut check_encoder = PrettyEncoder::new(&mut buf);
-        try!(f(&mut check_encoder));
+        // FIXME(14302) remove the transmute and unsafe block.
+        unsafe {
+            let mut check_encoder = PrettyEncoder::new(&mut buf);
+            try!(f(transmute(&mut check_encoder)));
+        }
         let buf = buf.unwrap();
         let out = from_utf8(buf.as_slice()).unwrap();
         let needs_wrapping = out.char_at(0) != '"' &&
index 372f69b805a2af03878a112cac40cff8ca76bcc9..d28553da69173b3b5ee20ecac72292328d673cac 100644 (file)
@@ -11,6 +11,8 @@
 use ast::*;
 use ast;
 use ast_util;
+use attr::{InlineNever, InlineNone};
+use attr;
 use codemap;
 use codemap::Span;
 use owned_slice::OwnedSlice;
@@ -742,6 +744,17 @@ pub fn get_inner_tys(ty: P<Ty>) -> Vec<P<Ty>> {
     }
 }
 
+/// Returns true if the static with the given mutability and attributes
+/// has a significant address and false otherwise.
+pub fn static_has_significant_address(mutbl: ast::Mutability,
+                                              attrs: &[ast::Attribute])
+                                              -> bool {
+    if mutbl == ast::MutMutable {
+        return true
+    }
+    let inline = attr::find_inline_attr(attrs);
+    inline == InlineNever || inline == InlineNone
+}
 
 #[cfg(test)]
 mod test {
index 31dd07f463c63d1f477dd4ca58806448b80d135f..18a91fe465ec53bc37d0bd40a145a76da08f6fcc 100644 (file)
@@ -271,21 +271,6 @@ pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
     }).collect()
 }
 
-/**
- * From a list of crate attributes get only the meta_items that affect crate
- * linkage
- */
-pub fn find_linkage_metas(attrs: &[Attribute]) -> Vec<Gc<MetaItem>> {
-    let mut result = Vec::new();
-    for attr in attrs.iter().filter(|at| at.check_name("link")) {
-        match attr.meta().node {
-            MetaList(_, ref items) => result.push_all(items.as_slice()),
-            _ => ()
-        }
-    }
-    result
-}
-
 pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
     match first_attr_value_str_by_name(attrs, "crate_id") {
         None => None,
index 33ea186db35c4257710efb91ce807e2c86ce8533..857eadfe57cc40ea9081dbf35136eb20baa47547 100644 (file)
@@ -312,14 +312,6 @@ fn verify_same(&self,
     /// These attributes are applied to all statics that this syntax extension
     /// will generate.
     fn static_attrs(&self) -> Vec<ast::Attribute> {
-        // Flag statics as `address_insignificant` so LLVM can merge duplicate
-        // globals as much as possible (which we're generating a whole lot of).
-        let unnamed = self.ecx
-                          .meta_word(self.fmtsp,
-                                     InternedString::new(
-                                         "address_insignificant"));
-        let unnamed = self.ecx.attribute(self.fmtsp, unnamed);
-
         // Do not warn format string as dead code
         let dead_code = self.ecx.meta_word(self.fmtsp,
                                            InternedString::new("dead_code"));
@@ -327,7 +319,7 @@ fn static_attrs(&self) -> Vec<ast::Attribute> {
                                                  InternedString::new("allow"),
                                                  vec!(dead_code));
         let allow_dead_code = self.ecx.attribute(self.fmtsp, allow_dead_code);
-        return vec!(unnamed, allow_dead_code);
+        return vec!(allow_dead_code);
     }
 
     fn rtpath(&self, s: &str) -> Vec<ast::Ident> {
index faffc496846038fbdcc8f0a3ff12fb431d0523fb..eb0c6f2555aee1360754fec4442982ffbaa5a31f 100644 (file)
@@ -281,6 +281,7 @@ mod test {
     use serialize::{json, Encodable};
     use std::io;
     use std::io::MemWriter;
+    use std::mem::transmute;
     use std::str;
     use std::gc::GC;
     use codemap::{Span, BytePos, Spanned};
@@ -295,8 +296,11 @@ mod test {
 
     fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> String {
         let mut writer = MemWriter::new();
-        let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
-        let _ = val.encode(&mut encoder);
+        // FIXME(14302) remove the transmute and unsafe block.
+        unsafe {
+            let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
+            let _ = val.encode(transmute(&mut encoder));
+        }
         str::from_utf8(writer.unwrap().as_slice()).unwrap().to_string()
     }
 
index 08e3eff0c8c5f7f6a967d070ea6a108d0e9e6a49..9e62415a20b4e8d6b615980ecc188d6d5088099a 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 pub fn foo<T>() -> int {
-    #[address_insignificant]
     static a: int = 3;
     a
 }
index b6cbae2d2afedbf7261fa1fd34ca08f4baae771b..13705107cfe8ec6a3c3fa9b14beb9f30ceb1d9a3 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[inline(never)]
 pub static global: int = 3;
 
+#[inline(never)]
 static global0: int = 4;
+
+#[inline(never)]
 pub static global2: &'static int = &global0;
 
 pub fn verify_same(a: &'static int) {