From 27164faaef69853e2c1adcc0ccd6e70780b6da0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Mon, 12 Feb 2018 01:17:32 -0500 Subject: [PATCH 1/5] Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893 --- src/libcore/clone.rs | 60 +++++++++++++++++++ src/libcore/marker.rs | 40 +++++++++++++ src/librustc/traits/select.rs | 10 +++- src/librustc/ty/util.rs | 7 +++ src/librustc_typeck/diagnostics.rs | 8 +-- .../atomic-lock-free/atomic_lock_free.rs | 2 + src/test/run-make-fulldeps/simd-ffi/simd.rs | 3 + src/test/ui/coherence-impls-copy.rs | 8 ++- src/test/ui/coherence-impls-copy.stderr | 60 +++++++++++++------ src/test/ui/error-codes/E0206.rs | 4 +- src/test/ui/error-codes/E0206.stderr | 4 +- 11 files changed, 176 insertions(+), 30 deletions(-) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index d25f498b99efe..5c83dd79bd7f1 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -135,3 +135,63 @@ pub struct AssertParamIsClone { _field: ::marker::PhantomData reason = "deriving hack, should not be public", issue = "0")] pub struct AssertParamIsCopy { _field: ::marker::PhantomData } + +/// 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 Clone for *const T { + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl 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 7d0174a178abf..008cb15131d89 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 Copy for *const T {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl 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 11daa96134c59..8a585d6ac1467 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 afe977d10baac..22f851a908b25 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 1f882676f61aa..691e0ffb6a5db 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 b41e8e9226b32..54f888b3796a1 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 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 94b91c711cce0..21411a35e3c35 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 51f43d27c34d2..f48790d1f4039 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 5f9b0c62df2b8..24e7e85b1a961 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 da0370b301b5b..9b3d1b351ddd9 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 bbc0da2248f6e..f2c23b0767af8 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 From f48c043154aeed1af44e6be66b17122fafacda51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Mon, 12 Feb 2018 02:31:26 -0500 Subject: [PATCH 2/5] Document builtin implementations of Clone and Copy There are types that implement `Clone` and `Copy` but are not mentioned in the documentation, because the implementations are provided by the compiler. They are types of variants that cannot be fully covered by trait implementations in Rust code, because the language is not expressive enough. --- src/libcore/clone.rs | 22 +++++++++++++++++----- src/libcore/marker.rs | 21 ++++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 5c83dd79bd7f1..b6a5948e6456e 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -63,11 +63,6 @@ /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d /// implementation of [`clone`] calls [`clone`] on each field. /// -/// ## Closures -/// -/// Closure types automatically implement `Clone` if they capture no value from the environment -/// or if all such captured values implement `Clone` themselves. -/// /// ## How can I implement `Clone`? /// /// Types that are [`Copy`] should have a trivial implementation of `Clone`. More formally: @@ -92,6 +87,23 @@ /// fn clone(&self) -> Stats { *self } /// } /// ``` +/// +/// ## Additional implementors +/// +/// In addition to the [implementors listed below][impls], +/// the following types also implement `Clone`: +/// +/// * Function item types (i.e. the distinct types defined for each function) +/// * Function pointer types (e.g. `fn() -> i32`) +/// * Array types, for all sizes, if the item type also implements `Clone` (e.g. `[i32; 123456]`) +/// * Tuple types, if each component also implements `Clone` (e.g. `()`, `(i32, bool)`) +/// * Closure types, if they capture no value from the environment +/// or if all such captured values implement `Clone` themselves. +/// Note that variables captured by shared reference always implement `Clone` +/// (even if the referent doesn't), +/// while variables captured by mutable reference never implement `Clone`. +/// +/// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "clone"] pub trait Clone : Sized { diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 008cb15131d89..885aabe08069d 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -166,11 +166,6 @@ pub trait Unsize { /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move /// can result in bits being copied in memory, although this is sometimes optimized away. /// -/// ## Closures -/// -/// Closure types automatically implement `Copy` if they capture no value from the environment -/// or if all such captured values implement `Copy` themselves. -/// /// ## How can I implement `Copy`? /// /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`: @@ -265,6 +260,21 @@ pub trait Unsize { /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to /// avoid a breaking API change. /// +/// ## Additional implementors +/// +/// In addition to the [implementors listed below][impls], +/// the following types also implement `Copy`: +/// +/// * Function item types (i.e. the distinct types defined for each function) +/// * Function pointer types (e.g. `fn() -> i32`) +/// * Array types, for all sizes, if the item type also implements `Copy` (e.g. `[i32; 123456]`) +/// * Tuple types, if each component also implements `Copy` (e.g. `()`, `(i32, bool)`) +/// * Closure types, if they capture no value from the environment +/// or if all such captured values implement `Copy` themselves. +/// Note that variables captured by shared reference always implement `Copy` +/// (even if the referent doesn't), +/// while variables captured by mutable reference never implement `Copy`. +/// /// [`Vec`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html /// [`Drop`]: ../../std/ops/trait.Drop.html @@ -272,6 +282,7 @@ pub trait Unsize { /// [`Clone`]: ../clone/trait.Clone.html /// [`String`]: ../../std/string/struct.String.html /// [`i32`]: ../../std/primitive.i32.html +/// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "copy"] pub trait Copy : Clone { From afa7f5bc8ac79503bb99a20a1dd19365318f504f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Sat, 10 Mar 2018 17:43:44 -0500 Subject: [PATCH 3/5] Add #[inline] to Clone impls for primitive types --- src/libcore/clone.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index b6a5948e6456e..f8e8c69621ae2 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -162,6 +162,7 @@ mod impls { $( #[stable(feature = "rust1", since = "1.0.0")] impl Clone for $t { + #[inline] fn clone(&self) -> Self { *self } @@ -179,6 +180,7 @@ mod impls { #[stable(feature = "never_type", since = "1.26.0")] impl Clone for ! { + #[inline] fn clone(&self) -> Self { *self } @@ -186,6 +188,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *const T { + #[inline] fn clone(&self) -> Self { *self } @@ -193,6 +196,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *mut T { + #[inline] fn clone(&self) -> Self { *self } @@ -201,6 +205,7 @@ mod impls { // Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized> Clone for &'a T { + #[inline] fn clone(&self) -> Self { *self } From d032a4b079e9605bd95919db59c817422e0fdba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Sat, 10 Mar 2018 19:04:40 -0500 Subject: [PATCH 4/5] Strengthen the repeat-trusted-len test Simply checking for the presence of `llvm.memset` is too brittle because this instrinsic can be used for seemingly trivial operations, such as zero-initializing a `RawVec`. --- src/test/codegen/repeat-trusted-len.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs index 43872f15d51e2..8b3294281e960 100644 --- a/src/test/codegen/repeat-trusted-len.rs +++ b/src/test/codegen/repeat-trusted-len.rs @@ -15,9 +15,14 @@ use std::iter; +// CHECK: @helper([[USIZE:i[0-9]+]] %arg0) +#[no_mangle] +pub fn helper(_: usize) { +} + // CHECK-LABEL: @repeat_take_collect #[no_mangle] pub fn repeat_take_collect() -> Vec { -// CHECK: call void @llvm.memset.p0i8 +// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}%{{[0-9]+}}, i8 42, [[USIZE]] 100000, i32 1, i1 false) iter::repeat(42).take(100000).collect() } From 87c08f9926b7078489a93cedd1c9f10df1bdf2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Mon, 26 Mar 2018 21:59:35 -0400 Subject: [PATCH 5/5] Update liblibc submodule to the 0.2.40 release --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index ed04152aacf5b..a7e78a78e17c8 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit ed04152aacf5b4798f78ff13396f3c04c0a77144 +Subproject commit a7e78a78e17c8776d7780008ccb3ce541ec64ae9