about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2015-02-13 15:15:05 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2015-02-18 08:19:21 +1100
commitcae969e2a755bd7e8ec22758a8a02146ddb599a4 (patch)
treee861a8a0c9cb6d40fa5bb3e3c40fa60bfa98b25a /src
parentf9aeea7cb7865a2b82e7102837daabbe549177ea (diff)
downloadrust-cae969e2a755bd7e8ec22758a8a02146ddb599a4.tar.gz
rust-cae969e2a755bd7e8ec22758a8a02146ddb599a4.zip
Remove the implicit `'static` bound on `Send`.
Previously Send was defined as `trait Send: 'static {}`. As detailed in
https://github.com/rust-lang/rfcs/pull/458, the `'static` bound is not
actually necessary for safety, we can use lifetimes to enforce that more
flexibly.

`unsafe` code that was previously relying on `Send` to insert a
`'static` bound now may allow incorrect patterns, and so should be
audited (a quick way to ensure safety immediately and postpone the audit
is to add an explicit `'static` bound to any uses of the `Send` type).

cc #22251.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/marker.rs10
-rw-r--r--src/librustc/middle/traits/select.rs32
-rw-r--r--src/librustc/util/ppaux.rs5
3 files changed, 15 insertions, 32 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index da93d4f6ca4..f5b42b3c858 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -32,9 +32,19 @@ use clone::Clone;
            reason = "will be overhauled with new lifetime rules; see RFC 458")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(stage0)] // SNAP ac134f7 remove after stage0
 pub unsafe trait Send: 'static {
     // empty.
 }
+/// Types able to be transferred across thread boundaries.
+#[unstable(feature = "core",
+           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[lang="send"]
+#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(not(stage0))]
+pub unsafe trait Send {
+    // empty.
+}
 
 /// Types with a constant size known at compile-time.
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 6f58f4655fe..061557eb7dc 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -20,7 +20,7 @@ use self::EvaluationResult::*;
 use super::{DerivedObligationCause};
 use super::{project};
 use super::project::Normalized;
-use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
+use super::{PredicateObligation, TraitObligation, ObligationCause};
 use super::{ObligationCauseCode, BuiltinDerivedObligation};
 use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
 use super::{Selection};
@@ -34,7 +34,7 @@ use super::{util};
 use middle::fast_reject;
 use middle::mem_categorization::Typer;
 use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
-use middle::ty::{self, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
+use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
 use middle::infer;
 use middle::infer::{InferCtxt, TypeFreshener};
 use middle::ty_fold::TypeFoldable;
@@ -1459,22 +1459,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                     ty::BoundSync |
                     ty::BoundSend => {
-                        // Note: technically, a region pointer is only
-                        // sendable if it has lifetime
-                        // `'static`. However, we don't take regions
-                        // into account when doing trait matching:
-                        // instead, when we decide that `T : Send`, we
-                        // will register a separate constraint with
-                        // the region inferencer that `T : 'static`
-                        // holds as well (because the trait `Send`
-                        // requires it). This will ensure that there
-                        // is no borrowed data in `T` (or else report
-                        // an inference error). The reason we do it
-                        // this way is that we do not yet *know* what
-                        // lifetime the borrowed reference has, since
-                        // we haven't finished running inference -- in
-                        // other words, there's a kind of
-                        // chicken-and-egg problem.
                         Ok(If(vec![referent_ty]))
                     }
                 }
@@ -1817,21 +1801,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             })
         }).collect::<Result<_, _>>();
-        let mut obligations = match obligations {
+        let obligations = match obligations {
             Ok(o) => o,
             Err(ErrorReported) => Vec::new()
         };
 
-        // as a special case, `Send` requires `'static`
-        if bound == ty::BoundSend {
-            obligations.push(Obligation {
-                cause: obligation.cause.clone(),
-                recursion_depth: obligation.recursion_depth+1,
-                predicate: ty::Binder(ty::OutlivesPredicate(obligation.self_ty(),
-                                                            ty::ReStatic)).as_predicate(),
-            });
-        }
-
         let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
 
         debug!("vtable_builtin_data: obligations={}",
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 0363978bada..426101e858a 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -697,9 +697,8 @@ impl<'tcx> UserString<'tcx> for ty::TyTrait<'tcx> {
         }
 
         // Region, if not obviously implied by builtin bounds.
-        if bounds.region_bound != ty::ReStatic ||
-            !bounds.builtin_bounds.contains(&ty::BoundSend)
-        { // Region bound is implied by builtin bounds:
+        if bounds.region_bound != ty::ReStatic {
+            // Region bound is implied by builtin bounds:
             components.push(bounds.region_bound.user_string(tcx));
         }