about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlavio Percoco <flaper87@gmail.com>2015-02-18 01:49:16 +0100
committerFlavio Percoco <flaper87@gmail.com>2015-02-22 02:14:26 +0100
commitd215411911c2f6e5a68a12686c930352f68d2031 (patch)
treef47b729649ea48f3bd112d4fc088106a93b396aa
parent1e3ed61d8273377544e40bdbbdf8391b51571293 (diff)
downloadrust-d215411911c2f6e5a68a12686c930352f68d2031.tar.gz
rust-d215411911c2f6e5a68a12686c930352f68d2031.zip
Make Send/Sync go through the default implementation path
-rw-r--r--src/librustc/middle/traits/select.rs38
-rw-r--r--src/librustc/middle/ty.rs5
-rw-r--r--src/librustc_resolve/lib.rs2
3 files changed, 27 insertions, 18 deletions
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 666c7c91070..6462f3830a1 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -824,24 +824,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                                             stack,
                                                             &mut candidates));
             }
-            Some(bound @ ty::BoundSend) |
-            Some(bound @ ty::BoundSync) => {
-                // Ideally, we shouldn't sepcial case Send/Sync. This will be unified
-                // as soon as default trait implementations for these traits land.
-                try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
-
-                // No explicit impls were declared for this type, consider the fallback rules.
-                if candidates.vec.is_empty() && !candidates.ambiguous {
-                    try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
-                }
-            }
-
             Some(bound @ ty::BoundSized) => {
                 // Sized and Copy are always automatically computed.
                 try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
             }
 
-            None => {
+            _ => {
                 // For the time being, we ignore user-defined impls for builtin-bounds, other than
                 // `Copy`.
                 // (And unboxed candidates only apply to the Fn/FnMut/etc traits.)
@@ -1149,8 +1137,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             });
         }
 
-        if ty::trait_has_default_impl(self.tcx(), def_id) {
-            candidates.vec.push(DefaultImplCandidate(def_id.clone()))
+        match self_ty.sty {
+            ty::ty_infer(ty::TyVar(_)) |
+            ty::ty_trait(..) => {},
+            _ => {
+                if ty::trait_has_default_impl(self.tcx(), def_id) {
+                    candidates.vec.push(DefaultImplCandidate(def_id.clone()))
+                }
+            }
         }
 
         Ok(())
@@ -1179,6 +1173,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let poly_trait_ref = match self_ty.sty {
             ty::ty_trait(ref data) => {
+                match self.tcx().lang_items.to_builtin_kind(obligation.predicate.def_id()) {
+                    Some(bound @ ty::BoundSend) | Some(bound @ ty::BoundSync) => {
+                        if data.bounds.builtin_bounds.contains(&bound) {
+                            debug!("assemble_candidates_from_object_ty: matched builtin bound, \
+                            pushing candidate");
+                            candidates.vec.push(BuiltinCandidate(bound));
+                            return;
+                        }
+                    }
+                    _ => {}
+                }
+
                 data.principal_trait_ref_with_self_ty(self.tcx(), self_ty)
             }
             ty::ty_infer(ty::TyVar(_)) => {
@@ -1622,13 +1628,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::ty_bare_fn(..) |
             ty::ty_str |
             ty::ty_err |
+            ty::ty_param(..) |
             ty::ty_char => {
                 Vec::new()
             }
 
             ty::ty_trait(..) |
             ty::ty_projection(..) |
-            ty::ty_param(..) |
             ty::ty_infer(..) => {
                 self.tcx().sess.bug(
                     &format!(
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 71d484866a9..3f8e283b209 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -6007,7 +6007,10 @@ pub fn trait_default_impl(tcx: &ctxt, trait_def_id: DefId) -> Option<ast::DefId>
 }
 
 pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
-    tcx.default_trait_impls.borrow().contains_key(&trait_def_id)
+    match tcx.lang_items.to_builtin_kind(trait_def_id) {
+        Some(BoundSend) | Some(BoundSync) => true,
+        _ => tcx.default_trait_impls.borrow().contains_key(&trait_def_id)
+    }
 }
 
 /// Records a trait-to-implementation mapping.
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ea99ad6a18a..bd1c8e1ba12 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2989,7 +2989,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // check for imports shadowing primitive types
                 if let ast::ViewPathSimple(ident, _) = view_path.node {
                     match self.def_map.borrow().get(&item.id) {
-                        Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefTrait(..)) | None => {
+                        Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefaultImpl(..)) | None => {
                             self.check_if_primitive_type_name(ident.name, item.span);
                         }
                         _ => {}