diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index c3e10405eb532..a8a047a29285b 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -316,7 +316,6 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { "codegen-units"); suite("check-incremental", "src/test/incremental", "incremental", "incremental"); - suite("check-ui", "src/test/ui", "ui", "ui"); } if build.config.build.contains("msvc") { @@ -363,6 +362,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { }); }; + suite("check-ui", "src/test/ui", "ui", "ui"); suite("check-rpass-full", "src/test/run-pass-fulldeps", "run-pass", "run-pass-fulldeps"); suite("check-rfail-full", "src/test/run-fail-fulldeps", @@ -1374,7 +1374,6 @@ mod tests { assert!(plan.iter().any(|s| s.name.contains("-ui"))); assert!(plan.iter().any(|s| s.name.contains("cfail"))); - assert!(plan.iter().any(|s| s.name.contains("cfail"))); assert!(plan.iter().any(|s| s.name.contains("cfail-full"))); assert!(plan.iter().any(|s| s.name.contains("codegen-units"))); assert!(plan.iter().any(|s| s.name.contains("debuginfo"))); @@ -1407,8 +1406,7 @@ mod tests { assert!(plan.iter().all(|s| s.host == "A")); assert!(plan.iter().all(|s| s.target == "C")); - assert!(plan.iter().any(|s| s.name.contains("-ui"))); - assert!(plan.iter().any(|s| s.name.contains("cfail"))); + assert!(!plan.iter().any(|s| s.name.contains("-ui"))); assert!(plan.iter().any(|s| s.name.contains("cfail"))); assert!(!plan.iter().any(|s| s.name.contains("cfail-full"))); assert!(plan.iter().any(|s| s.name.contains("codegen-units"))); diff --git a/src/doc/nomicon/coercions.md b/src/doc/nomicon/coercions.md index 6a9ebd6edf8fb..b699946cecaa2 100644 --- a/src/doc/nomicon/coercions.md +++ b/src/doc/nomicon/coercions.md @@ -17,6 +17,7 @@ Coercion is allowed between the following types: * `&T` to `*const T` * `&mut T` to `*mut T` * Unsizing: `T` to `U` if `T` implements `CoerceUnsized` +* Deref coercion: Expression `&x` of type `&T` to `&*x` of type `&U` if `T` derefs to `U` (i.e. `T: Deref`) `CoerceUnsized> for Pointer where T: Unsize` is implemented for all pointer types (including smart pointers like Box and Rc). Unsize is @@ -27,8 +28,9 @@ only implemented automatically, and enables the following transformations: * `Foo<..., T, ...>` => `Foo<..., U, ...>` where: * `T: Unsize` * `Foo` is a struct - * Only the last field of `Foo` has type `T` + * Only the last field of `Foo` has type involving `T` * `T` is not part of the type of any other fields + * `Bar: Unsize>`, if the last field of `Foo` has type `Bar` Coercions occur at a *coercion site*. Any location that is explicitly typed will cause a coercion to its type. If inference is necessary, the coercion will diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index e1a240a0d2eba..459dc94f33686 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -708,7 +708,7 @@ impl Arc { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Arc { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc { /// Drops the `Arc`. /// /// This will decrement the strong reference count. If the strong reference @@ -736,7 +736,6 @@ impl Drop for Arc { /// drop(foo); // Doesn't print anything /// drop(foo2); // Prints "dropped!" /// ``` - #[unsafe_destructor_blind_to_params] #[inline] fn drop(&mut self) { // Because `fetch_sub` is already atomic, we do not need to synchronize diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 9ca9f93f3d33a..c67106cf57aaf 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -79,9 +79,10 @@ #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(custom_attribute)] -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #![cfg_attr(not(test), feature(exact_size_is_empty))] #![feature(fundamental)] +#![feature(generic_param_attrs)] #![feature(lang_items)] #![feature(needs_allocator)] #![feature(optin_builtin_traits)] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index f23ea0ea8bf71..357a2724e0020 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -539,8 +539,7 @@ impl RawVec { } } -impl Drop for RawVec { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for RawVec { /// Frees the memory owned by the RawVec *without* trying to Drop its contents. fn drop(&mut self) { let elem_size = mem::size_of::(); diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 86f8c746646aa..010e378ef2f48 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -644,7 +644,7 @@ impl Deref for Rc { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Rc { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { /// Drops the `Rc`. /// /// This will decrement the strong reference count. If the strong reference @@ -672,7 +672,6 @@ impl Drop for Rc { /// drop(foo); // Doesn't print anything /// drop(foo2); // Prints "dropped!" /// ``` - #[unsafe_destructor_blind_to_params] fn drop(&mut self) { unsafe { let ptr = *self.ptr; diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 82ca989c9efb0..a3cfc15895eb7 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -30,10 +30,10 @@ #![feature(alloc)] #![feature(core_intrinsics)] +#![feature(dropck_eyepatch)] #![feature(heap_api)] -#![feature(heap_api)] +#![feature(generic_param_attrs)] #![feature(staged_api)] -#![feature(dropck_parametricity)] #![cfg_attr(test, feature(test))] #![allow(deprecated)] @@ -258,8 +258,7 @@ impl TypedArena { } } -impl Drop for TypedArena { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for TypedArena { fn drop(&mut self) { unsafe { // Determine how much was filled. diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 788236c24d063..98c71967f3c39 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -137,8 +137,7 @@ pub struct BTreeMap { } #[stable(feature = "btree_drop", since = "1.7.0")] -impl Drop for BTreeMap { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap { fn drop(&mut self) { unsafe { for _ in ptr::read(self).into_iter() { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index ea2feac49f6ed..561d8860dc880 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -35,10 +35,11 @@ #![feature(box_syntax)] #![cfg_attr(not(test), feature(char_escape_debug))] #![feature(core_intrinsics)] -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(fmt_internals)] #![feature(fused)] +#![feature(generic_param_attrs)] #![feature(heap_api)] #![feature(inclusive_range)] #![feature(lang_items)] diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 310855090885c..7f913d4afe476 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -726,8 +726,7 @@ impl LinkedList { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for LinkedList { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for LinkedList { fn drop(&mut self) { while let Some(_) = self.pop_front_node() {} } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index c399283babf26..27cf0268c99bb 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -370,7 +370,8 @@ impl Vec { /// * `capacity` needs to be the capacity that the pointer was allocated with. /// /// Violating these may cause problems like corrupting the allocator's - /// internal datastructures. + /// internal datastructures. For example it is **not** safe + /// to build a `Vec` from a pointer to a C `char` array and a `size_t`. /// /// The ownership of `ptr` is effectively transferred to the /// `Vec` which may then deallocate, reallocate or change the @@ -1786,8 +1787,7 @@ impl Ord for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Vec { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for Vec { fn drop(&mut self) { unsafe { // use drop for [T] @@ -2056,8 +2056,7 @@ impl Clone for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for IntoIter { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for IntoIter { fn drop(&mut self) { // destroy the remaining elements for _x in self.by_ref() {} diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index d650360435aa0..76e44c815793f 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -69,8 +69,7 @@ impl Clone for VecDeque { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for VecDeque { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for VecDeque { fn drop(&mut self) { let (front, back) = self.as_mut_slices(); unsafe { diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs index 44aa08e245873..6a766fc02df3e 100644 --- a/src/libcompiler_builtins/build.rs +++ b/src/libcompiler_builtins/build.rs @@ -192,14 +192,12 @@ fn main() { if !target.contains("ios") { sources.extend(&["absvti2.c", - "addtf3.c", "addvti3.c", "ashlti3.c", "ashrti3.c", "clzti2.c", "cmpti2.c", "ctzti2.c", - "divtf3.c", "divti3.c", "ffsti2.c", "fixdfti.c", @@ -216,17 +214,13 @@ fn main() { "floatuntixf.c", "lshrti3.c", "modti3.c", - "multf3.c", "multi3.c", "mulvti3.c", "negti2.c", "negvti2.c", "parityti2.c", "popcountti2.c", - "powitf2.c", - "subtf3.c", "subvti3.c", - "trampoline_setup.c", "ucmpti2.c", "udivmodti4.c", "udivti3.c", diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index ed01b93f1335a..798f1e6cbeb84 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -100,13 +100,26 @@ pub trait Sized { /// /// All implementations of `Unsize` are provided automatically by the compiler. /// +/// `Unsize` is implemented for: +/// +/// - `[T; N]` is `Unsize<[T]>` +/// - `T` is `Unsize` when `T: Trait` +/// - `Foo<..., T, ...>` is `Unsize>` if: +/// - `T: Unsize` +/// - Foo is a struct +/// - Only the last field of `Foo` has a type involving `T` +/// - `T` is not part of the type of any other fields +/// - `Bar: Unsize>`, if the last field of `Foo` has type `Bar` +/// /// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow /// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized -/// types. See the [DST coercion RFC][RFC982] for more details. +/// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce] +/// for more details. /// /// [coerceunsized]: ../ops/trait.CoerceUnsized.html /// [rc]: ../../std/rc/struct.Rc.html /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md + #[unstable(feature = "unsize", issue = "27732")] #[lang="unsize"] pub trait Unsize { diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 40d941a8b27e0..94df72f28fa9c 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -2710,6 +2710,35 @@ mod impls { /// Trait that indicates that this is a pointer or a wrapper for one, /// where unsizing can be performed on the pointee. +/// +/// See the [DST coercion RfC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce] +/// for more details. +/// +/// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize` +/// by converting from a thin pointer to a fat pointer. +/// +/// For custom types, the coercion here works by coercing `Foo` to `Foo` +/// provided an impl of `CoerceUnsized> for Foo` exists. +/// Such an impl can only be written if `Foo` has only a single non-phantomdata +/// field involving `T`. If the type of that field is `Bar`, an implementation +/// of `CoerceUnsized> for Bar` must exist. The coercion will work by +/// by coercing the `Bar` field into `Bar` and filling in the rest of the fields +/// from `Foo` to create a `Foo`. This will effectively drill down to a pointer +/// field and coerce that. +/// +/// Generally, for smart pointers you will implement +/// `CoerceUnsized> for Ptr where T: Unsize, U: ?Sized`, with an +/// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T` +/// like `Cell` and `RefCell`, you +/// can directly implement `CoerceUnsized> for Wrap where T: CoerceUnsized`. +/// This will let coercions of types like `Cell>` work. +/// +/// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind +/// pointers. It is implemented automatically by the compiler. +/// +/// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md +/// [unsize]: ../marker/trait.Unsize.html +/// [nomicon-coerce]: ../../nomicon/coercions.html #[unstable(feature = "coerce_unsized", issue = "27732")] #[lang="coerce_unsized"] pub trait CoerceUnsized { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 59bc001516c79..104c851e057e6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1175,7 +1175,7 @@ pub fn rustc_short_optgroups() -> Vec { assumed.", "[KIND=]NAME"), opt::multi_s("", "crate-type", "Comma separated list of types of crates for the compiler to emit", - "[bin|lib|rlib|dylib|cdylib|staticlib]"), + "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]"), opt::opt_s("", "crate-name", "Specify the name of the crate being built", "NAME"), opt::multi_s("", "emit", "Comma separated list of types of output for \ diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 2cd9362a65791..1ab62130cd3dd 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -1061,8 +1061,7 @@ impl Clone for RawTable { } } -impl Drop for RawTable { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable { fn drop(&mut self) { if self.capacity == 0 { return; diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 84b50f04463fe..175fe30db661c 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -259,6 +259,15 @@ impl OsStr { /// Yields a `&str` slice if the `OsStr` is valid Unicode. /// /// This conversion may entail doing a check for UTF-8 validity. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new("foo"); + /// assert_eq!(os_str.to_str(), Some("foo")); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn to_str(&self) -> Option<&str> { self.inner.to_str() @@ -267,6 +276,20 @@ impl OsStr { /// Converts an `OsStr` to a `Cow`. /// /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. + /// + /// # Examples + /// + /// Calling `to_string_lossy` on an `OsStr` with valid unicode: + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new("foo"); + /// assert_eq!(os_str.to_string_lossy(), "foo"); + /// ``` + /// + /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might + /// have returned `"fo�"`. #[stable(feature = "rust1", since = "1.0.0")] pub fn to_string_lossy(&self) -> Cow { self.inner.to_string_lossy() diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 9557c520c5071..521b938acfb7e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -250,13 +250,14 @@ #![feature(const_fn)] #![feature(core_float)] #![feature(core_intrinsics)] -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(float_extras)] #![feature(float_from_str_radix)] #![feature(fn_traits)] #![feature(fnbox)] #![feature(fused)] +#![feature(generic_param_attrs)] #![feature(hashmap_hasher)] #![feature(heap_api)] #![feature(inclusive_range)] diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index ed1f08f9c9090..e203789ce81d9 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -52,7 +52,7 @@ pub struct TcpStream(net_imp::TcpStream); /// // ... /// } /// -/// // accept connections and process them, spawning a new thread for each one +/// // accept connections and process them serially /// for stream in listener.incoming() { /// match stream { /// Ok(stream) => { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index d13baea40a9ff..3f9bf70adde22 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1428,8 +1428,8 @@ impl Path { /// ``` /// use std::path::Path; /// - /// let path_str = Path::new("foo.txt").to_str(); - /// assert_eq!(path_str, Some("foo.txt")); + /// let path = Path::new("foo.txt"); + /// assert_eq!(path.to_str(), Some("foo.txt")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn to_str(&self) -> Option<&str> { @@ -1444,12 +1444,17 @@ impl Path { /// /// # Examples /// + /// Calling `to_string_lossy` on a `Path` with valid unicode: + /// /// ``` /// use std::path::Path; /// - /// let path_str = Path::new("foo.txt").to_string_lossy(); - /// assert_eq!(path_str, "foo.txt"); + /// let path = Path::new("foo.txt"); + /// assert_eq!(path.to_string_lossy(), "foo.txt"); /// ``` + /// + /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might + /// have returned `"fo�.txt"`. #[stable(feature = "rust1", since = "1.0.0")] pub fn to_string_lossy(&self) -> Cow { self.inner.to_string_lossy() diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 5981b482a9728..ced0288766bb1 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -502,7 +502,7 @@ mod prim_str { } /// [`Hash`]: hash/trait.Hash.html /// /// Due to a temporary restriction in Rust's type system, these traits are only -/// implemented on tuples of arity 32 or less. In the future, this may change. +/// implemented on tuples of arity 12 or less. In the future, this may change. /// /// # Examples /// diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index f6dbe01d7bdbf..f8426e3b5782f 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -280,8 +280,7 @@ impl Mutex { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Mutex { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex { fn drop(&mut self) { // This is actually safe b/c we know that there is no further usage of // this mutex (it's up to the user to arrange for a mutex to get diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 0a11c71706b7e..adbb98e4b1f4f 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -310,8 +310,7 @@ impl RwLock { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for RwLock { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock { fn drop(&mut self) { // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`. unsafe { self.inner.destroy() } diff --git a/src/test/incremental/hashes/trait_impls.rs b/src/test/incremental/hashes/trait_impls.rs index 500aaf52324b0..15094492248e6 100644 --- a/src/test/incremental/hashes/trait_impls.rs +++ b/src/test/incremental/hashes/trait_impls.rs @@ -402,3 +402,155 @@ impl ChangeArgumentTypeTrait for Foo { fn method_name(&self, _x: char) { } } + + +struct Bar(T); + +// Add Type Parameter To Impl -------------------------------------------------- +trait AddTypeParameterToImpl { + fn id(t: T) -> T; +} + +#[cfg(cfail1)] +impl AddTypeParameterToImpl for Bar { + fn id(t: u32) -> u32 { t } +} + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +impl AddTypeParameterToImpl for Bar { + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + fn id(t: T) -> T { t } +} + + + +// Change Self Type of Impl ---------------------------------------------------- +trait ChangeSelfTypeOfImpl { + fn id(self) -> Self; +} + +#[cfg(cfail1)] +impl ChangeSelfTypeOfImpl for u32 { + fn id(self) -> Self { self } +} + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +impl ChangeSelfTypeOfImpl for u64 { + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + fn id(self) -> Self { self } +} + + + +// Add Lifetime Bound to Impl -------------------------------------------------- +trait AddLifetimeBoundToImplParameter { + fn id(self) -> Self; +} + +#[cfg(cfail1)] +impl AddLifetimeBoundToImplParameter for T { + fn id(self) -> Self { self } +} + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +impl AddLifetimeBoundToImplParameter for T { + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + fn id(self) -> Self { self } +} + + + +// Add Trait Bound to Impl Parameter ------------------------------------------- +trait AddTraitBoundToImplParameter { + fn id(self) -> Self; +} + +#[cfg(cfail1)] +impl AddTraitBoundToImplParameter for T { + fn id(self) -> Self { self } +} + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +impl AddTraitBoundToImplParameter for T { + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + fn id(self) -> Self { self } +} + + + +// Add #[no_mangle] to Method -------------------------------------------------- +trait AddNoMangleToMethod { + fn add_no_mangle_to_method(&self) { } +} + +#[cfg(cfail1)] +impl AddNoMangleToMethod for Foo { + fn add_no_mangle_to_method(&self) { } +} + +#[cfg(not(cfail1))] +#[rustc_clean(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +impl AddNoMangleToMethod for Foo { + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + #[no_mangle] + fn add_no_mangle_to_method(&self) { } +} + + +// Make Method #[inline] ------------------------------------------------------- +trait MakeMethodInline { + fn make_method_inline(&self) -> u8 { 0 } +} + +#[cfg(cfail1)] +impl MakeMethodInline for Foo { + fn make_method_inline(&self) -> u8 { 0 } +} + +#[cfg(not(cfail1))] +#[rustc_clean(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +impl MakeMethodInline for Foo { + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + #[inline] + fn make_method_inline(&self) -> u8 { 0 } +} diff --git a/src/test/ui/custom-derive/auxiliary/plugin.rs b/src/test/ui/custom-derive/auxiliary/plugin.rs new file mode 100644 index 0000000000000..c5ba2aa9413e7 --- /dev/null +++ b/src/test/ui/custom-derive/auxiliary/plugin.rs @@ -0,0 +1,28 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro, proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Foo)] +pub fn derive_foo(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(Bar)] +pub fn derive_bar(input: TokenStream) -> TokenStream { + panic!("lolnope"); +} diff --git a/src/test/ui/custom-derive/issue-36935.rs b/src/test/ui/custom-derive/issue-36935.rs new file mode 100644 index 0000000000000..22d603563de17 --- /dev/null +++ b/src/test/ui/custom-derive/issue-36935.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:plugin.rs + +#![feature(proc_macro)] + +#[macro_use] extern crate plugin; + +#[derive(Foo, Bar)] +struct Baz { + a: i32, + b: i32, +} + +fn main() {} diff --git a/src/test/ui/custom-derive/issue-36935.stderr b/src/test/ui/custom-derive/issue-36935.stderr new file mode 100644 index 0000000000000..213366a307d40 --- /dev/null +++ b/src/test/ui/custom-derive/issue-36935.stderr @@ -0,0 +1,8 @@ +error: custom derive attribute panicked + --> $DIR/issue-36935.rs:17:15 + | +17 | #[derive(Foo, Bar)] + | ^^^ + | + = help: message: lolnope + diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs new file mode 100644 index 0000000000000..81fcb007eb491 --- /dev/null +++ b/src/test/ui/span/issue-27522.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Point at correct span for self type + +struct SomeType {} + +trait Foo { + fn handler(self: &SomeType); +} + +fn main() {} diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr new file mode 100644 index 0000000000000..71130f4947a68 --- /dev/null +++ b/src/test/ui/span/issue-27522.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched method receiver + --> $DIR/issue-27522.rs:16:22 + | +16 | fn handler(self: &SomeType); + | ^^^^^^^^^ expected Self, found struct `SomeType` + | + = note: expected type `&Self` + = note: found type `&SomeType` + +error: aborting due to previous error +