]> git.lizzy.rs Git - rust.git/commitdiff
Looser restrictions on what can be captured in unbounded traits.
authorBen Blum <bblum@andrew.cmu.edu>
Thu, 20 Jun 2013 02:06:50 +0000 (22:06 -0400)
committerBen Blum <bblum@andrew.cmu.edu>
Wed, 26 Jun 2013 22:14:43 +0000 (18:14 -0400)
src/libextra/test.rs
src/librustc/middle/kind.rs
src/librustc/middle/ty.rs

index e058a098fa49edff200dfbf93de0db0565e81a08..ee0d3649467bf6b47669129e8cd553d3d0046fd6 100644 (file)
@@ -423,7 +423,7 @@ enum TestEvent {
 
 fn run_tests(opts: &TestOpts,
              tests: ~[TestDescAndFn],
-             callback: @fn(e: TestEvent)) {
+             callback: &fn(e: TestEvent)) {
 
     let filtered_tests = filter_tests(opts, tests);
     let filtered_descs = filtered_tests.map(|t| copy t.desc);
index 1c669631244c36a7c0294d480e3198d266f6dce3..4dde982c34ca238b032c9a38caa1e1200a2bf6f3 100644 (file)
@@ -293,9 +293,9 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt<Context>)) {
         expr_cast(source, _) => {
             check_cast_for_escaping_regions(cx, source, e);
             match ty::get(ty::expr_ty(cx.tcx, e)).sty {
-                ty::ty_trait(_, _, store, _, bounds) => {
+                ty::ty_trait(_, _, _, _, bounds) => {
                     let source_ty = ty::expr_ty(cx.tcx, source);
-                    check_trait_cast_bounds(cx, e.span, source_ty, bounds, store)
+                    check_trait_cast_bounds(cx, e.span, source_ty, bounds)
                 }
                 _ => { }
             }
@@ -391,7 +391,7 @@ pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t,
 }
 
 pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t,
-                               bounds: ty::BuiltinBounds, store: ty::TraitStore) {
+                               bounds: ty::BuiltinBounds) {
     do check_builtin_bounds(cx, ty, bounds) |missing| {
         cx.tcx.sess.span_err(sp,
             fmt!("cannot pack type `%s`, which does not fulfill \
@@ -399,11 +399,6 @@ pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t,
                  ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx),
                  bounds.user_string(cx.tcx)));
     }
-    // FIXME(#3569): Remove this check when the corresponding restriction
-    // is made with type contents.
-    if store == ty::UniqTraitStore && !ty::type_is_owned(cx.tcx, ty) {
-        cx.tcx.sess.span_err(sp, "uniquely-owned trait objects must be sendable");
-    }
 }
 
 fn is_nullary_variant(cx: Context, ex: @expr) -> bool {
index a43025e4ff9791ad93a5fc5286f28af56b064d7d..9e6d9e167cd6a388c6b1ef59152b83cfeacceb74 100644 (file)
@@ -2063,20 +2063,8 @@ fn tc_ty(cx: ctxt,
                 TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
             }
 
-            ty_trait(_, _, UniqTraitStore, _, _bounds) => {
-                // FIXME(#3569): Make this conditional on the trait's bounds.
-                TC_NONCOPY_TRAIT + TC_OWNED_POINTER
-            }
-
-            ty_trait(_, _, BoxTraitStore, mutbl, _bounds) => {
-                match mutbl {
-                    ast::m_mutbl => TC_MANAGED + TC_MUTABLE,
-                    _ => TC_MANAGED
-                }
-            }
-
-            ty_trait(_, _, RegionTraitStore(r), mutbl, _bounds) => {
-                borrowed_contents(r, mutbl)
+            ty_trait(_, _, store, mutbl, bounds) => {
+                trait_contents(store, mutbl, bounds)
             }
 
             ty_rptr(r, mt) => {
@@ -2278,6 +2266,35 @@ fn closure_contents(cty: &ClosureTy) -> TypeContents {
         st + rt + ot
     }
 
+    fn trait_contents(store: TraitStore, mutbl: ast::mutability,
+                      bounds: BuiltinBounds) -> TypeContents {
+        let st = match store {
+            UniqTraitStore      => TC_OWNED_POINTER,
+            BoxTraitStore       => TC_MANAGED,
+            RegionTraitStore(r) => borrowed_contents(r, mutbl),
+        };
+        let mt = match mutbl { ast::m_mutbl => TC_MUTABLE, _ => TC_NONE };
+        // We get additional "special type contents" for each bound that *isn't*
+        // on the trait. So iterate over the inverse of the bounds that are set.
+        // This is like with typarams below, but less "pessimistic" and also
+        // dependent on the trait store.
+        let mut bt = TC_NONE;
+        for (AllBuiltinBounds() - bounds).each |bound| {
+            bt = bt + match bound {
+                BoundCopy if store == UniqTraitStore
+                            => TC_NONCOPY_TRAIT,
+                BoundCopy   => TC_NONE, // @Trait/&Trait are copyable either way
+                BoundStatic if bounds.contains_elem(BoundOwned)
+                            => TC_NONE, // Owned bound implies static bound.
+                BoundStatic => TC_BORROWED_POINTER, // Useful for "@Trait:'static"
+                BoundOwned  => TC_NON_OWNED,
+                BoundConst  => TC_MUTABLE,
+                BoundSized  => TC_NONE, // don't care if interior is sized
+            };
+        }
+        st + mt + bt
+    }
+
     fn type_param_def_to_contents(cx: ctxt,
                                   type_param_def: &TypeParameterDef) -> TypeContents
     {