about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/clone.rs60
-rw-r--r--src/libcore/marker.rs40
-rw-r--r--src/librustc/traits/select.rs10
-rw-r--r--src/librustc/ty/util.rs7
-rw-r--r--src/librustc_typeck/diagnostics.rs8
-rw-r--r--src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs2
-rw-r--r--src/test/run-make-fulldeps/simd-ffi/simd.rs3
-rw-r--r--src/test/ui/coherence-impls-copy.rs8
-rw-r--r--src/test/ui/coherence-impls-copy.stderr60
-rw-r--r--src/test/ui/error-codes/E0206.rs4
-rw-r--r--src/test/ui/error-codes/E0206.stderr4
11 files changed, 176 insertions, 30 deletions
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index d25f498b99e..5c83dd79bd7 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -135,3 +135,63 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: ::marker::PhantomData
            reason = "deriving hack, should not be public",
            issue = "0")]
 pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T> }
+
+/// Implementations of `Clone` for primitive types.
+///
+/// Implementations that cannot be described in Rust
+/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+#[cfg(not(stage0))]
+mod impls {
+
+    use super::Clone;
+
+    macro_rules! impl_clone {
+        ($($t:ty)*) => {
+            $(
+                #[stable(feature = "rust1", since = "1.0.0")]
+                impl Clone for $t {
+                    fn clone(&self) -> Self {
+                        *self
+                    }
+                }
+            )*
+        }
+    }
+
+    impl_clone! {
+        usize u8 u16 u32 u64 u128
+        isize i8 i16 i32 i64 i128
+        f32 f64
+        bool char
+    }
+
+    #[stable(feature = "never_type", since = "1.26.0")]
+    impl Clone for ! {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Clone for *const T {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Clone for *mut T {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    // Shared references can be cloned, but mutable references *cannot*!
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized> Clone for &'a T {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+}
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 7d0174a178a..008cb15131d 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -593,3 +593,43 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 /// This trait is automatically implemented for almost every type.
 #[unstable(feature = "pin", issue = "49150")]
 pub unsafe auto trait Unpin {}
+
+/// Implementations of `Copy` for primitive types.
+///
+/// Implementations that cannot be described in Rust
+/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+#[cfg(not(stage0))]
+mod copy_impls {
+
+    use super::Copy;
+
+    macro_rules! impl_copy {
+        ($($t:ty)*) => {
+            $(
+                #[stable(feature = "rust1", since = "1.0.0")]
+                impl Copy for $t {}
+            )*
+        }
+    }
+
+    impl_copy! {
+        usize u8 u16 u32 u64 u128
+        isize i8 i16 i32 i64 i128
+        f32 f64
+        bool char
+    }
+
+    #[stable(feature = "never_type", since = "1.26.0")]
+    impl Copy for ! {}
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Copy for *const T {}
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Copy for *mut T {}
+
+    // Shared references can be copied, but mutable references *cannot*!
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized> Copy for &'a T {}
+
+}
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 11daa96134c..8a585d6ac14 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2061,11 +2061,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
         match self_ty.sty {
             ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
+            ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyError => {
+                Where(ty::Binder(Vec::new()))
+            }
+
             ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
-            ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
-            ty::TyRawPtr(..) | ty::TyError | ty::TyNever |
+            ty::TyChar | ty::TyRawPtr(..) | ty::TyNever |
             ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
-                Where(ty::Binder(Vec::new()))
+                // Implementations provided in libcore
+                None
             }
 
             ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) |
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index afe977d10ba..22f851a908b 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -197,7 +197,14 @@ impl<'tcx> ty::ParamEnv<'tcx> {
         // FIXME: (@jroesch) float this code up
         tcx.infer_ctxt().enter(|infcx| {
             let (adt, substs) = match self_type.sty {
+                // These types used to have a builtin impl.
+                // Now libcore provides that impl.
+                ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
+                ty::TyChar | ty::TyRawPtr(..) | ty::TyNever |
+                ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => return Ok(()),
+
                 ty::TyAdt(adt, substs) => (adt, substs),
+
                 _ => return Err(CopyImplementationError::NotAnAdt),
             };
 
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 1f882676f61..691e0ffb6a5 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1918,16 +1918,16 @@ differs from the behavior for `&T`, which is always `Copy`).
 
 E0206: r##"
 You can only implement `Copy` for a struct or enum. Both of the following
-examples will fail, because neither `i32` (primitive type) nor `&'static Bar`
-(reference to `Bar`) is a struct or enum:
+examples will fail, because neither `[u8; 256]` nor `&'static mut Bar`
+(mutable reference to `Bar`) is a struct or enum:
 
 ```compile_fail,E0206
-type Foo = i32;
+type Foo = [u8; 256];
 impl Copy for Foo { } // error
 
 #[derive(Copy, Clone)]
 struct Bar;
-impl Copy for &'static Bar { } // error
+impl Copy for &'static mut Bar { } // error
 ```
 "##,
 
diff --git a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
index b41e8e9226b..54f888b3796 100644
--- a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
+++ b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
@@ -23,6 +23,8 @@ trait Copy {}
 #[lang = "freeze"]
 trait Freeze {}
 
+impl<T: ?Sized> Copy for *mut T {}
+
 #[cfg(target_has_atomic = "8")]
 pub unsafe fn atomic_u8(x: *mut u8) {
     atomic_xadd(x, 1);
diff --git a/src/test/run-make-fulldeps/simd-ffi/simd.rs b/src/test/run-make-fulldeps/simd-ffi/simd.rs
index 94b91c711cc..21411a35e3c 100644
--- a/src/test/run-make-fulldeps/simd-ffi/simd.rs
+++ b/src/test/run-make-fulldeps/simd-ffi/simd.rs
@@ -75,6 +75,9 @@ pub trait Sized { }
 #[lang = "copy"]
 pub trait Copy { }
 
+impl Copy for f32 {}
+impl Copy for i32 {}
+
 pub mod marker {
     pub use Copy;
 }
diff --git a/src/test/ui/coherence-impls-copy.rs b/src/test/ui/coherence-impls-copy.rs
index 51f43d27c34..f48790d1f40 100644
--- a/src/test/ui/coherence-impls-copy.rs
+++ b/src/test/ui/coherence-impls-copy.rs
@@ -12,6 +12,10 @@
 
 use std::marker::Copy;
 
+impl Copy for i32 {}
+//~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `i32`:
+//~| ERROR only traits defined in the current crate can be implemented for arbitrary types
+
 enum TestE {
   A
 }
@@ -35,14 +39,14 @@ impl Copy for (MyType, MyType) {}
 //~| ERROR only traits defined in the current crate can be implemented for arbitrary types
 
 impl Copy for &'static NotSync {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `&NotSync`:
 
 impl Copy for [MyType] {}
 //~^ ERROR the trait `Copy` may not be implemented for this type
 //~| ERROR only traits defined in the current crate can be implemented for arbitrary types
 
 impl Copy for &'static [NotSync] {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
 //~| ERROR only traits defined in the current crate can be implemented for arbitrary types
 
 fn main() {
diff --git a/src/test/ui/coherence-impls-copy.stderr b/src/test/ui/coherence-impls-copy.stderr
index 5f9b0c62df2..24e7e85b1a9 100644
--- a/src/test/ui/coherence-impls-copy.stderr
+++ b/src/test/ui/coherence-impls-copy.stderr
@@ -1,35 +1,61 @@
-error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:29:15
+error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `i32`:
+  --> $DIR/coherence-impls-copy.rs:15:1
    |
-LL | impl Copy for &'static mut MyType {}
-   |               ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration
+LL | impl Copy for i32 {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl std::marker::Copy for i32;
+
+error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`:
+  --> $DIR/coherence-impls-copy.rs:41:1
+   |
+LL | impl Copy for &'static NotSync {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<'a, T> std::marker::Copy for &'a T
+             where T: ?Sized;
+
+error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
+  --> $DIR/coherence-impls-copy.rs:48:1
+   |
+LL | impl Copy for &'static [NotSync] {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<'a, T> std::marker::Copy for &'a T
+             where T: ?Sized;
 
 error[E0206]: the trait `Copy` may not be implemented for this type
   --> $DIR/coherence-impls-copy.rs:33:15
    |
-LL | impl Copy for (MyType, MyType) {}
-   |               ^^^^^^^^^^^^^^^^ type is not a structure or enumeration
+LL | impl Copy for &'static mut MyType {}
+   |               ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
 error[E0206]: the trait `Copy` may not be implemented for this type
   --> $DIR/coherence-impls-copy.rs:37:15
    |
-LL | impl Copy for &'static NotSync {}
+LL | impl Copy for (MyType, MyType) {}
    |               ^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
 error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:40:15
+  --> $DIR/coherence-impls-copy.rs:44:15
    |
 LL | impl Copy for [MyType] {}
    |               ^^^^^^^^ type is not a structure or enumeration
 
-error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:44:15
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/coherence-impls-copy.rs:15:1
    |
-LL | impl Copy for &'static [NotSync] {}
-   |               ^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration
+LL | impl Copy for i32 {}
+   | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   |
+   = note: the impl does not reference any types defined in this crate
+   = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:33:1
+  --> $DIR/coherence-impls-copy.rs:37:1
    |
 LL | impl Copy for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
@@ -38,7 +64,7 @@ LL | impl Copy for (MyType, MyType) {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:40:1
+  --> $DIR/coherence-impls-copy.rs:44:1
    |
 LL | impl Copy for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
@@ -47,7 +73,7 @@ LL | impl Copy for [MyType] {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:44:1
+  --> $DIR/coherence-impls-copy.rs:48:1
    |
 LL | impl Copy for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
@@ -55,7 +81,7 @@ LL | impl Copy for &'static [NotSync] {}
    = note: the impl does not reference any types defined in this crate
    = note: define and implement a trait or new type instead
 
-error: aborting due to 8 previous errors
+error: aborting due to 10 previous errors
 
-Some errors occurred: E0117, E0206.
+Some errors occurred: E0117, E0119, E0206.
 For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/error-codes/E0206.rs b/src/test/ui/error-codes/E0206.rs
index da0370b301b..9b3d1b351dd 100644
--- a/src/test/ui/error-codes/E0206.rs
+++ b/src/test/ui/error-codes/E0206.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type Foo = i32;
+type Foo = [u8; 256];
 
 impl Copy for Foo { }
 //~^ ERROR the trait `Copy` may not be implemented for this type
@@ -17,7 +17,7 @@ impl Copy for Foo { }
 #[derive(Copy, Clone)]
 struct Bar;
 
-impl Copy for &'static Bar { }
+impl Copy for &'static mut Bar { }
 //~^ ERROR the trait `Copy` may not be implemented for this type
 
 fn main() {
diff --git a/src/test/ui/error-codes/E0206.stderr b/src/test/ui/error-codes/E0206.stderr
index bbc0da2248f..f2c23b0767a 100644
--- a/src/test/ui/error-codes/E0206.stderr
+++ b/src/test/ui/error-codes/E0206.stderr
@@ -7,8 +7,8 @@ LL | impl Copy for Foo { }
 error[E0206]: the trait `Copy` may not be implemented for this type
   --> $DIR/E0206.rs:20:15
    |
-LL | impl Copy for &'static Bar { }
-   |               ^^^^^^^^^^^^ type is not a structure or enumeration
+LL | impl Copy for &'static mut Bar { }
+   |               ^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
   --> $DIR/E0206.rs:13:1