From 4c2e3144a98f7a636fd6a33fce122121431ad9b4 Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Thu, 26 Apr 2018 16:29:22 -0700 Subject: [PATCH 01/39] added DerefOption and DerefResult + tests to std --- src/libcore/option.rs | 21 +++++++++++-- src/libcore/result.rs | 59 ++++++++++++++++++++++++++++++++++++- src/libcore/tests/option.rs | 11 +++++++ src/libcore/tests/result.rs | 21 +++++++++++++ 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 0dfdabee03182..c3ef619d739c0 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -146,7 +146,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use iter::{FromIterator, FusedIterator, TrustedLen}; -use {mem, ops}; +use {mem, ops::{self, Deref}}; // Note that this is not a lang item per se, but it has a hidden dependency on // `Iterator`, which is one. The compiler assumes that the `next` method of @@ -914,7 +914,6 @@ fn expect_failed(msg: &str) -> ! { panic!("{}", msg) } - ///////////////////////////////////////////////////////////////////////////// // Trait implementations ///////////////////////////////////////////////////////////////////////////// @@ -979,6 +978,24 @@ impl From for Option { } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +/// Extension trait to get a reference of an Option via the Deref trait. +pub trait OptionDeref { + /// Converts from `&Option` to `Option<&T::Target>`. + /// + /// Leaves the original Option in-place, creating a new one with a reference + /// to the original one, additionally coercing the contents via `Deref`. + fn deref(&self) -> Option<&T::Target>; +} + +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl OptionDeref for Option +{ + fn deref(&self) -> Option<&T::Target> { + self.as_ref().map(|t| t.deref()) + } +} + ///////////////////////////////////////////////////////////////////////////// // The Option Iterators ///////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index c152d4979b90e..9877a2001a0ff 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -242,7 +242,7 @@ use fmt; use iter::{FromIterator, FusedIterator, TrustedLen}; -use ops; +use ops::{self, Deref}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// @@ -999,6 +999,63 @@ impl<'a, T, E> IntoIterator for &'a mut Result { } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +/// Extension trait to get a reference to a Result via the Deref trait. +pub trait ResultDeref { + /// Converts from `&Result` to `Result<&T::Target, &E>`. + /// + /// Leaves the original Result in-place, creating a new one with a reference + /// to the original one, additionally coercing the `Ok` arm of the Result via + /// `Deref`. + fn deref_ok(&self) -> Result<&T::Target, &E> + where + T: Deref; + + /// Converts from `&Result` to `Result<&T, &E::Target>`. + /// + /// Leaves the original Result in-place, creating a new one with a reference + /// to the original one, additionally coercing the `Err` arm of the Result via + /// `Deref`. + fn deref_err(&self) -> Result<&T, &E::Target> + where + E: Deref; + + /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. + /// + /// Leaves the original Result in-place, creating a new one with a reference + /// to the original one, additionally coercing both the `Ok` and `Err` arms + /// of the Result via `Deref`. + fn deref(&self) -> Result<&T::Target, &E::Target> + where + T: Deref, + E: Deref; +} + +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl ResultDeref for Result { + fn deref_ok(&self) -> Result<&T::Target, &E> + where + T: Deref, + { + self.as_ref().map(|t| t.deref()) + } + + fn deref_err(&self) -> Result<&T, &E::Target> + where + E: Deref, + { + self.as_ref().map_err(|e| e.deref()) + } + + fn deref(&self) -> Result<&T::Target, &E::Target> + where + T: Deref, + E: Deref, + { + self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) + } +} + ///////////////////////////////////////////////////////////////////////////// // The Result Iterators ///////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 22109e28edd9b..77d550c532a34 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -297,3 +297,14 @@ fn test_try() { } assert_eq!(try_option_err(), Err(NoneError)); } + +#[test] +fn test_option_deref() { + // Some: &Option::Some(T) -> Option<&T::Deref::Target>::Some(&*T) + let ref_option = &Some(&42); + assert_eq!(ref_option.deref(), Some(&42)); + + // None: &Option>::None -> None + let ref_option = &None; + assert_eq!(ref_option.deref(), None); +} diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index ce41bde8342ed..dd23467322dc9 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -231,3 +231,24 @@ fn test_try() { } assert_eq!(try_result_err(), Err(1)); } + +#[test] +fn test_result_deref() { + // Ok(T).deref_ok() -> Result<&T, &E::Deref::Target>::Ok(&T) + let ref_ok: &Result<&i32, &u8> = &Ok(&42); + assert_eq!(ref_ok.deref_ok(), Ok(&42)); + assert_eq!(ref_ok.deref_ok(), Ok(&42)); + assert_eq!(ref_ok.deref(), Ok(&42)); + + // Err(E) -> Result<&T, &E::Deref::Target>::Err(&*E) + let ref_err: &Result<&i32, &u8> = &Err(&41); + assert_eq!(ref_err.deref_err(), Err(&41)); + assert_eq!(ref_err.deref_err(), Err(&41)); + assert_eq!(ref_err.deref(), Err(&41)); + + // &Ok(T).deref_err() -> Result<&T, &E::Deref::Target>::Ok(&T) + assert_eq!(ref_ok.deref_err(), Ok(&&42)); + + // &Err(E) -> Result<&T::Deref::Target, &E>::Err(&E) + assert_eq!(ref_err.deref_ok(), Err(&&41)); +} From 6c7ea4ca9b92e527873115951cfc8c864bbb71ad Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Thu, 26 Apr 2018 19:54:24 -0700 Subject: [PATCH 02/39] refactored to implement without trait --- src/libcore/option.rs | 29 ++++++-------- src/libcore/result.rs | 91 ++++++++++++++++--------------------------- 2 files changed, 45 insertions(+), 75 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index c3ef619d739c0..506e54ba5e4e6 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -878,6 +878,17 @@ impl Option { } } +# [unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Option { + /// Converts from `&Option` to `Option<&T::Target>`. + /// + /// Leaves the original Option in-place, creating a new one with a reference + /// to the original one, additionally coercing the contents via `Deref`. + pub fn deref(&self) -> Option<&T::Target> { + self.as_ref().map(|t| t.deref()) + } +} + impl Option> { /// Transposes an `Option` of a `Result` into a `Result` of an `Option`. /// @@ -978,24 +989,6 @@ impl From for Option { } } -#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -/// Extension trait to get a reference of an Option via the Deref trait. -pub trait OptionDeref { - /// Converts from `&Option` to `Option<&T::Target>`. - /// - /// Leaves the original Option in-place, creating a new one with a reference - /// to the original one, additionally coercing the contents via `Deref`. - fn deref(&self) -> Option<&T::Target>; -} - -#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -impl OptionDeref for Option -{ - fn deref(&self) -> Option<&T::Target> { - self.as_ref().map(|t| t.deref()) - } -} - ///////////////////////////////////////////////////////////////////////////// // The Option Iterators ///////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 9877a2001a0ff..fbf2035e83f46 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -909,6 +909,40 @@ impl Result { } } +impl Result { + #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] + /// Converts from `&Result` to `Result<&T::Target, &E>`. + /// + /// Leaves the original Result in-place, creating a new one with a reference + /// to the original one, additionally coercing the `Ok` arm of the Result via + /// `Deref`. + pub fn deref_ok(&self) -> Result<&T::Target, &E> { + self.as_ref().map(|t| t.deref()) + } + + #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] + /// Converts from `&Result` to `Result<&T, &E::Target>`. + /// + /// Leaves the original Result in-place, creating a new one with a reference + /// to the original one, additionally coercing the `Err` arm of the Result via + /// `Deref`. + pub fn deref_err(&self) -> Result<&T, &E::Target> + { + self.as_ref().map_err(|e| e.deref()) + } + + #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] + /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. + /// + /// Leaves the original Result in-place, creating a new one with a reference + /// to the original one, additionally coercing both the `Ok` and `Err` arms + /// of the Result via `Deref`. + pub fn deref(&self) -> Result<&T::Target, &E::Target> + { + self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) + } +} + impl Result, E> { /// Transposes a `Result` of an `Option` into an `Option` of a `Result`. /// @@ -999,63 +1033,6 @@ impl<'a, T, E> IntoIterator for &'a mut Result { } } -#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -/// Extension trait to get a reference to a Result via the Deref trait. -pub trait ResultDeref { - /// Converts from `&Result` to `Result<&T::Target, &E>`. - /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing the `Ok` arm of the Result via - /// `Deref`. - fn deref_ok(&self) -> Result<&T::Target, &E> - where - T: Deref; - - /// Converts from `&Result` to `Result<&T, &E::Target>`. - /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing the `Err` arm of the Result via - /// `Deref`. - fn deref_err(&self) -> Result<&T, &E::Target> - where - E: Deref; - - /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. - /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing both the `Ok` and `Err` arms - /// of the Result via `Deref`. - fn deref(&self) -> Result<&T::Target, &E::Target> - where - T: Deref, - E: Deref; -} - -#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -impl ResultDeref for Result { - fn deref_ok(&self) -> Result<&T::Target, &E> - where - T: Deref, - { - self.as_ref().map(|t| t.deref()) - } - - fn deref_err(&self) -> Result<&T, &E::Target> - where - E: Deref, - { - self.as_ref().map_err(|e| e.deref()) - } - - fn deref(&self) -> Result<&T::Target, &E::Target> - where - T: Deref, - E: Deref, - { - self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) - } -} - ///////////////////////////////////////////////////////////////////////////// // The Result Iterators ///////////////////////////////////////////////////////////////////////////// From 527e84f300a2cc36b74dcfc6a23ea9352cbf2e0b Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Thu, 26 Apr 2018 20:41:10 -0700 Subject: [PATCH 03/39] cleaned up #[unstable] attributes --- src/libcore/result.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index fbf2035e83f46..9e302cb9f968e 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -909,8 +909,8 @@ impl Result { } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] /// Converts from `&Result` to `Result<&T::Target, &E>`. /// /// Leaves the original Result in-place, creating a new one with a reference @@ -920,7 +920,6 @@ impl Result { self.as_ref().map(|t| t.deref()) } - #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] /// Converts from `&Result` to `Result<&T, &E::Target>`. /// /// Leaves the original Result in-place, creating a new one with a reference @@ -931,7 +930,6 @@ impl Result { self.as_ref().map_err(|e| e.deref()) } - #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. /// /// Leaves the original Result in-place, creating a new one with a reference From b812d44a01bbc7180c11c9fdc3de3926105cbe05 Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Thu, 26 Apr 2018 20:42:44 -0700 Subject: [PATCH 04/39] added #![feature(inner_deref)] to enable inner_deref-related unit tests --- src/libcore/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 0e21a3327fddf..55c5e1e7971d4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -103,6 +103,7 @@ #![feature(untagged_unions)] #![feature(unwind_attributes)] #![feature(doc_alias)] +#![feature(inner_deref)] #![cfg_attr(not(stage0), feature(mmx_target_feature))] #![cfg_attr(not(stage0), feature(tbm_target_feature))] From 2bf9fbc8d61e2283cd6133b96cff2e04988bbe69 Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Fri, 27 Apr 2018 06:36:37 -0700 Subject: [PATCH 05/39] separated inner_deref Result impls --- src/libcore/result.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 9e302cb9f968e..c545064aadb29 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -910,7 +910,7 @@ impl Result { } #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -impl Result { +impl Result { /// Converts from `&Result` to `Result<&T::Target, &E>`. /// /// Leaves the original Result in-place, creating a new one with a reference @@ -919,7 +919,10 @@ impl Result { pub fn deref_ok(&self) -> Result<&T::Target, &E> { self.as_ref().map(|t| t.deref()) } +} +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { /// Converts from `&Result` to `Result<&T, &E::Target>`. /// /// Leaves the original Result in-place, creating a new one with a reference @@ -929,7 +932,10 @@ impl Result { { self.as_ref().map_err(|e| e.deref()) } +} +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. /// /// Leaves the original Result in-place, creating a new one with a reference From 8aa049e54be521c3826b0af15a87b3b4db1fb77b Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Fri, 27 Apr 2018 06:39:04 -0700 Subject: [PATCH 06/39] moved #![feature(inner_deref) to from libcore crate to libcore tests crate to enable related tests --- src/libcore/lib.rs | 1 - src/libcore/tests/lib.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 55c5e1e7971d4..0e21a3327fddf 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -103,7 +103,6 @@ #![feature(untagged_unions)] #![feature(unwind_attributes)] #![feature(doc_alias)] -#![feature(inner_deref)] #![cfg_attr(not(stage0), feature(mmx_target_feature))] #![cfg_attr(not(stage0), feature(tbm_target_feature))] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index e4d277179382f..111cf58c2c69d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -46,6 +46,7 @@ #![feature(reverse_bits)] #![feature(inclusive_range_fields)] #![feature(iterator_find_map)] +#![feature(inner_deref)] extern crate core; extern crate test; From 17124488c7c7582fb9ab22ed87b2759ee20a4602 Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Fri, 27 Apr 2018 07:07:26 -0700 Subject: [PATCH 07/39] fixed inner_deref test case for None --- src/libcore/tests/option.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 77d550c532a34..e7e48b2daa2e2 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -305,6 +305,6 @@ fn test_option_deref() { assert_eq!(ref_option.deref(), Some(&42)); // None: &Option>::None -> None - let ref_option = &None; + let ref_option: &Option<&i32> = &None; assert_eq!(ref_option.deref(), None); } From c025fdebbada2757deccdd97219ff0313631f2ed Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Mon, 30 Apr 2018 12:51:43 -0700 Subject: [PATCH 08/39] fixed some and added more tests --- src/libcore/option.rs | 2 +- src/libcore/tests/option.rs | 8 ++ src/libcore/tests/result.rs | 102 +++++++++++++++--- .../option_deref.rs | 16 +++ .../result_deref.rs | 16 +++ .../result_deref_err.rs | 16 +++ .../result_deref_ok.rs | 16 +++ 7 files changed, 158 insertions(+), 18 deletions(-) create mode 100644 src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs create mode 100644 src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs create mode 100644 src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs create mode 100644 src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 506e54ba5e4e6..deb0380171c4e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -878,7 +878,7 @@ impl Option { } } -# [unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Option { /// Converts from `&Option` to `Option<&T::Target>`. /// diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index e7e48b2daa2e2..ced7b03636a09 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -304,7 +304,15 @@ fn test_option_deref() { let ref_option = &Some(&42); assert_eq!(ref_option.deref(), Some(&42)); + let ref_option = &Some(String::from("a result")); + assert_eq!(ref_option.deref(), Some("a result")); + + let ref_option = &Some(vec![1, 2, 3, 4, 5]); + assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..])); + // None: &Option>::None -> None let ref_option: &Option<&i32> = &None; assert_eq!(ref_option.deref(), None); + + } diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index dd23467322dc9..fd0dd21401b88 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -234,21 +234,89 @@ fn test_try() { #[test] fn test_result_deref() { - // Ok(T).deref_ok() -> Result<&T, &E::Deref::Target>::Ok(&T) - let ref_ok: &Result<&i32, &u8> = &Ok(&42); - assert_eq!(ref_ok.deref_ok(), Ok(&42)); - assert_eq!(ref_ok.deref_ok(), Ok(&42)); - assert_eq!(ref_ok.deref(), Ok(&42)); - - // Err(E) -> Result<&T, &E::Deref::Target>::Err(&*E) - let ref_err: &Result<&i32, &u8> = &Err(&41); - assert_eq!(ref_err.deref_err(), Err(&41)); - assert_eq!(ref_err.deref_err(), Err(&41)); - assert_eq!(ref_err.deref(), Err(&41)); - - // &Ok(T).deref_err() -> Result<&T, &E::Deref::Target>::Ok(&T) - assert_eq!(ref_ok.deref_err(), Ok(&&42)); - - // &Err(E) -> Result<&T::Deref::Target, &E>::Err(&E) - assert_eq!(ref_err.deref_ok(), Err(&&41)); + // &Result::Ok(T).deref_ok() -> + // Result<&T::Deref::Target, &E>::Ok(&*T) + let ref_ok = &Result::Ok::<&i32, u8>(&42); + let expected_result = Result::Ok::<&i32, &u8>(&42); + assert_eq!(ref_ok.deref_ok(), expected_result); + + let ref_ok = &Result::Ok::(String::from("a result")); + let expected_result = Result::Ok::<&str, &u32>("a result"); + assert_eq!(ref_ok.deref_ok(), expected_result); + + let ref_ok = &Result::Ok::, u32>(vec![1, 2, 3, 4, 5]); + let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]); + assert_eq!(ref_ok.deref_ok(), expected_result); + + // &Result::Ok(T).deref() -> + // Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T) + let ref_ok = &Result::Ok::<&i32, &u8>(&42); + let expected_result = Result::Ok::<&i32, &u8>(&42); + assert_eq!(ref_ok.deref(), expected_result); + + let ref_ok = &Result::Ok::(String::from("a result")); + let expected_result = Result::Ok::<&str, &u32>("a result"); + assert_eq!(ref_ok.deref(), expected_result); + + let ref_ok = &Result::Ok::, &u32>(vec![1, 2, 3, 4, 5]); + let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]); + assert_eq!(ref_ok.deref(), expected_result); + + // &Result::Err(T).deref_err() -> + // Result<&T, &E::Deref::Target>::Err(&*E) + let ref_err = &Result::Err::(&41); + let expected_result = Result::Err::<&u8, &i32>(&41); + assert_eq!(ref_err.deref_err(), expected_result); + + let ref_err = &Result::Err::(String::from("an error")); + let expected_result = Result::Err::<&u32, &str>("an error"); + assert_eq!(ref_err.deref_err(), expected_result); + + let ref_err = &Result::Err::>(vec![5, 4, 3, 2, 1]); + let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); + assert_eq!(ref_err.deref_err(), expected_result); + + // &Result::Err(T).deref_err() -> + // Result<&T, &E::Deref::Target>::Err(&*E) + let ref_err = &Result::Err::<&u8, &i32>(&41); + let expected_result = Result::Err::<&u8, &i32>(&41); + assert_eq!(ref_err.deref(), expected_result); + + let ref_err = &Result::Err::<&u32, String>(String::from("an error")); + let expected_result = Result::Err::<&u32, &str>("an error"); + assert_eq!(ref_err.deref(), expected_result); + + let ref_err = &Result::Err::<&u32, Vec>(vec![5, 4, 3, 2, 1]); + let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); + assert_eq!(ref_err.deref(), expected_result); + + // *Odd corner cases (tested for completeness)* + + // &Result::Ok(T).deref_err() -> + // Result<&T, &E::Deref::Target>::Ok(&T) + let ref_ok = &Result::Ok::(42); + let expected_result = Result::Ok::<&i32, &u8>(&42); + assert_eq!(ref_ok.deref_err(), expected_result); + + let ref_ok = &Result::Ok::<&str, &u32>("a result"); + let expected_result = Result::Ok::<&&str, &u32>(&"a result"); + assert_eq!(ref_ok.deref_err(), expected_result); + + let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]); + let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]); + assert_eq!(ref_ok.deref_err(), expected_result); + + // &Result::Err(E).deref_ok() -> + // Result<&T::Deref::Target, &E>::Err(&E) + let ref_err = &Result::Err::<&u8, i32>(41); + let expected_result = Result::Err::<&u8, &i32>(&41); + assert_eq!(ref_err.deref_ok(), expected_result); + + let ref_err = &Result::Err::<&u32, &str>("an error"); + let expected_result = Result::Err::<&u32, &&str>(&"an error"); + assert_eq!(ref_err.deref_ok(), expected_result); + + let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]); + let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]); + assert_eq!(ref_err.deref_ok(), expected_result); } diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs new file mode 100644 index 0000000000000..4c67fb3bef103 --- /dev/null +++ b/src/test/compile-fail/issue-50264-inner-deref-trait/option_deref.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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. + +#![feature(inner_deref)] + +fn main() { + let _result = &Some(42).deref(); +//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>` +} diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs new file mode 100644 index 0000000000000..73bdf0b920907 --- /dev/null +++ b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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. + +#![feature(inner_deref)] + +fn main() { + let _result = &Ok(42).deref(); +//~^ ERROR no method named `deref` found +} diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs new file mode 100644 index 0000000000000..5d1e7472d8f18 --- /dev/null +++ b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_err.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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. + +#![feature(inner_deref)] + +fn main() { + let _result = &Err(41).deref_err(); +//~^ ERROR no method named `deref_err` found +} diff --git a/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs new file mode 100644 index 0000000000000..bee8e0c062bae --- /dev/null +++ b/src/test/compile-fail/issue-50264-inner-deref-trait/result_deref_ok.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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. + +#![feature(inner_deref)] + +fn main() { + let _result = &Ok(42).deref_ok(); +//~^ ERROR no method named `deref_ok` found +} From e1d5509bf381d978a1894b6ba869c3b56dd3eeca Mon Sep 17 00:00:00 2001 From: Brad Gibson Date: Wed, 2 May 2018 19:16:29 -0700 Subject: [PATCH 09/39] Added comments providing justification for support of calling deref_* with wrong variant --- src/libcore/tests/result.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index fd0dd21401b88..f8b5ea5e16e48 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -290,7 +290,11 @@ fn test_result_deref() { let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); assert_eq!(ref_err.deref(), expected_result); - // *Odd corner cases (tested for completeness)* + // The following cases test calling deref_* with the wrong variant (i.e. + // `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`. + // While unusual, these cases are supported to ensure that an `inner_deref` + // call can still be made even when one of the Result types does not implement + // `Deref` (for example, std::io::Error). // &Result::Ok(T).deref_err() -> // Result<&T, &E::Deref::Target>::Ok(&T) From acdafa0fb13a8d1e1e76ce4bf4725104a0b749cb Mon Sep 17 00:00:00 2001 From: Markus Wein Date: Wed, 11 Jul 2018 13:21:10 +0200 Subject: [PATCH 10/39] Document From conversions for OsString and OsStr --- src/libstd/ffi/os_str.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index b1c6e7af693d0..9b91bd0d41efa 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -348,6 +348,11 @@ impl OsString { #[stable(feature = "rust1", since = "1.0.0")] impl From for OsString { + /// Converts a [`String`] into a [`OsString`]. + /// The conversion copies the data, and includes an allocation on the heap. + /// + /// [`String`]: ../string/struct.String.html + /// [`OsString`]: struct.OsString.html fn from(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } @@ -630,6 +635,10 @@ impl<'a> From<&'a OsStr> for Box { #[stable(feature = "os_string_from_box", since = "1.18.0")] impl From> for OsString { + /// Converts a `Box` into a `OsString` without copying or allocating. + /// + /// [`Box`]: ../boxed/struct.Box.html + /// [`OsString`]: ../ffi/struct.OsString.html fn from(boxed: Box) -> OsString { boxed.into_os_string() } @@ -637,6 +646,10 @@ impl From> for OsString { #[stable(feature = "box_from_os_string", since = "1.20.0")] impl From for Box { + /// Converts a [`OsString`] into a [`Box`]`` without copying or allocating. + /// + /// [`Box`]: ../boxed/struct.Box.html + /// [`OsString`]: ../ffi/struct.OsString.html fn from(s: OsString) -> Box { s.into_boxed_os_str() } @@ -652,6 +665,10 @@ impl Clone for Box { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Arc { + /// Converts a [`OsString`] into a [`Arc`]`` without copying or allocating. + /// + /// [`Arc`]: ../sync/struct.Arc.html + /// [`OsString`]: ../ffi/struct.OsString.html #[inline] fn from(s: OsString) -> Arc { let arc = s.inner.into_arc(); @@ -670,6 +687,10 @@ impl<'a> From<&'a OsStr> for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { + /// Converts a [`OsString`] into a [`Rc`]`` without copying or allocating. + /// + /// [`Rc`]: ../rc/struct.Rc.html + /// [`OsString`]: ../ffi/struct.OsString.html #[inline] fn from(s: OsString) -> Rc { let rc = s.inner.into_rc(); From b81ee0b370ebc1a9e15a5c6a68b2201ddbdaa36f Mon Sep 17 00:00:00 2001 From: Markus Wein Date: Wed, 11 Jul 2018 13:32:03 +0200 Subject: [PATCH 11/39] Document From conversions for CString and CStr --- src/libstd/ffi/c_str.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index b816f4b7850ef..14ace79581924 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -642,6 +642,11 @@ impl fmt::Debug for CString { #[stable(feature = "cstring_into", since = "1.7.0")] impl From for Vec { + /// Converts a [`CString`] into a [`Vec`]``. + /// The conversion consumes the [`CString`], and removes the terminating NUL byte. + /// + /// [`Vec`]: ../vec/struct.Vec.html + /// [`CString`]: ../ffi/struct.CString.html #[inline] fn from(s: CString) -> Vec { s.into_bytes() @@ -700,6 +705,10 @@ impl<'a> From<&'a CStr> for Box { #[stable(feature = "c_string_from_box", since = "1.18.0")] impl From> for CString { + /// Converts a [`Box`]`` into a [`CString`] without copying or allocating. + /// + /// [`Box`]: ../boxed/struct.Box.html + /// [`CString`]: ../ffi/struct.CString.html #[inline] fn from(s: Box) -> CString { s.into_c_string() @@ -716,6 +725,10 @@ impl Clone for Box { #[stable(feature = "box_from_c_string", since = "1.20.0")] impl From for Box { + /// Converts a [`CString`] into a [`Box`]`` without copying or allocating. + /// + /// [`CString`]: ../ffi/struct.CString.html + /// [`Box`]: ../boxed/struct.Box.html #[inline] fn from(s: CString) -> Box { s.into_boxed_c_str() @@ -748,6 +761,10 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Arc { + /// Converts a [`CString`] into a [`Arc`]`` without copying or allocating. + /// + /// [`CString`]: ../ffi/struct.CString.html + /// [`Arc`]: ../sync/struct.Arc.html #[inline] fn from(s: CString) -> Arc { let arc: Arc<[u8]> = Arc::from(s.into_inner()); @@ -766,6 +783,10 @@ impl<'a> From<&'a CStr> for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { + /// Converts a [`CString`] into a [`Rc`]`` without copying or allocating. + /// + /// [`CString`]: ../ffi/struct.CString.html + /// [`Rc`]: ../rc/struct.Rc.html #[inline] fn from(s: CString) -> Rc { let rc: Rc<[u8]> = Rc::from(s.into_inner()); @@ -839,6 +860,10 @@ impl fmt::Display for NulError { #[stable(feature = "rust1", since = "1.0.0")] impl From for io::Error { + /// Converts a [`NulError`] into a [`io::Error`]. + /// + /// [`NulError`]: ../ffi/struct.NulError.html + /// [`io::Error`]: ../io/struct.Error.html fn from(_: NulError) -> io::Error { io::Error::new(io::ErrorKind::InvalidInput, "data provided contains a nul byte") From d70bc8f86851c900203b7e62947d4b26855c9d77 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:01:19 -0500 Subject: [PATCH 12/39] AMDGPU call abi info. --- src/librustc_target/abi/call/amdgpu.rs | 42 ++++++++++++++++++++++++++ src/librustc_target/abi/call/mod.rs | 2 ++ 2 files changed, 44 insertions(+) create mode 100644 src/librustc_target/abi/call/amdgpu.rs diff --git a/src/librustc_target/abi/call/amdgpu.rs b/src/librustc_target/abi/call/amdgpu.rs new file mode 100644 index 0000000000000..62462f04d8f56 --- /dev/null +++ b/src/librustc_target/abi/call/amdgpu.rs @@ -0,0 +1,42 @@ +// Copyright 2018 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. + +use abi::call::{ArgType, FnType, }; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; + +fn classify_ret_ty<'a, Ty, C>(_tuncx: C, ret: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + ret.extend_integer_width_to(32); +} + +fn classify_arg_ty<'a, Ty, C>(_cx: C, arg: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + arg.extend_integer_width_to(32); +} + +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + if !fty.ret.is_ignore() { + classify_ret_ty(cx, &mut fty.ret); + } + + for arg in &mut fty.args { + if arg.is_ignore() { + continue; + } + classify_arg_ty(cx, arg); + } +} diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index ca5aba5b6420a..8a59fc925900a 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -13,6 +13,7 @@ use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; mod aarch64; +mod amdgpu; mod arm; mod asmjs; mod hexagon; @@ -480,6 +481,7 @@ impl<'a, Ty> FnType<'a, Ty> { x86_64::compute_abi_info(cx, self); }, "aarch64" => aarch64::compute_abi_info(cx, self), + "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), "mips" => mips::compute_abi_info(cx, self), "mips64" => mips64::compute_abi_info(cx, self), From 9d3ba6e2db8e8d496f8755eaf9db65be4349760f Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:03:39 -0500 Subject: [PATCH 13/39] Actually enable the amdgpu component if present. --- src/librustc_llvm/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 1619637b827df..316926b1995be 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -81,7 +81,7 @@ fn main() { let is_crossed = target != host; let mut optional_components = - vec!["x86", "arm", "aarch64", "mips", "powerpc", + vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"]; let mut version_cmd = Command::new(&llvm_config); From 3170507490bc9837fc8a018388fe4b341194d9ab Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:04:27 -0500 Subject: [PATCH 14/39] AMDGPU ignores `noinline` when it slaps `alwaysinline` everywhere. Allow target specs to disable that attribute. --- src/librustc_codegen_llvm/attributes.rs | 11 ++++++++--- src/librustc_codegen_llvm/callee.rs | 2 +- src/librustc_codegen_llvm/mono_item.rs | 2 +- src/librustc_target/spec/mod.rs | 9 +++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 8246bb2436694..7a51a0cf966f7 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -16,6 +16,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::session::Session; use rustc::session::config::Sanitizer; use rustc::ty::TyCtxt; +use rustc::ty::layout::HasTyCtxt; use rustc::ty::query::Providers; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::FxHashMap; @@ -30,12 +31,16 @@ use context::CodegenCx; /// Mark LLVM function to use provided inline heuristic. #[inline] -pub fn inline(val: ValueRef, inline: InlineAttr) { +pub fn inline(cx: &CodegenCx, val: ValueRef, inline: InlineAttr) { use self::InlineAttr::*; match inline { Hint => Attribute::InlineHint.apply_llfn(Function, val), Always => Attribute::AlwaysInline.apply_llfn(Function, val), - Never => Attribute::NoInline.apply_llfn(Function, val), + Never => { + if !cx.tcx().sess.target.target.options.ignore_inline_never { + Attribute::NoInline.apply_llfn(Function, val); + } + }, None => { Attribute::InlineHint.unapply_llfn(Function, val); Attribute::AlwaysInline.unapply_llfn(Function, val); @@ -126,7 +131,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) { let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(id); - inline(llfn, codegen_fn_attrs.inline); + inline(cx, llfn, codegen_fn_attrs.inline); set_frame_pointer_elimination(cx, llfn); set_probestack(cx, llfn); diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 2c01bd42cc77a..b9cb412796964 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -95,7 +95,7 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, debug!("get_fn: not casting pointer!"); if instance.def.is_inline(tcx) { - attributes::inline(llfn, attributes::InlineAttr::Hint); + attributes::inline(cx, llfn, attributes::InlineAttr::Hint); } attributes::from_fn_attrs(cx, llfn, instance.def.def_id()); diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index a528008e3b4bd..3bbcf98f20f32 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -181,7 +181,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance); if instance.def.is_inline(cx.tcx) { - attributes::inline(lldecl, attributes::InlineAttr::Hint); + attributes::inline(cx, lldecl, attributes::InlineAttr::Hint); } attributes::from_fn_attrs(cx, lldecl, instance.def.def_id()); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 9ac6e9835f06f..fc4d6f75ea689 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -635,6 +635,12 @@ pub struct TargetOptions { /// typically because the platform needs to unwind for things like stack /// unwinders. pub requires_uwtable: bool, + + /// Targets like AMDGPU add alwaysinline hints everywhere, + /// and basically inline everything regardless of our wishes anyway. + /// This causes LLVM validation errors due to the conflicting attributes. + /// Defaults to false. + pub ignore_inline_never: bool, } impl Default for TargetOptions { @@ -713,6 +719,7 @@ impl Default for TargetOptions { embed_bitcode: false, emit_debug_gdb_scripts: true, requires_uwtable: false, + ignore_inline_never: false, } } } @@ -972,6 +979,7 @@ impl Target { key!(embed_bitcode, bool); key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); + key!(ignore_inline_never, bool); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1181,6 +1189,7 @@ impl ToJson for Target { target_option_val!(embed_bitcode); target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); + target_option_val!(ignore_inline_never); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() From d992a94c3010901a29731b060621e93b77cdcbc9 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:05:08 -0500 Subject: [PATCH 15/39] Fix an AMDGPU related load bit range metadata assertion. --- src/librustc_codegen_llvm/builder.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index c71e49b0d8821..af8067bc74002 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -564,6 +564,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn range_metadata(&self, load: ValueRef, range: Range) { + if self.sess().target.target.arch == "amdgpu" { + // amdgpu/LLVM does something weird and thinks a i64 value is + // split into a v2i32, halving the bitwidth LLVM expects, + // tripping an assertion. So, for now, just disable this + // optimization. + return; + } + unsafe { let llty = val_ty(load); let v = [ From ed5edcb3186e87715143bbd53ab1dfa69771cbf9 Mon Sep 17 00:00:00 2001 From: Markus Wein Date: Mon, 23 Jul 2018 15:38:15 +0200 Subject: [PATCH 16/39] Seperate summaries from rest of the comment --- src/libstd/ffi/c_str.rs | 1 + src/libstd/ffi/os_str.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 14ace79581924..01558457f6c4c 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -643,6 +643,7 @@ impl fmt::Debug for CString { #[stable(feature = "cstring_into", since = "1.7.0")] impl From for Vec { /// Converts a [`CString`] into a [`Vec`]``. + /// /// The conversion consumes the [`CString`], and removes the terminating NUL byte. /// /// [`Vec`]: ../vec/struct.Vec.html diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 9b91bd0d41efa..9e501a84e05ec 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -349,6 +349,7 @@ impl OsString { #[stable(feature = "rust1", since = "1.0.0")] impl From for OsString { /// Converts a [`String`] into a [`OsString`]. + /// /// The conversion copies the data, and includes an allocation on the heap. /// /// [`String`]: ../string/struct.String.html From 7fb0a5204a3c35f69708b5691a93e1aa58dd025c Mon Sep 17 00:00:00 2001 From: Thomas Gideon Date: Thu, 26 Jul 2018 12:30:04 -0400 Subject: [PATCH 17/39] Update clippy to latest master --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index afd91248eda02..b0dabce47803c 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit afd91248eda02cf2968e4e02c77b6c10ecd3fd4f +Subproject commit b0dabce47803c18b935ec5390de69e04ad5304c2 From 922bf1d2acf7b779fddd1bc05415d4d9052f9ec2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 27 Jul 2018 14:01:42 +0300 Subject: [PATCH 18/39] Clarify thread::park semantics --- src/libstd/thread/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 90f054186d161..6f3945301e439 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -731,7 +731,8 @@ const NOTIFIED: usize = 2; /// specifying a maximum time to block the thread for. /// /// * The [`unpark`] method on a [`Thread`] atomically makes the token available -/// if it wasn't already. +/// if it wasn't already. Because the token is initially absent, [`unpark`] +/// followed by [`park`] will result in the second call returning immediately. /// /// In other words, each [`Thread`] acts a bit like a spinlock that can be /// locked and unlocked using `park` and `unpark`. @@ -766,6 +767,8 @@ const NOTIFIED: usize = 2; /// // Let some time pass for the thread to be spawned. /// thread::sleep(Duration::from_millis(10)); /// +/// // There is no race condition here, if `unpark` +/// // happens first, `park` will return immediately. /// println!("Unpark the thread"); /// parked_thread.thread().unpark(); /// From 5f87f78b148c1825b92514580f47866c5ae67fbb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 27 Jul 2018 14:44:20 +0300 Subject: [PATCH 19/39] Fix ws --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 6f3945301e439..e9bd0332d987b 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -731,7 +731,7 @@ const NOTIFIED: usize = 2; /// specifying a maximum time to block the thread for. /// /// * The [`unpark`] method on a [`Thread`] atomically makes the token available -/// if it wasn't already. Because the token is initially absent, [`unpark`] +/// if it wasn't already. Because the token is initially absent, [`unpark`] /// followed by [`park`] will result in the second call returning immediately. /// /// In other words, each [`Thread`] acts a bit like a spinlock that can be From b6d3143488bd91017df4d60a7229745086aa5f5f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 29 Jul 2018 15:43:54 +0900 Subject: [PATCH 20/39] pretty print for std::collections::vecdeque --- src/etc/debugger_pretty_printers_common.py | 33 ++++++++++++++++++++++ src/etc/gdb_rust_pretty_printing.py | 23 +++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/etc/debugger_pretty_printers_common.py b/src/etc/debugger_pretty_printers_common.py index 4a38d4be083fd..87c7b21bb8a35 100644 --- a/src/etc/debugger_pretty_printers_common.py +++ b/src/etc/debugger_pretty_printers_common.py @@ -47,6 +47,7 @@ TYPE_KIND_FIXED_SIZE_VEC = 16 TYPE_KIND_REGULAR_UNION = 17 TYPE_KIND_OS_STRING = 18 +TYPE_KIND_STD_VECDEQUE = 19 ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$" ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR" @@ -62,6 +63,14 @@ STD_VEC_FIELD_NAMES = [STD_VEC_FIELD_NAME_BUF, STD_VEC_FIELD_NAME_LENGTH] +# std::collections::VecDeque<> related constants +STD_VECDEQUE_FIELD_NAME_TAIL = "tail" +STD_VECDEQUE_FIELD_NAME_HEAD = "head" +STD_VECDEQUE_FIELD_NAME_BUF = "buf" +STD_VECDEQUE_FIELD_NAMES = [STD_VECDEQUE_FIELD_NAME_TAIL, + STD_VECDEQUE_FIELD_NAME_HEAD, + STD_VECDEQUE_FIELD_NAME_BUF] + # std::String related constants STD_STRING_FIELD_NAMES = ["vec"] @@ -161,6 +170,11 @@ def __classify_struct(self): self.__conforms_to_field_layout(STD_VEC_FIELD_NAMES)): return TYPE_KIND_STD_VEC + # STD COLLECTION VECDEQUE + if (unqualified_type_name.startswith("VecDeque<") and + self.__conforms_to_field_layout(STD_VECDEQUE_FIELD_NAMES)): + return TYPE_KIND_STD_VECDEQUE + # STD STRING if (unqualified_type_name.startswith("String") and self.__conforms_to_field_layout(STD_STRING_FIELD_NAMES)): @@ -325,6 +339,25 @@ def extract_length_ptr_and_cap_from_std_vec(vec_val): assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR return (length, data_ptr, capacity) + +def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val): + assert vec_val.type.get_type_kind() == TYPE_KIND_STD_VECDEQUE + tail_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_TAIL) + head_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_HEAD) + buf_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_BUF) + + tail = vec_val.get_child_at_index(tail_field_index).as_integer() + head = vec_val.get_child_at_index(head_field_index).as_integer() + buf = vec_val.get_child_at_index(buf_field_index) + + vec_ptr_val = buf.get_child_at_index(0) + capacity = buf.get_child_at_index(1).as_integer() + unique_ptr_val = vec_ptr_val.get_child_at_index(0) + data_ptr = unique_ptr_val.get_child_at_index(0) + assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR + return (tail, head, data_ptr, capacity) + + def extract_length_and_ptr_from_slice(slice_val): assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index 0612873e28153..410301ee6f16d 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -124,6 +124,9 @@ def rust_pretty_printer_lookup_function(gdb_val): if type_kind == rustpp.TYPE_KIND_STD_VEC: return RustStdVecPrinter(val) + if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE: + return RustStdVecDequePrinter(val) + if type_kind == rustpp.TYPE_KIND_STD_STRING: return RustStdStringPrinter(val) @@ -274,6 +277,26 @@ def children(self): yield (str(index), (gdb_ptr + index).dereference()) +class RustStdVecDequePrinter(object): + def __init__(self, val): + self.__val = val + + @staticmethod + def display_hint(): + return "array" + + def to_string(self): + (tail, head, data_ptr, cap) = rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + return (self.__val.type.get_unqualified_type_name() + + ("(len: %i, cap: %i)" % (head - tail, cap))) + + def children(self): + (tail, head, data_ptr, cap) = rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + gdb_ptr = data_ptr.get_wrapped_value() + for index in xrange(tail, head): + yield (str(index), (gdb_ptr + index).dereference()) + + class RustStdStringPrinter(object): def __init__(self, val): self.__val = val From ea25cf1cc6da92c85e7c17753e6b1defd8effee9 Mon Sep 17 00:00:00 2001 From: Josef Reinhard Brandl Date: Sun, 29 Jul 2018 10:31:20 +0200 Subject: [PATCH 21/39] Fix From --- src/libcore/task/wake.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 321b432d3f430..d770536ef4279 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -42,7 +42,7 @@ impl Waker { /// `Arc` type and the safe `Wake` trait. #[inline] pub unsafe fn new(inner: NonNull) -> Self { - Waker { inner: inner } + Waker { inner } } /// Wake up the task associated with this `Waker`. @@ -120,7 +120,7 @@ impl LocalWaker { /// on the current thread. #[inline] pub unsafe fn new(inner: NonNull) -> Self { - LocalWaker { inner: inner } + LocalWaker { inner } } /// Wake up the task associated with this `LocalWaker`. @@ -159,7 +159,9 @@ impl LocalWaker { impl From for Waker { #[inline] fn from(local_waker: LocalWaker) -> Self { - Waker { inner: local_waker.inner } + let inner = local_waker.inner; + mem::forget(local_waker); + Waker { inner } } } From 9ccd7eef1eeda8d207f62dae0c32d35cad7fa826 Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 29 Jul 2018 12:20:06 +0100 Subject: [PATCH 22/39] Fix -Wpessimizing-move warnings in rustllvm/PassWrapper --- src/rustllvm/PassWrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 85fbc4bf378a5..6501b3873e29c 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -1092,7 +1092,7 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true); if (!MOrErr) - return std::move(MOrErr); + return MOrErr; // The rest of this closure is a workaround for // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports @@ -1110,14 +1110,14 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { // shouldn't be a perf hit. if (Error Err = (*MOrErr)->materializeMetadata()) { Expected> Ret(std::move(Err)); - return std::move(Ret); + return Ret; } auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections"); if (WasmCustomSections) WasmCustomSections->eraseFromParent(); - return std::move(MOrErr); + return MOrErr; }; FunctionImporter Importer(Data->Index, Loader); Expected Result = Importer.importFunctions(Mod, ImportList); From 90165b82fcd455deacfbecdc79953988342d5796 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 29 Jul 2018 13:41:43 +0200 Subject: [PATCH 23/39] Make sure #47772 does not regress --- .../codegen/slice-position-bounds-check.rs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/test/codegen/slice-position-bounds-check.rs diff --git a/src/test/codegen/slice-position-bounds-check.rs b/src/test/codegen/slice-position-bounds-check.rs new file mode 100644 index 0000000000000..bcbf7fd83cf00 --- /dev/null +++ b/src/test/codegen/slice-position-bounds-check.rs @@ -0,0 +1,34 @@ +// Copyright 2017 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-system-llvm +// compile-flags: -O +#![crate_type = "lib"] + +fn search(arr: &mut [T], a: &T) -> Result { + match arr.iter().position(|x| x == a) { + Some(p) => { + Ok(p) + }, + None => Err(()), + } +} + +// CHECK-LABEL: @position_no_bounds_check +#[no_mangle] +pub fn position_no_bounds_check(y: &mut [u32], x: &u32, z: &u32) -> bool { + // This contains "call assume" so we cannot just rule out all calls + // CHECK-NOT: panic + if let Ok(p) = search(y, x) { + y[p] == *z + } else { + false + } +} From 9845ee08867e3527b9e57c86b08d38d5a0db255a Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 29 Jul 2018 23:45:32 +0900 Subject: [PATCH 24/39] fix coding style --- src/etc/gdb_rust_pretty_printing.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index 410301ee6f16d..b7de42a938417 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -286,12 +286,14 @@ def display_hint(): return "array" def to_string(self): - (tail, head, data_ptr, cap) = rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + (tail, head, data_ptr, cap) = \ + rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) return (self.__val.type.get_unqualified_type_name() + ("(len: %i, cap: %i)" % (head - tail, cap))) def children(self): - (tail, head, data_ptr, cap) = rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + (tail, head, data_ptr, cap) = \ + rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) gdb_ptr = data_ptr.get_wrapped_value() for index in xrange(tail, head): yield (str(index), (gdb_ptr + index).dereference()) From 2b25ee0764660f33e103babee1a2d5040eee4491 Mon Sep 17 00:00:00 2001 From: toidiu Date: Sun, 29 Jul 2018 21:12:58 -0400 Subject: [PATCH 25/39] update comment --- src/libsyntax/feature_gate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 087fec097191b..a32f3724cd455 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -396,7 +396,7 @@ declare_features! ( // Infer outlives requirements; RFC 2093 (active, infer_outlives_requirements, "1.26.0", Some(44493), None), - // Infer outlives requirements; RFC 2093 + // Infer static outlives requirements; RFC 2093 (active, infer_static_outlives_requirements, "1.26.0", Some(44493), None), // Multiple patterns with `|` in `if let` and `while let` From 2994b27e4033c2a0b77ab90f5a896ce09a122992 Mon Sep 17 00:00:00 2001 From: kennytm Date: Mon, 30 Jul 2018 12:06:22 +0800 Subject: [PATCH 26/39] Add timeout to use of `curl` in bootstrap.py. --- src/bootstrap/bootstrap.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 71c1c61e3d97e..829487163a945 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -88,7 +88,10 @@ def _download(path, url, probably_big, verbose, exception): option = "-#" else: option = "-s" - run(["curl", option, "--retry", "3", "-Sf", "-o", path, url], + run(["curl", option, + "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds + "--connect-timeout", "30", # timeout if cannot connect within 30 seconds + "--retry", "3", "-Sf", "-o", path, url], verbose=verbose, exception=exception) From c57deb923e56e04634b7e4b3fdc0f84ea0d41ed4 Mon Sep 17 00:00:00 2001 From: Donato Sciarra Date: Sun, 29 Jul 2018 19:50:30 +0200 Subject: [PATCH 27/39] Remove references to AUTHORS.txt file Refer instead to thanks page. --- COPYRIGHT | 4 ++-- src/doc/man/rustdoc.1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 9bc018d983d7d..e2d0ed77224e3 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -10,8 +10,8 @@ Copyrights in the Rust project are retained by their contributors. No copyright assignment is required to contribute to the Rust project. Some files include explicit copyright notices and/or license notices. -For full authorship information, see AUTHORS.txt and the version control -history. +For full authorship information, see the version control history or +https://thanks.rust-lang.org Except as otherwise noted (below and/or in individual files), Rust is licensed under the Apache License, Version 2.0 or diff --git a/src/doc/man/rustdoc.1 b/src/doc/man/rustdoc.1 index a878380f556b3..d7f78e8f6f4de 100644 --- a/src/doc/man/rustdoc.1 +++ b/src/doc/man/rustdoc.1 @@ -119,7 +119,7 @@ See <\fBhttps://github.com/rust\-lang/rust/issues\fR> for issues. .SH "AUTHOR" -See \fIAUTHORS.txt\fR in the Rust source distribution. +See the version control history or <\fBhttps://thanks.rust\-lang.org\fR> .SH "COPYRIGHT" This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms. From f162438fb3910b3b68f1b0aa664a3a89df1383de Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 30 Jul 2018 11:55:20 +0200 Subject: [PATCH 28/39] Revert "Stabilize to_bytes and from_bytes for integers." This reverts commit c8f9b84b393915a48253e3edc862c15a9b7152a7. --- src/libcore/num/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 0b8f8f0703df7..3bc2861460e14 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1903,10 +1903,12 @@ $EndFeature, " /// # Examples /// /// ``` + /// #![feature(int_to_from_bytes)] + /// /// let bytes = i32::min_value().to_be().to_bytes(); /// assert_eq!(bytes, [0x80, 0, 0, 0]); /// ``` - #[stable(feature = "int_to_from_bytes", since = "1.29.0")] + #[unstable(feature = "int_to_from_bytes", issue = "49792")] #[inline] pub fn to_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } @@ -1923,10 +1925,12 @@ $EndFeature, " /// # Examples /// /// ``` + /// #![feature(int_to_from_bytes)] + /// /// let int = i32::from_be(i32::from_bytes([0x80, 0, 0, 0])); /// assert_eq!(int, i32::min_value()); /// ``` - #[stable(feature = "int_to_from_bytes", since = "1.29.0")] + #[unstable(feature = "int_to_from_bytes", issue = "49792")] #[inline] pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } @@ -3508,10 +3512,12 @@ $EndFeature, " /// # Examples /// /// ``` + /// #![feature(int_to_from_bytes)] + /// /// let bytes = 0x1234_5678_u32.to_be().to_bytes(); /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); /// ``` - #[stable(feature = "int_to_from_bytes", since = "1.29.0")] + #[unstable(feature = "int_to_from_bytes", issue = "49792")] #[inline] pub fn to_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } @@ -3528,10 +3534,12 @@ $EndFeature, " /// # Examples /// /// ``` + /// #![feature(int_to_from_bytes)] + /// /// let int = u32::from_be(u32::from_bytes([0x12, 0x34, 0x56, 0x78])); /// assert_eq!(int, 0x1234_5678_u32); /// ``` - #[stable(feature = "int_to_from_bytes", since = "1.29.0")] + #[unstable(feature = "int_to_from_bytes", issue = "49792")] #[inline] pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } From f8d1dc88a7994d25e481d0272b555b22f9026afb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 30 Jul 2018 12:52:01 +0200 Subject: [PATCH 29/39] improve --stage documentation --- src/bootstrap/flags.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 6a013053e580c..23a02c86683b1 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -121,7 +121,10 @@ To learn more about a subcommand, run `./x.py -h`" opts.optmulti("", "exclude", "build paths to exclude", "PATH"); opts.optopt("", "on-fail", "command to run on failure", "CMD"); opts.optflag("", "dry-run", "dry run; don't build anything"); - opts.optopt("", "stage", "stage to build", "N"); + opts.optopt("", "stage", + "stage to build (indicates compiler to use/test, e.g. stage 0 uses the \ + bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)", + "N"); opts.optmulti("", "keep-stage", "stage(s) to keep without recompiling", "N"); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS"); From aa7d7d0c2b7c85ae860b9eba61d59005b0d049b0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 30 Jul 2018 12:57:20 +0200 Subject: [PATCH 30/39] improve test stage documentation --- src/bootstrap/flags.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 23a02c86683b1..60b4d65f44401 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -261,7 +261,7 @@ Arguments: ./x.py build --stage 1 src/libtest - This will first build everything once (like --stage 0 without further + This will first build everything once (like `--stage 0` without further arguments would), and then use the compiler built in stage 0 to build src/libtest and its dependencies. Once this is done, build/$ARCH/stage1 contains a usable compiler.", @@ -293,10 +293,14 @@ Arguments: ./x.py test src/test/run-pass ./x.py test src/libstd --test-args hash_map - ./x.py test src/libstd --stage 0 + ./x.py test src/libstd --stage 0 --no-doc ./x.py test src/test/ui --bless ./x.py test src/test/ui --compare-mode nll + Note that `test src/test/* --stage N` does NOT depend on `build src/rustc --stage N`; + just like `build src/libstd --stage N` it tests the compiler produced by the previous + stage. + If no arguments are passed then the complete artifacts for that stage are compiled and tested. From ca762ba9547649f57e2d8a3e56b83d0a6298fbb2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 26 Jul 2018 14:53:15 -0700 Subject: [PATCH 31/39] rustc: Disallow machine applicability in foreign macros Recent changes to lints disallowed lints from being emitted against code located in foreign macros, except for future-incompatible lints. For a future incompatible lint, however, the automatic suggestions may not be applicable! This commit updates this code path to force all applicability suggestions made to foreign macros to never be `MachineApplicable`. This should avoid rustfix actually attempting fixing these suggestions, causing non-compiling code to be produced. Closes rust-lang/cargo#5799 --- src/librustc/lint/mod.rs | 30 +++---- src/librustc_errors/diagnostic_builder.rs | 83 ++++++++++++++----- .../suggestions-not-always-applicable.rs | 22 +++++ .../suggestions-not-always-applicable.fixed | 37 +++++++++ .../suggestions-not-always-applicable.rs | 37 +++++++++ .../suggestions-not-always-applicable.stderr | 24 ++++++ src/tools/compiletest/src/header.rs | 11 +++ src/tools/compiletest/src/runtest.rs | 8 +- 8 files changed, 217 insertions(+), 35 deletions(-) create mode 100644 src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs create mode 100644 src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed create mode 100644 src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs create mode 100644 src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.stderr diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 3c1b205620892..96b7d865dc8ba 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -575,7 +575,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, // Check for future incompatibility lints and issue a stronger warning. let lints = sess.lint_store.borrow(); let lint_id = LintId::of(lint); - if let Some(future_incompatible) = lints.future_incompatible(lint_id) { + let future_incompatible = lints.future_incompatible(lint_id); + if let Some(future_incompatible) = future_incompatible { const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \ it will become a hard error"; @@ -593,20 +594,21 @@ pub fn struct_lint_level<'a>(sess: &'a Session, future_incompatible.reference); err.warn(&explanation); err.note(&citation); + } - // If this lint is *not* a future incompatibility warning then we want to be - // sure to not be too noisy in some situations. If this code originates in a - // foreign macro, aka something that this crate did not itself author, then - // it's likely that there's nothing this crate can do about it. We probably - // want to skip the lint entirely. - // - // For some lints though (like unreachable code) there's clear actionable - // items to take care of (delete the macro invocation). As a result we have - // a few lints we whitelist here for allowing a lint even though it's in a - // foreign macro invocation. - } else if !lint.report_in_external_macro { - if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) { - err.cancel(); + // If this code originates in a foreign macro, aka something that this crate + // did not itself author, then it's likely that there's nothing this crate + // can do about it. We probably want to skip the lint entirely. + if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) { + // Any suggestions made here are likely to be incorrect, so anything we + // emit shouldn't be automatically fixed by rustfix. + err.allow_suggestions(false); + + // If this is a future incompatible lint it'll become a hard error, so + // we have to emit *something*. Also allow lints to whitelist themselves + // on a case-by-case basis for emission in a foreign macro. + if future_incompatible.is_none() && !lint.report_in_external_macro { + err.cancel() } } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index a0f3abda077f9..1b34898b99084 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -26,6 +26,7 @@ use syntax_pos::{MultiSpan, Span}; pub struct DiagnosticBuilder<'a> { pub handler: &'a Handler, diagnostic: Diagnostic, + allow_suggestions: bool, } /// In general, the `DiagnosticBuilder` uses deref to allow access to @@ -186,27 +187,67 @@ impl<'a> DiagnosticBuilder<'a> { msg: &str, suggestions: Vec) -> &mut Self); - forward!(pub fn span_suggestion_with_applicability(&mut self, - sp: Span, - msg: &str, - suggestion: String, - applicability: Applicability) - -> &mut Self); - forward!(pub fn span_suggestions_with_applicability(&mut self, - sp: Span, - msg: &str, - suggestions: Vec, - applicability: Applicability) - -> &mut Self); - forward!(pub fn span_suggestion_short_with_applicability(&mut self, - sp: Span, - msg: &str, - suggestion: String, - applicability: Applicability) - -> &mut Self); + pub fn span_suggestion_with_applicability(&mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability) + -> &mut Self { + if !self.allow_suggestions { + return self + } + self.diagnostic.span_suggestion_with_applicability( + sp, + msg, + suggestion, + applicability, + ); + self + } + + pub fn span_suggestions_with_applicability(&mut self, + sp: Span, + msg: &str, + suggestions: Vec, + applicability: Applicability) + -> &mut Self { + if !self.allow_suggestions { + return self + } + self.diagnostic.span_suggestions_with_applicability( + sp, + msg, + suggestions, + applicability, + ); + self + } + + pub fn span_suggestion_short_with_applicability(&mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability) + -> &mut Self { + if !self.allow_suggestions { + return self + } + self.diagnostic.span_suggestion_short_with_applicability( + sp, + msg, + suggestion, + applicability, + ); + self + } forward!(pub fn set_span>(&mut self, sp: S) -> &mut Self); forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self); + pub fn allow_suggestions(&mut self, allow: bool) -> &mut Self { + self.allow_suggestions = allow; + self + } + /// Convenience function for internal use, clients should use one of the /// struct_* methods on Handler. pub fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> { @@ -228,7 +269,11 @@ impl<'a> DiagnosticBuilder<'a> { /// diagnostic. pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> { - DiagnosticBuilder { handler, diagnostic } + DiagnosticBuilder { + handler, + diagnostic, + allow_suggestions: true, + } } } diff --git a/src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs b/src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs new file mode 100644 index 0000000000000..7ae4731fde196 --- /dev/null +++ b/src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs @@ -0,0 +1,22 @@ +// Copyright 2018 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"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn foo(_attr: TokenStream, _f: TokenStream) -> TokenStream { + "pub fn foo() -> ::Foo { ::Foo }".parse().unwrap() +} diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed new file mode 100644 index 0000000000000..e5b47c70863e5 --- /dev/null +++ b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed @@ -0,0 +1,37 @@ +// Copyright 2018 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:suggestions-not-always-applicable.rs +// compile-flags: --edition 2015 +// run-rustfix +// rustfix-only-machine-applicable +// compile-pass + +#![feature(rust_2018_preview)] +#![warn(rust_2018_compatibility)] + +extern crate suggestions_not_always_applicable as foo; + +pub struct Foo; + +mod test { + use crate::foo::foo; + + #[foo] //~ WARN: absolute paths must start with + //~| WARN: previously accepted + //~| WARN: absolute paths + //~| WARN: previously accepted + fn main() { + } +} + +fn main() { + test::foo(); +} diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs new file mode 100644 index 0000000000000..e5b47c70863e5 --- /dev/null +++ b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs @@ -0,0 +1,37 @@ +// Copyright 2018 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:suggestions-not-always-applicable.rs +// compile-flags: --edition 2015 +// run-rustfix +// rustfix-only-machine-applicable +// compile-pass + +#![feature(rust_2018_preview)] +#![warn(rust_2018_compatibility)] + +extern crate suggestions_not_always_applicable as foo; + +pub struct Foo; + +mod test { + use crate::foo::foo; + + #[foo] //~ WARN: absolute paths must start with + //~| WARN: previously accepted + //~| WARN: absolute paths + //~| WARN: previously accepted + fn main() { + } +} + +fn main() { + test::foo(); +} diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.stderr b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.stderr new file mode 100644 index 0000000000000..76dc139b58f07 --- /dev/null +++ b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.stderr @@ -0,0 +1,24 @@ +warning: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition + --> $DIR/suggestions-not-always-applicable.rs:27:5 + | +LL | #[foo] //~ WARN: absolute paths must start with + | ^^^^^^ + | +note: lint level defined here + --> $DIR/suggestions-not-always-applicable.rs:18:9 + | +LL | #![warn(rust_2018_compatibility)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: #[warn(absolute_paths_not_starting_with_crate)] implied by #[warn(rust_2018_compatibility)] + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue TBD + +warning: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition + --> $DIR/suggestions-not-always-applicable.rs:27:5 + | +LL | #[foo] //~ WARN: absolute paths must start with + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue TBD + diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index d77261f495972..5f68d00eab1d4 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -231,6 +231,7 @@ pub struct TestProps { pub normalize_stderr: Vec<(String, String)>, pub failure_status: i32, pub run_rustfix: bool, + pub rustfix_only_machine_applicable: bool, } impl TestProps { @@ -263,6 +264,7 @@ impl TestProps { normalize_stderr: vec![], failure_status: -1, run_rustfix: false, + rustfix_only_machine_applicable: false, } } @@ -397,6 +399,11 @@ impl TestProps { if !self.run_rustfix { self.run_rustfix = config.parse_run_rustfix(ln); } + + if !self.rustfix_only_machine_applicable { + self.rustfix_only_machine_applicable = + config.parse_rustfix_only_machine_applicable(ln); + } }); if self.failure_status == -1 { @@ -663,6 +670,10 @@ impl Config { self.parse_name_directive(line, "run-rustfix") } + fn parse_rustfix_only_machine_applicable(&self, line: &str) -> bool { + self.parse_name_directive(line, "rustfix-only-machine-applicable") + } + fn parse_edition(&self, line: &str) -> Option { self.parse_name_value_directive(line, "edition") } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ce7828144cd0c..c8f3956415d53 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2624,7 +2624,11 @@ impl<'test> TestCx<'test> { let suggestions = get_suggestions_from_json( &proc_res.stderr, &HashSet::new(), - Filter::Everything, + if self.props.rustfix_only_machine_applicable { + Filter::MachineApplicableOnly + } else { + Filter::Everything + }, ).unwrap(); let fixed_code = apply_suggestions(&unfixed_code, &suggestions).expect(&format!( "failed to apply suggestions for {:?} with rustfix", @@ -2686,7 +2690,7 @@ impl<'test> TestCx<'test> { if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); } - if !res.stderr.is_empty() { + if !res.stderr.is_empty() && !self.props.rustfix_only_machine_applicable { self.fatal_proc_rec("fixed code is still producing diagnostics", &res); } } From 7a8693861e3e5816ddb391d9ab7e49ab24391b52 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 30 Jul 2018 11:09:48 -0400 Subject: [PATCH 32/39] update books for new release --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/book b/src/doc/book index f475da63a18d5..88cdde350fd3a 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit f475da63a18d50217459a601cbef69a4bcac5e71 +Subproject commit 88cdde350fd3a90c93f3bac8b4f168f105d28060 diff --git a/src/doc/nomicon b/src/doc/nomicon index 66ef7373409d1..790e96b87f4b5 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 66ef7373409d1979c2839db8886ac2ec9b6a58cd +Subproject commit 790e96b87f4b5817cac310e73a524d25c3d076d8 diff --git a/src/doc/reference b/src/doc/reference index 0f63519ea10c0..219e261ddb833 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 0f63519ea10c028f48b2dbf7d0a2454203b68b0b +Subproject commit 219e261ddb833a5683627b0a9be87a0f4486abb9 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index d2a64395a5210..e3719fc78ff4a 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit d2a64395a5210a61d3512a3a5c615f5c47699443 +Subproject commit e3719fc78ff4a21dfd13cfcc9e2ca42cb5de29f4 From d9331749f152b60ea376016fa387ed9eea5e8e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 30 Jul 2018 17:41:19 +0200 Subject: [PATCH 33/39] releases.md: fix 2 typos --- RELEASES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index b983851f88198..0368c5414e16f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -190,7 +190,7 @@ Version 1.27.0 (2018-06-21) Language -------- - [Removed 'proc' from the reserved keywords list.][49699] This allows `proc` to - be used as an identifer. + be used as an identifier. - [The dyn syntax is now available.][49968] This syntax is equivalent to the bare `Trait` syntax, and should make it clearer when being used in tandem with `impl Trait`. Since it is equivalent to the following syntax: @@ -4795,7 +4795,7 @@ Language -------- * Patterns with `ref mut` now correctly invoke [`DerefMut`] when - matching against dereferencable values. + matching against dereferenceable values. Libraries --------- From b6b025bdafe150103b443b36e2ed4c4e164814e8 Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Mon, 30 Jul 2018 17:05:30 +0100 Subject: [PATCH 34/39] Fix wrong issue number in the test name --- src/test/ui/nll/{issue-52133.rs => issue-52113.rs} | 0 src/test/ui/nll/{issue-52133.stderr => issue-52113.stderr} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/test/ui/nll/{issue-52133.rs => issue-52113.rs} (100%) rename src/test/ui/nll/{issue-52133.stderr => issue-52113.stderr} (94%) diff --git a/src/test/ui/nll/issue-52133.rs b/src/test/ui/nll/issue-52113.rs similarity index 100% rename from src/test/ui/nll/issue-52133.rs rename to src/test/ui/nll/issue-52113.rs diff --git a/src/test/ui/nll/issue-52133.stderr b/src/test/ui/nll/issue-52113.stderr similarity index 94% rename from src/test/ui/nll/issue-52133.stderr rename to src/test/ui/nll/issue-52113.stderr index c1841004cf620..4a7c10c3f1af8 100644 --- a/src/test/ui/nll/issue-52133.stderr +++ b/src/test/ui/nll/issue-52113.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/issue-52133.rs:43:9 + --> $DIR/issue-52113.rs:43:9 | LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { | -------------------- ------- these two types are declared with different lifetimes... From d8b3c830fbcdd14d085209a8dcc3399151f3286a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 26 Jul 2018 14:54:41 +0200 Subject: [PATCH 35/39] Remove the unstable std_unicode crate, deprecated since 1.27 Its former contents are now in libcore. --- src/Cargo.lock | 9 --------- src/bootstrap/compile.rs | 1 - src/bootstrap/dist.rs | 1 - src/bootstrap/doc.rs | 2 +- src/libstd/Cargo.toml | 1 - src/libstd_unicode/Cargo.toml | 14 -------------- src/libstd_unicode/lib.rs | 36 ----------------------------------- 7 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 src/libstd_unicode/Cargo.toml delete mode 100644 src/libstd_unicode/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 89daa8e09c7d1..2b0833b096629 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2615,18 +2615,9 @@ dependencies = [ "rustc_lsan 0.0.0", "rustc_msan 0.0.0", "rustc_tsan 0.0.0", - "std_unicode 0.0.0", "unwind 0.0.0", ] -[[package]] -name = "std_unicode" -version = "0.0.0" -dependencies = [ - "compiler_builtins 0.0.0", - "core 0.0.0", -] - [[package]] name = "string_cache" version = "0.7.3" diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 04e8e133b03a1..8c4f2df60fe6f 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -157,7 +157,6 @@ pub fn std_cargo(builder: &Builder, cargo.arg("--features").arg("c mem") .args(&["-p", "alloc"]) .args(&["-p", "compiler_builtins"]) - .args(&["-p", "std_unicode"]) .arg("--manifest-path") .arg(builder.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); } else { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c6b39a52ae135..188e64cd668dd 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -856,7 +856,6 @@ impl Step for Src { "src/librustc_msan", "src/librustc_tsan", "src/libstd", - "src/libstd_unicode", "src/libunwind", "src/rustc/compiler_builtins_shim", "src/rustc/libc_shim", diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 9dbbe6bcfe490..ed9b5b1773fae 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -489,7 +489,7 @@ impl Step for Std { // Keep a whitelist so we do not build internal stdlib crates, these will be // build by the rustc step later if enabled. cargo.arg("--no-deps"); - for krate in &["alloc", "core", "std", "std_unicode"] { + for krate in &["alloc", "core", "std"] { cargo.arg("-p").arg(krate); // Create all crate output directories first to make sure rustdoc uses // relative links. diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 5a2dce5930a4b..5348c9a0f3498 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -22,7 +22,6 @@ core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } -std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } [dev-dependencies] diff --git a/src/libstd_unicode/Cargo.toml b/src/libstd_unicode/Cargo.toml deleted file mode 100644 index b1c55c2e4b6ce..0000000000000 --- a/src/libstd_unicode/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "std_unicode" -version = "0.0.0" - -[lib] -name = "std_unicode" -path = "lib.rs" -test = false -bench = false - -[dependencies] -core = { path = "../libcore" } -compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs deleted file mode 100644 index c0d47f1fcb42b..0000000000000 --- a/src/libstd_unicode/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2012-2014 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. - -//! # The Unicode Library -//! -//! Unicode-intensive functions for `char` and `str` types. -//! -//! This crate provides a collection of Unicode-related functionality, -//! including decompositions, conversions, etc., and provides traits -//! implementing these functions for the `char` and `str` types. -//! -//! The functionality included here is only that which is necessary to -//! provide for basic string-related manipulations. This crate does not -//! (yet) aim to provide a full set of Unicode tables. - -#![unstable(feature = "unicode", issue = "27783")] -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", - test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] -#![no_std] - -#![feature(unicode_internals)] -#![feature(staged_api)] -#![rustc_deprecated(since = "1.27.0", reason = "moved into libcore")] - -pub use core::unicode::*; From 4ca77f702f813332defe15a0aa73707628bf592e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 26 Jul 2018 15:03:49 +0200 Subject: [PATCH 36/39] Remove unstable and deprecated APIs --- src/libcore/char/decode.rs | 127 --------------- src/libcore/char/mod.rs | 5 - src/libcore/ptr.rs | 80 ---------- src/libcore/tests/char.rs | 51 ------ src/libstd/ascii.rs | 310 ------------------------------------- src/libstd/io/buffered.rs | 46 ------ src/libstd/io/cursor.rs | 20 --- src/libstd/io/mod.rs | 148 ------------------ 8 files changed, 787 deletions(-) diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs index 0b8dce19dffa1..cc52f048b891b 100644 --- a/src/libcore/char/decode.rs +++ b/src/libcore/char/decode.rs @@ -11,135 +11,8 @@ //! UTF-8 and UTF-16 decoding iterators use fmt; -use iter::FusedIterator; use super::from_u32_unchecked; -/// An iterator over an iterator of bytes of the characters the bytes represent -/// as UTF-8 -#[unstable(feature = "decode_utf8", issue = "33906")] -#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] -#[derive(Clone, Debug)] -#[allow(deprecated)] -pub struct DecodeUtf8>(::iter::Peekable); - -/// Decodes an `Iterator` of bytes as UTF-8. -#[unstable(feature = "decode_utf8", issue = "33906")] -#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] -#[allow(deprecated)] -#[inline] -pub fn decode_utf8>(i: I) -> DecodeUtf8 { - DecodeUtf8(i.into_iter().peekable()) -} - -/// `::next` returns this for an invalid input sequence. -#[unstable(feature = "decode_utf8", issue = "33906")] -#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] -#[derive(PartialEq, Eq, Debug)] -#[allow(deprecated)] -pub struct InvalidSequence(()); - -#[unstable(feature = "decode_utf8", issue = "33906")] -#[allow(deprecated)] -impl> Iterator for DecodeUtf8 { - type Item = Result; - #[inline] - - fn next(&mut self) -> Option> { - self.0.next().map(|first_byte| { - // Emit InvalidSequence according to - // Unicode §5.22 Best Practice for U+FFFD Substitution - // http://www.unicode.org/versions/Unicode9.0.0/ch05.pdf#G40630 - - // Roughly: consume at least one byte, - // then validate one byte at a time and stop before the first unexpected byte - // (which might be the valid start of the next byte sequence). - - let mut code_point; - macro_rules! first_byte { - ($mask: expr) => { - code_point = u32::from(first_byte & $mask) - } - } - macro_rules! continuation_byte { - () => { continuation_byte!(0x80..=0xBF) }; - ($range: pat) => { - match self.0.peek() { - Some(&byte @ $range) => { - code_point = (code_point << 6) | u32::from(byte & 0b0011_1111); - self.0.next(); - } - _ => return Err(InvalidSequence(())) - } - } - } - - match first_byte { - 0x00..=0x7F => { - first_byte!(0b1111_1111); - } - 0xC2..=0xDF => { - first_byte!(0b0001_1111); - continuation_byte!(); - } - 0xE0 => { - first_byte!(0b0000_1111); - continuation_byte!(0xA0..=0xBF); // 0x80..=0x9F here are overlong - continuation_byte!(); - } - 0xE1..=0xEC | 0xEE..=0xEF => { - first_byte!(0b0000_1111); - continuation_byte!(); - continuation_byte!(); - } - 0xED => { - first_byte!(0b0000_1111); - continuation_byte!(0x80..=0x9F); // 0xA0..0xBF here are surrogates - continuation_byte!(); - } - 0xF0 => { - first_byte!(0b0000_0111); - continuation_byte!(0x90..=0xBF); // 0x80..0x8F here are overlong - continuation_byte!(); - continuation_byte!(); - } - 0xF1..=0xF3 => { - first_byte!(0b0000_0111); - continuation_byte!(); - continuation_byte!(); - continuation_byte!(); - } - 0xF4 => { - first_byte!(0b0000_0111); - continuation_byte!(0x80..=0x8F); // 0x90..0xBF here are beyond char::MAX - continuation_byte!(); - continuation_byte!(); - } - _ => return Err(InvalidSequence(())) // Illegal first byte, overlong, or beyond MAX - } - unsafe { - Ok(from_u32_unchecked(code_point)) - } - }) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (lower, upper) = self.0.size_hint(); - - // A code point is at most 4 bytes long. - let min_code_points = lower / 4; - - (min_code_points, upper) - } -} - -#[unstable(feature = "decode_utf8", issue = "33906")] -#[allow(deprecated)] -impl> FusedIterator for DecodeUtf8 {} - /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s. #[stable(feature = "decode_utf16", since = "1.9.0")] #[derive(Clone, Debug)] diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index 59bcf1383f47a..5be673db3200d 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -50,11 +50,6 @@ pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error}; pub use unicode::tables::UNICODE_VERSION; #[unstable(feature = "unicode_version", issue = "49726")] pub use unicode::version::UnicodeVersion; -#[unstable(feature = "decode_utf8", issue = "33906")] -#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] -#[allow(deprecated)] -pub use self::decode::{decode_utf8, DecodeUtf8, InvalidSequence}; use fmt::{self, Write}; use iter::FusedIterator; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fe5914c72e1ac..479c10c4ffbae 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -680,46 +680,6 @@ impl *const T { } } - /// Calculates the distance between two pointers. The returned value is in - /// units of T: the distance in bytes is divided by `mem::size_of::()`. - /// - /// If the address different between the two pointers ia not a multiple of - /// `mem::size_of::()` then the result of the division is rounded towards - /// zero. - /// - /// This function returns `None` if `T` is a zero-sized type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// #![feature(offset_to)] - /// #![allow(deprecated)] - /// - /// fn main() { - /// let a = [0; 5]; - /// let ptr1: *const i32 = &a[1]; - /// let ptr2: *const i32 = &a[3]; - /// assert_eq!(ptr1.offset_to(ptr2), Some(2)); - /// assert_eq!(ptr2.offset_to(ptr1), Some(-2)); - /// assert_eq!(unsafe { ptr1.offset(2) }, ptr2); - /// assert_eq!(unsafe { ptr2.offset(-2) }, ptr1); - /// } - /// ``` - #[unstable(feature = "offset_to", issue = "41079")] - #[rustc_deprecated(since = "1.27.0", reason = "Replaced by `wrapping_offset_from`, with the \ - opposite argument order. If you're writing unsafe code, consider `offset_from`.")] - #[inline] - pub fn offset_to(self, other: *const T) -> Option where T: Sized { - let size = mem::size_of::(); - if size == 0 { - None - } else { - Some(other.wrapping_offset_from(self)) - } - } - /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::()`. /// @@ -1464,46 +1424,6 @@ impl *mut T { } } - /// Calculates the distance between two pointers. The returned value is in - /// units of T: the distance in bytes is divided by `mem::size_of::()`. - /// - /// If the address different between the two pointers ia not a multiple of - /// `mem::size_of::()` then the result of the division is rounded towards - /// zero. - /// - /// This function returns `None` if `T` is a zero-sized type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// #![feature(offset_to)] - /// #![allow(deprecated)] - /// - /// fn main() { - /// let mut a = [0; 5]; - /// let ptr1: *mut i32 = &mut a[1]; - /// let ptr2: *mut i32 = &mut a[3]; - /// assert_eq!(ptr1.offset_to(ptr2), Some(2)); - /// assert_eq!(ptr2.offset_to(ptr1), Some(-2)); - /// assert_eq!(unsafe { ptr1.offset(2) }, ptr2); - /// assert_eq!(unsafe { ptr2.offset(-2) }, ptr1); - /// } - /// ``` - #[unstable(feature = "offset_to", issue = "41079")] - #[rustc_deprecated(since = "1.27.0", reason = "Replaced by `wrapping_offset_from`, with the \ - opposite argument order. If you're writing unsafe code, consider `offset_from`.")] - #[inline] - pub fn offset_to(self, other: *const T) -> Option where T: Sized { - let size = mem::size_of::(); - if size == 0 { - None - } else { - Some(other.wrapping_offset_from(self)) - } - } - /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::()`. /// diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs index d2a9ed75be658..46c54056e2cc9 100644 --- a/src/libcore/tests/char.rs +++ b/src/libcore/tests/char.rs @@ -363,54 +363,3 @@ fn eu_iterator_specializations() { check('\u{12340}'); check('\u{10FFFF}'); } - -#[test] -#[allow(deprecated)] -fn test_decode_utf8() { - macro_rules! assert_decode_utf8 { - ($input_bytes: expr, $expected_str: expr) => { - let input_bytes: &[u8] = &$input_bytes; - let s = char::decode_utf8(input_bytes.iter().cloned()) - .map(|r_b| r_b.unwrap_or('\u{FFFD}')) - .collect::(); - assert_eq!(s, $expected_str, - "input bytes: {:?}, expected str: {:?}, result: {:?}", - input_bytes, $expected_str, s); - assert_eq!(String::from_utf8_lossy(&$input_bytes), $expected_str); - } - } - - assert_decode_utf8!([], ""); - assert_decode_utf8!([0x41], "A"); - assert_decode_utf8!([0xC1, 0x81], "��"); - assert_decode_utf8!([0xE2, 0x99, 0xA5], "♥"); - assert_decode_utf8!([0xE2, 0x99, 0xA5, 0x41], "♥A"); - assert_decode_utf8!([0xE2, 0x99], "�"); - assert_decode_utf8!([0xE2, 0x99, 0x41], "�A"); - assert_decode_utf8!([0xC0], "�"); - assert_decode_utf8!([0xC0, 0x41], "�A"); - assert_decode_utf8!([0x80], "�"); - assert_decode_utf8!([0x80, 0x41], "�A"); - assert_decode_utf8!([0xFE], "�"); - assert_decode_utf8!([0xFE, 0x41], "�A"); - assert_decode_utf8!([0xFF], "�"); - assert_decode_utf8!([0xFF, 0x41], "�A"); - assert_decode_utf8!([0xC0, 0x80], "��"); - - // Surrogates - assert_decode_utf8!([0xED, 0x9F, 0xBF], "\u{D7FF}"); - assert_decode_utf8!([0xED, 0xA0, 0x80], "���"); - assert_decode_utf8!([0xED, 0xBF, 0x80], "���"); - assert_decode_utf8!([0xEE, 0x80, 0x80], "\u{E000}"); - - // char::MAX - assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0xBF], "\u{10FFFF}"); - assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0x41], "�A"); - assert_decode_utf8!([0xF4, 0x90, 0x80, 0x80], "����"); - - // 5 and 6 bytes sequence - // Part of the original design of UTF-8, - // but invalid now that UTF-8 is artificially restricted to match the range of UTF-16. - assert_decode_utf8!([0xF8, 0x80, 0x80, 0x80, 0x80], "�����"); - assert_decode_utf8!([0xFC, 0x80, 0x80, 0x80, 0x80, 0x80], "������"); -} diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 376410677346c..0c8e95aa42624 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -154,180 +154,6 @@ pub trait AsciiExt { /// [`to_ascii_lowercase`]: #tymethod.to_ascii_lowercase #[stable(feature = "ascii", since = "1.9.0")] fn make_ascii_lowercase(&mut self); - - /// Checks if the value is an ASCII alphabetic character: - /// U+0041 'A' ... U+005A 'Z' or U+0061 'a' ... U+007A 'z'. - /// For strings, true if all characters in the string are - /// ASCII alphabetic. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_alphabetic)`. - /// For `str` use `.bytes().all(u8::is_ascii_alphabetic)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII uppercase character: - /// U+0041 'A' ... U+005A 'Z'. - /// For strings, true if all characters in the string are - /// ASCII uppercase. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_uppercase)`. - /// For `str` use `.bytes().all(u8::is_ascii_uppercase)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_uppercase(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII lowercase character: - /// U+0061 'a' ... U+007A 'z'. - /// For strings, true if all characters in the string are - /// ASCII lowercase. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_lowercase)`. - /// For `str` use `.bytes().all(u8::is_ascii_lowercase)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_lowercase(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII alphanumeric character: - /// U+0041 'A' ... U+005A 'Z', U+0061 'a' ... U+007A 'z', or - /// U+0030 '0' ... U+0039 '9'. - /// For strings, true if all characters in the string are - /// ASCII alphanumeric. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_alphanumeric)`. - /// For `str` use `.bytes().all(u8::is_ascii_alphanumeric)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII decimal digit: - /// U+0030 '0' ... U+0039 '9'. - /// For strings, true if all characters in the string are - /// ASCII digits. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_digit)`. - /// For `str` use `.bytes().all(u8::is_ascii_digit)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_digit(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII hexadecimal digit: - /// U+0030 '0' ... U+0039 '9', U+0041 'A' ... U+0046 'F', or - /// U+0061 'a' ... U+0066 'f'. - /// For strings, true if all characters in the string are - /// ASCII hex digits. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_hexdigit)`. - /// For `str` use `.bytes().all(u8::is_ascii_hexdigit)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII punctuation character: - /// - /// U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /` - /// U+003A ... U+0040 `: ; < = > ? @` - /// U+005B ... U+0060 ``[ \\ ] ^ _ ` `` - /// U+007B ... U+007E `{ | } ~` - /// - /// For strings, true if all characters in the string are - /// ASCII punctuation. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_punctuation)`. - /// For `str` use `.bytes().all(u8::is_ascii_punctuation)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_punctuation(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII graphic character: - /// U+0021 '!' ... U+007E '~'. - /// For strings, true if all characters in the string are - /// ASCII graphic characters. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_graphic)`. - /// For `str` use `.bytes().all(u8::is_ascii_graphic)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_graphic(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII whitespace character: - /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED, - /// U+000C FORM FEED, or U+000D CARRIAGE RETURN. - /// For strings, true if all characters in the string are - /// ASCII whitespace. - /// - /// Rust uses the WhatWG Infra Standard's [definition of ASCII - /// whitespace][infra-aw]. There are several other definitions in - /// wide use. For instance, [the POSIX locale][pct] includes - /// U+000B VERTICAL TAB as well as all the above characters, - /// but—from the very same specification—[the default rule for - /// "field splitting" in the Bourne shell][bfs] considers *only* - /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace. - /// - /// If you are writing a program that will process an existing - /// file format, check what that format's definition of whitespace is - /// before using this function. - /// - /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace - /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01 - /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_whitespace)`. - /// For `str` use `.bytes().all(u8::is_ascii_whitespace)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_whitespace(&self) -> bool { unimplemented!(); } - - /// Checks if the value is an ASCII control character: - /// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE. - /// Note that most ASCII whitespace characters are control - /// characters, but SPACE is not. - /// - /// # Note - /// - /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8` and `char`. - /// For `[u8]` use `.iter().all(u8::is_ascii_control)`. - /// For `str` use `.bytes().all(u8::is_ascii_control)`. - #[unstable(feature = "ascii_ctype", issue = "39658")] - #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] - fn is_ascii_control(&self) -> bool { unimplemented!(); } } macro_rules! delegating_ascii_methods { @@ -352,47 +178,12 @@ macro_rules! delegating_ascii_methods { } } -macro_rules! delegating_ascii_ctype_methods { - () => { - #[inline] - fn is_ascii_alphabetic(&self) -> bool { self.is_ascii_alphabetic() } - - #[inline] - fn is_ascii_uppercase(&self) -> bool { self.is_ascii_uppercase() } - - #[inline] - fn is_ascii_lowercase(&self) -> bool { self.is_ascii_lowercase() } - - #[inline] - fn is_ascii_alphanumeric(&self) -> bool { self.is_ascii_alphanumeric() } - - #[inline] - fn is_ascii_digit(&self) -> bool { self.is_ascii_digit() } - - #[inline] - fn is_ascii_hexdigit(&self) -> bool { self.is_ascii_hexdigit() } - - #[inline] - fn is_ascii_punctuation(&self) -> bool { self.is_ascii_punctuation() } - - #[inline] - fn is_ascii_graphic(&self) -> bool { self.is_ascii_graphic() } - - #[inline] - fn is_ascii_whitespace(&self) -> bool { self.is_ascii_whitespace() } - - #[inline] - fn is_ascii_control(&self) -> bool { self.is_ascii_control() } - } -} - #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] impl AsciiExt for u8 { type Owned = u8; delegating_ascii_methods!(); - delegating_ascii_ctype_methods!(); } #[stable(feature = "rust1", since = "1.0.0")] @@ -401,7 +192,6 @@ impl AsciiExt for char { type Owned = char; delegating_ascii_methods!(); - delegating_ascii_ctype_methods!(); } #[stable(feature = "rust1", since = "1.0.0")] @@ -410,56 +200,6 @@ impl AsciiExt for [u8] { type Owned = Vec; delegating_ascii_methods!(); - - #[inline] - fn is_ascii_alphabetic(&self) -> bool { - self.iter().all(|b| b.is_ascii_alphabetic()) - } - - #[inline] - fn is_ascii_uppercase(&self) -> bool { - self.iter().all(|b| b.is_ascii_uppercase()) - } - - #[inline] - fn is_ascii_lowercase(&self) -> bool { - self.iter().all(|b| b.is_ascii_lowercase()) - } - - #[inline] - fn is_ascii_alphanumeric(&self) -> bool { - self.iter().all(|b| b.is_ascii_alphanumeric()) - } - - #[inline] - fn is_ascii_digit(&self) -> bool { - self.iter().all(|b| b.is_ascii_digit()) - } - - #[inline] - fn is_ascii_hexdigit(&self) -> bool { - self.iter().all(|b| b.is_ascii_hexdigit()) - } - - #[inline] - fn is_ascii_punctuation(&self) -> bool { - self.iter().all(|b| b.is_ascii_punctuation()) - } - - #[inline] - fn is_ascii_graphic(&self) -> bool { - self.iter().all(|b| b.is_ascii_graphic()) - } - - #[inline] - fn is_ascii_whitespace(&self) -> bool { - self.iter().all(|b| b.is_ascii_whitespace()) - } - - #[inline] - fn is_ascii_control(&self) -> bool { - self.iter().all(|b| b.is_ascii_control()) - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -468,54 +208,4 @@ impl AsciiExt for str { type Owned = String; delegating_ascii_methods!(); - - #[inline] - fn is_ascii_alphabetic(&self) -> bool { - self.bytes().all(|b| b.is_ascii_alphabetic()) - } - - #[inline] - fn is_ascii_uppercase(&self) -> bool { - self.bytes().all(|b| b.is_ascii_uppercase()) - } - - #[inline] - fn is_ascii_lowercase(&self) -> bool { - self.bytes().all(|b| b.is_ascii_lowercase()) - } - - #[inline] - fn is_ascii_alphanumeric(&self) -> bool { - self.bytes().all(|b| b.is_ascii_alphanumeric()) - } - - #[inline] - fn is_ascii_digit(&self) -> bool { - self.bytes().all(|b| b.is_ascii_digit()) - } - - #[inline] - fn is_ascii_hexdigit(&self) -> bool { - self.bytes().all(|b| b.is_ascii_hexdigit()) - } - - #[inline] - fn is_ascii_punctuation(&self) -> bool { - self.bytes().all(|b| b.is_ascii_punctuation()) - } - - #[inline] - fn is_ascii_graphic(&self) -> bool { - self.bytes().all(|b| b.is_ascii_graphic()) - } - - #[inline] - fn is_ascii_whitespace(&self) -> bool { - self.bytes().all(|b| b.is_ascii_whitespace()) - } - - #[inline] - fn is_ascii_control(&self) -> bool { - self.bytes().all(|b| b.is_ascii_control()) - } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 2babf508fdcc3..03c97de6ec1e9 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -154,33 +154,6 @@ impl BufReader { #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut R { &mut self.inner } - /// Returns `true` if there are no bytes in the internal buffer. - /// - /// # Examples - // - /// ```no_run - /// # #![feature(bufreader_is_empty)] - /// use std::io::BufReader; - /// use std::io::BufRead; - /// use std::fs::File; - /// - /// fn main() -> std::io::Result<()> { - /// let f1 = File::open("log.txt")?; - /// let mut reader = BufReader::new(f1); - /// assert!(reader.is_empty()); - /// - /// if reader.fill_buf()?.len() > 0 { - /// assert!(!reader.is_empty()); - /// } - /// Ok(()) - /// } - /// ``` - #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")] - #[rustc_deprecated(since = "1.26.0", reason = "use .buffer().is_empty() instead")] - pub fn is_empty(&self) -> bool { - self.buffer().is_empty() - } - /// Returns a reference to the internally buffered data. /// /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty. @@ -1265,25 +1238,6 @@ mod tests { assert_eq!(reader.read(&mut buf).unwrap(), 0); } - #[test] - #[allow(deprecated)] - fn read_char_buffered() { - let buf = [195, 159]; - let reader = BufReader::with_capacity(1, &buf[..]); - assert_eq!(reader.chars().next().unwrap().unwrap(), 'ß'); - } - - #[test] - #[allow(deprecated)] - fn test_chars() { - let buf = [195, 159, b'a']; - let reader = BufReader::with_capacity(1, &buf[..]); - let mut it = reader.chars(); - assert_eq!(it.next().unwrap().unwrap(), 'ß'); - assert_eq!(it.next().unwrap().unwrap(), 'a'); - assert!(it.next().is_none()); - } - #[test] #[should_panic] fn dont_panic_in_drop_on_panicked_flush() { diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 3622df16b9d0b..14f20151dca86 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -550,26 +550,6 @@ mod tests { assert_eq!(reader.read(&mut buf).unwrap(), 0); } - #[test] - #[allow(deprecated)] - fn test_read_char() { - let b = &b"Vi\xE1\xBB\x87t"[..]; - let mut c = Cursor::new(b).chars(); - assert_eq!(c.next().unwrap().unwrap(), 'V'); - assert_eq!(c.next().unwrap().unwrap(), 'i'); - assert_eq!(c.next().unwrap().unwrap(), 'ệ'); - assert_eq!(c.next().unwrap().unwrap(), 't'); - assert!(c.next().is_none()); - } - - #[test] - #[allow(deprecated)] - fn test_read_bad_char() { - let b = &b"\x80"[..]; - let mut c = Cursor::new(b).chars(); - assert!(c.next().unwrap().is_err()); - } - #[test] fn seek_past_end() { let buf = [0xff]; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 8530487484827..5e89ad45f81d2 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -270,10 +270,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use cmp; -use core::str as core_str; -use error as std_error; use fmt; -use result; use str; use memchr; use ptr; @@ -800,53 +797,6 @@ pub trait Read { Bytes { inner: self } } - /// Transforms this `Read` instance to an [`Iterator`] over [`char`]s. - /// - /// This adaptor will attempt to interpret this reader as a UTF-8 encoded - /// sequence of characters. The returned iterator will return [`None`] once - /// EOF is reached for this reader. Otherwise each element yielded will be a - /// [`Result`]`<`[`char`]`, E>` where `E` may contain information about what I/O error - /// occurred or where decoding failed. - /// - /// Currently this adaptor will discard intermediate data read, and should - /// be avoided if this is not desired. - /// - /// # Examples - /// - /// [`File`]s implement `Read`: - /// - /// [`File`]: ../fs/struct.File.html - /// [`Iterator`]: ../../std/iter/trait.Iterator.html - /// [`Result`]: ../../std/result/enum.Result.html - /// [`char`]: ../../std/primitive.char.html - /// [`None`]: ../../std/option/enum.Option.html#variant.None - /// - /// ```no_run - /// #![feature(io)] - /// use std::io; - /// use std::io::prelude::*; - /// use std::fs::File; - /// - /// fn main() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// - /// for c in f.chars() { - /// println!("{}", c.unwrap()); - /// } - /// Ok(()) - /// } - /// ``` - #[unstable(feature = "io", reason = "the semantics of a partial read/write \ - of where errors happen is currently \ - unclear and may change", - issue = "27802")] - #[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] - #[allow(deprecated)] - fn chars(self) -> Chars where Self: Sized { - Chars { inner: self } - } - /// Creates an adaptor which will chain this stream with another. /// /// The returned `Read` instance will first read all bytes from this object @@ -2005,104 +1955,6 @@ impl Iterator for Bytes { } } -/// An iterator over the `char`s of a reader. -/// -/// This struct is generally created by calling [`chars`][chars] on a reader. -/// Please see the documentation of `chars()` for more details. -/// -/// [chars]: trait.Read.html#method.chars -#[unstable(feature = "io", reason = "awaiting stability of Read::chars", - issue = "27802")] -#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] -#[derive(Debug)] -#[allow(deprecated)] -pub struct Chars { - inner: R, -} - -/// An enumeration of possible errors that can be generated from the `Chars` -/// adapter. -#[unstable(feature = "io", reason = "awaiting stability of Read::chars", - issue = "27802")] -#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead: - https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")] -#[derive(Debug)] -#[allow(deprecated)] -pub enum CharsError { - /// Variant representing that the underlying stream was read successfully - /// but it did not contain valid utf8 data. - NotUtf8, - - /// Variant representing that an I/O error occurred. - Other(Error), -} - -#[unstable(feature = "io", reason = "awaiting stability of Read::chars", - issue = "27802")] -#[allow(deprecated)] -impl Iterator for Chars { - type Item = result::Result; - - fn next(&mut self) -> Option> { - let first_byte = match read_one_byte(&mut self.inner)? { - Ok(b) => b, - Err(e) => return Some(Err(CharsError::Other(e))), - }; - let width = core_str::utf8_char_width(first_byte); - if width == 1 { return Some(Ok(first_byte as char)) } - if width == 0 { return Some(Err(CharsError::NotUtf8)) } - let mut buf = [first_byte, 0, 0, 0]; - { - let mut start = 1; - while start < width { - match self.inner.read(&mut buf[start..width]) { - Ok(0) => return Some(Err(CharsError::NotUtf8)), - Ok(n) => start += n, - Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, - Err(e) => return Some(Err(CharsError::Other(e))), - } - } - } - Some(match str::from_utf8(&buf[..width]).ok() { - Some(s) => Ok(s.chars().next().unwrap()), - None => Err(CharsError::NotUtf8), - }) - } -} - -#[unstable(feature = "io", reason = "awaiting stability of Read::chars", - issue = "27802")] -#[allow(deprecated)] -impl std_error::Error for CharsError { - fn description(&self) -> &str { - match *self { - CharsError::NotUtf8 => "invalid utf8 encoding", - CharsError::Other(ref e) => std_error::Error::description(e), - } - } - fn cause(&self) -> Option<&dyn std_error::Error> { - match *self { - CharsError::NotUtf8 => None, - CharsError::Other(ref e) => e.cause(), - } - } -} - -#[unstable(feature = "io", reason = "awaiting stability of Read::chars", - issue = "27802")] -#[allow(deprecated)] -impl fmt::Display for CharsError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - CharsError::NotUtf8 => { - "byte stream did not contain valid utf8".fmt(f) - } - CharsError::Other(ref e) => e.fmt(f), - } - } -} - /// An iterator over the contents of an instance of `BufRead` split on a /// particular byte. /// From cbbcecbee065d4031618615365b0d234fe5b112b Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 30 Jul 2018 09:13:30 -0700 Subject: [PATCH 37/39] Implement Unpin for FutureObj and LocalFutureObj --- src/libcore/future/future_obj.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcore/future/future_obj.rs b/src/libcore/future/future_obj.rs index 98c504a3f7bef..6045fac2b4b3d 100644 --- a/src/libcore/future/future_obj.rs +++ b/src/libcore/future/future_obj.rs @@ -36,6 +36,8 @@ pub struct LocalFutureObj<'a, T> { _marker: PhantomData<&'a ()>, } +impl<'a, T> Unpin for LocalFutureObj<'a, T> {} + impl<'a, T> LocalFutureObj<'a, T> { /// Create a `LocalFutureObj` from a custom trait object representation. #[inline] @@ -104,6 +106,7 @@ impl<'a, T> Drop for LocalFutureObj<'a, T> { /// information #44874) pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>); +impl<'a, T> Unpin for FutureObj<'a, T> {} unsafe impl<'a, T> Send for FutureObj<'a, T> {} impl<'a, T> FutureObj<'a, T> { From d5f1f70a8e8d3f54230fe07eb0a79002161b2788 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 Jul 2018 00:07:39 +0200 Subject: [PATCH 38/39] Fix Alias intra doc ICE --- src/librustdoc/clean/mod.rs | 40 +++++++++---------- src/librustdoc/visit_ast.rs | 4 +- src/test/rustdoc-ui/intra-doc-alias-ice.rs | 16 ++++++++ .../rustdoc-ui/intra-doc-alias-ice.stderr | 13 ++++++ 4 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 src/test/rustdoc-ui/intra-doc-alias-ice.rs create mode 100644 src/test/rustdoc-ui/intra-doc-alias-ice.stderr diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c050e30fea050..e019b26dd1dd9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1197,7 +1197,8 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option })?; match ty.def { Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => { - let item = cx.tcx.inherent_impls(did).iter() + let item = cx.tcx.inherent_impls(did) + .iter() .flat_map(|imp| cx.tcx.associated_items(*imp)) .find(|item| item.ident.name == item_name); if let Some(item) = item { @@ -1208,26 +1209,23 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option }; Ok((ty.def, Some(format!("{}.{}", out, item_name)))) } else { - let is_enum = match ty.def { - Def::Enum(_) => true, - _ => false, - }; - let elem = if is_enum { - cx.tcx.adt_def(did).all_fields().find(|item| item.ident.name == item_name) - } else { - cx.tcx.adt_def(did) - .non_enum_variant() - .fields - .iter() - .find(|item| item.ident.name == item_name) - }; - if let Some(item) = elem { - Ok((ty.def, - Some(format!("{}.{}", - if is_enum { "variant" } else { "structfield" }, - item.ident)))) - } else { - Err(()) + match cx.tcx.type_of(did).sty { + ty::TyAdt(def, _) => { + if let Some(item) = def.all_fields() + .find(|item| item.ident.name == item_name) { + Ok((ty.def, + Some(format!("{}.{}", + if def.is_enum() { + "variant" + } else { + "structfield" + }, + item.ident)))) + } else { + Err(()) + } + } + _ => Err(()), } } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 09d304b71a2c1..287913d2cc9b8 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -105,8 +105,8 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { } pub fn visit_variant_data(&mut self, item: &hir::Item, - name: ast::Name, sd: &hir::VariantData, - generics: &hir::Generics) -> Struct { + name: ast::Name, sd: &hir::VariantData, + generics: &hir::Generics) -> Struct { debug!("Visiting struct"); let struct_type = struct_type_from_def(&*sd); Struct { diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.rs b/src/test/rustdoc-ui/intra-doc-alias-ice.rs new file mode 100644 index 0000000000000..a459ab5dd2bea --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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. + +#![deny(intra_doc_link_resolution_failure)] + +pub type TypeAlias = usize; + +/// [broken cross-reference](TypeAlias::hoge) //~ ERROR +pub fn some_public_item() {} diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr new file mode 100644 index 0000000000000..231963976ea75 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr @@ -0,0 +1,13 @@ +error: `[TypeAlias::hoge]` cannot be resolved, ignoring it... + --> $DIR/intra-doc-alias-ice.rs:15:30 + | +15 | /// [broken cross-reference](TypeAlias::hoge) //~ ERROR + | ^^^^^^^^^^^^^^^ cannot be resolved, ignoring + | +note: lint level defined here + --> $DIR/intra-doc-alias-ice.rs:11:9 + | +11 | #![deny(intra_doc_link_resolution_failure)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + From 620c4fdf53ab4e1a1a4afa890e7fd534ec886ca9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 22 Jul 2018 15:01:09 -0600 Subject: [PATCH 39/39] Delete unused code in rustdoc --- src/librustdoc/clean/mod.rs | 22 ------ src/librustdoc/doctree.rs | 6 -- src/librustdoc/fold.rs | 18 ++--- src/librustdoc/html/highlight.rs | 14 ---- src/librustdoc/lib.rs | 43 +++++----- src/librustdoc/passes/mod.rs | 110 +++++++++++++++----------- src/librustdoc/passes/strip_hidden.rs | 4 +- 7 files changed, 96 insertions(+), 121 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f658d57426497..7454f79ed6bbb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -425,9 +425,6 @@ impl Item { pub fn is_enum(&self) -> bool { self.type_() == ItemType::Enum } - pub fn is_fn(&self) -> bool { - self.type_() == ItemType::Function - } pub fn is_associated_type(&self) -> bool { self.type_() == ItemType::AssociatedType } @@ -2188,10 +2185,6 @@ pub struct FnDecl { } impl FnDecl { - pub fn has_self(&self) -> bool { - self.inputs.values.len() > 0 && self.inputs.values[0].name == "self" - } - pub fn self_type(&self) -> Option { self.inputs.values.get(0).and_then(|v| v.to_self()) } @@ -3547,21 +3540,6 @@ pub struct Path { } impl Path { - pub fn singleton(name: String) -> Path { - Path { - global: false, - def: Def::Err, - segments: vec![PathSegment { - name, - args: GenericArgs::AngleBracketed { - lifetimes: Vec::new(), - types: Vec::new(), - bindings: Vec::new(), - } - }] - } - } - pub fn last_name(&self) -> &str { self.segments.last().unwrap().name.as_str() } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 591c660138aee..d6e8f3d938e93 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -11,7 +11,6 @@ //! This module is used to store stuff from Rust's AST in a more convenient //! manner (and with prettier names) before cleaning. pub use self::StructType::*; -pub use self::TypeBound::*; use syntax::ast; use syntax::ast::{Name, NodeId}; @@ -91,11 +90,6 @@ pub enum StructType { Unit, } -pub enum TypeBound { - RegionBound, - TraitBound(hir::TraitRef) -} - pub struct Struct { pub vis: hir::Visibility, pub stab: Option, diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index ddc5d56b474fc..6d96bc8e36038 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -12,19 +12,13 @@ use std::mem; use clean::*; -pub enum FoldItem { - Retain(Item), - Strip(Item), - Erase, -} +pub struct StripItem(pub Item); -impl FoldItem { - pub fn fold(self) -> Option { - match self { - FoldItem::Erase => None, - FoldItem::Retain(i) => Some(i), - FoldItem::Strip(item@ Item { inner: StrippedItem(..), .. } ) => Some(item), - FoldItem::Strip(mut i) => { +impl StripItem { + pub fn strip(self) -> Option { + match self.0 { + Item { inner: StrippedItem(..), .. } => Some(self.0), + mut i => { i.inner = StrippedItem(box i.inner); Some(i) } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 6cf9b143373a8..065778d8d0725 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -60,20 +60,6 @@ pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str> String::from_utf8_lossy(&out[..]).into_owned() } -/// Highlights `src`, returning the HTML output. Returns only the inner html to -/// be inserted into an element. C.f., `render_with_highlighting` which includes -/// an enclosing `
` block.
-pub fn render_inner_with_highlighting(src: &str) -> io::Result {
-    let sess = parse::ParseSess::new(FilePathMapping::empty());
-    let fm = sess.codemap().new_filemap(FileName::Custom("stdin".to_string()), src.to_string());
-
-    let mut out = Vec::new();
-    let mut classifier = Classifier::new(lexer::StringReader::new(&sess, fm, None), sess.codemap());
-    classifier.write_source(&mut out)?;
-
-    Ok(String::from_utf8_lossy(&out).into_owned())
-}
-
 /// Processes a program (nested in the internal `lexer`), classifying strings of
 /// text by highlighting category (`Class`). Calls out to a `Writer` to write
 /// each span of text in sequence.
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 613ca01ff82f8..041a233617083 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -25,6 +25,7 @@
 #![feature(vec_remove_item)]
 #![feature(entry_and_modify)]
 #![feature(ptr_offset_from)]
+#![feature(crate_visibility_modifier)]
 
 #![recursion_limit="256"]
 
@@ -72,28 +73,28 @@ use rustc_target::spec::TargetTriple;
 use rustc::session::config::get_cmd_lint_options;
 
 #[macro_use]
-pub mod externalfiles;
+mod externalfiles;
 
-pub mod clean;
-pub mod core;
-pub mod doctree;
-pub mod fold;
+mod clean;
+mod core;
+mod doctree;
+mod fold;
 pub mod html {
-    pub mod highlight;
-    pub mod escape;
-    pub mod item_type;
-    pub mod format;
-    pub mod layout;
+    crate mod highlight;
+    crate mod escape;
+    crate mod item_type;
+    crate mod format;
+    crate mod layout;
     pub mod markdown;
-    pub mod render;
-    pub mod toc;
+    crate mod render;
+    crate mod toc;
 }
-pub mod markdown;
-pub mod passes;
-pub mod visit_ast;
-pub mod visit_lib;
-pub mod test;
-pub mod theme;
+mod markdown;
+mod passes;
+mod visit_ast;
+mod visit_lib;
+mod test;
+mod theme;
 
 use clean::AttributesExt;
 
@@ -140,7 +141,7 @@ fn unstable(name: &'static str, f: F) -> RustcOptGroup
     RustcOptGroup::unstable(name, f)
 }
 
-pub fn opts() -> Vec {
+fn opts() -> Vec {
     vec![
         stable("h", |o| o.optflag("h", "help", "show this help message")),
         stable("V", |o| o.optflag("V", "version", "print rustdoc's version")),
@@ -334,7 +335,7 @@ pub fn opts() -> Vec {
     ]
 }
 
-pub fn usage(argv0: &str) {
+fn usage(argv0: &str) {
     let mut options = getopts::Options::new();
     for option in opts() {
         (option.apply)(&mut options);
@@ -342,7 +343,7 @@ pub fn usage(argv0: &str) {
     println!("{}", options.usage(&format!("{} [options] ", argv0)));
 }
 
-pub fn main_args(args: &[String]) -> isize {
+fn main_args(args: &[String]) -> isize {
     let mut options = getopts::Options::new();
     for option in opts() {
         (option.apply)(&mut options);
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 8de4fed5bf0c0..aa4acaf75bf31 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -15,7 +15,7 @@ use std::mem;
 
 use clean::{self, GetDefId, Item};
 use fold;
-use fold::FoldItem::Strip;
+use fold::StripItem;
 
 mod collapse_docs;
 pub use self::collapse_docs::collapse_docs;
@@ -35,24 +35,44 @@ pub use self::unindent_comments::unindent_comments;
 mod propagate_doc_cfg;
 pub use self::propagate_doc_cfg::propagate_doc_cfg;
 
-type Pass = (&'static str,                                      // name
-             fn(clean::Crate) -> clean::Crate,                  // fn
-             &'static str);                                     // description
+type Pass = (
+    &'static str,                     // name
+    fn(clean::Crate) -> clean::Crate, // fn
+    &'static str,
+); // description
 
 pub const PASSES: &'static [Pass] = &[
-    ("strip-hidden", strip_hidden,
-     "strips all doc(hidden) items from the output"),
-    ("unindent-comments", unindent_comments,
-     "removes excess indentation on comments in order for markdown to like it"),
-    ("collapse-docs", collapse_docs,
-     "concatenates all document attributes into one document attribute"),
-    ("strip-private", strip_private,
-     "strips all private items from a crate which cannot be seen externally, \
-      implies strip-priv-imports"),
-    ("strip-priv-imports", strip_priv_imports,
-     "strips all private import statements (`use`, `extern crate`) from a crate"),
-    ("propagate-doc-cfg", propagate_doc_cfg,
-     "propagates `#[doc(cfg(...))]` to child items"),
+    (
+        "strip-hidden",
+        strip_hidden,
+        "strips all doc(hidden) items from the output",
+    ),
+    (
+        "unindent-comments",
+        unindent_comments,
+        "removes excess indentation on comments in order for markdown to like it",
+    ),
+    (
+        "collapse-docs",
+        collapse_docs,
+        "concatenates all document attributes into one document attribute",
+    ),
+    (
+        "strip-private",
+        strip_private,
+        "strips all private items from a crate which cannot be seen externally, \
+         implies strip-priv-imports",
+    ),
+    (
+        "strip-priv-imports",
+        strip_priv_imports,
+        "strips all private import statements (`use`, `extern crate`) from a crate",
+    ),
+    (
+        "propagate-doc-cfg",
+        propagate_doc_cfg,
+        "propagates `#[doc(cfg(...))]` to child items",
+    ),
 ];
 
 pub const DEFAULT_PASSES: &'static [&'static str] = &[
@@ -79,15 +99,9 @@ pub enum DefaultPassOption {
 
 pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] {
     match default_set {
-        DefaultPassOption::Default => {
-            DEFAULT_PASSES
-        },
-        DefaultPassOption::Private => {
-            DEFAULT_PRIVATE_PASSES
-        },
-        DefaultPassOption::None => {
-            &[]
-        },
+        DefaultPassOption::Default => DEFAULT_PASSES,
+        DefaultPassOption::Private => DEFAULT_PRIVATE_PASSES,
+        DefaultPassOption::None => &[],
     }
 }
 
@@ -110,14 +124,21 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                 return ret;
             }
             // These items can all get re-exported
-            clean::ExistentialItem(..) |
-            clean::TypedefItem(..) | clean::StaticItem(..) |
-            clean::StructItem(..) | clean::EnumItem(..) |
-            clean::TraitItem(..) | clean::FunctionItem(..) |
-            clean::VariantItem(..) | clean::MethodItem(..) |
-            clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
-            clean::ConstantItem(..) | clean::UnionItem(..) |
-            clean::AssociatedConstItem(..) | clean::ForeignTypeItem => {
+            clean::ExistentialItem(..)
+            | clean::TypedefItem(..)
+            | clean::StaticItem(..)
+            | clean::StructItem(..)
+            | clean::EnumItem(..)
+            | clean::TraitItem(..)
+            | clean::FunctionItem(..)
+            | clean::VariantItem(..)
+            | clean::MethodItem(..)
+            | clean::ForeignFunctionItem(..)
+            | clean::ForeignStaticItem(..)
+            | clean::ConstantItem(..)
+            | clean::UnionItem(..)
+            | clean::AssociatedConstItem(..)
+            | clean::ForeignTypeItem => {
                 if i.def_id.is_local() {
                     if !self.access_levels.is_exported(i.def_id) {
                         return None;
@@ -127,14 +148,14 @@ impl<'a> fold::DocFolder for Stripper<'a> {
 
             clean::StructFieldItem(..) => {
                 if i.visibility != Some(clean::Public) {
-                    return Strip(i).fold();
+                    return StripItem(i).strip();
                 }
             }
 
             clean::ModuleItem(..) => {
                 if i.def_id.is_local() && i.visibility != Some(clean::Public) {
                     let old = mem::replace(&mut self.update_retained, false);
-                    let ret = Strip(self.fold_item_recur(i).unwrap()).fold();
+                    let ret = StripItem(self.fold_item_recur(i).unwrap()).strip();
                     self.update_retained = old;
                     return ret;
                 }
@@ -167,7 +188,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
             clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
             // Struct variant fields have inherited visibility
             clean::VariantItem(clean::Variant {
-                kind: clean::VariantKind::Struct(..)
+                kind: clean::VariantKind::Struct(..),
             }) => true,
             _ => false,
         };
@@ -192,7 +213,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
 
 // This stripper discards all impls which reference stripped items
 struct ImplStripper<'a> {
-    retained: &'a DefIdSet
+    retained: &'a DefIdSet,
 }
 
 impl<'a> fold::DocFolder for ImplStripper<'a> {
@@ -203,9 +224,7 @@ impl<'a> fold::DocFolder for ImplStripper<'a> {
                 return None;
             }
             if let Some(did) = imp.for_.def_id() {
-                if did.is_local() && !imp.for_.is_generic() &&
-                    !self.retained.contains(&did)
-                {
+                if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) {
                     return None;
                 }
             }
@@ -233,9 +252,12 @@ struct ImportStripper;
 impl fold::DocFolder for ImportStripper {
     fn fold_item(&mut self, i: Item) -> Option {
         match i.inner {
-            clean::ExternCrateItem(..) |
-            clean::ImportItem(..) if i.visibility != Some(clean::Public) => None,
-            _ => self.fold_item_recur(i)
+            clean::ExternCrateItem(..) | clean::ImportItem(..)
+                if i.visibility != Some(clean::Public) =>
+            {
+                None
+            }
+            _ => self.fold_item_recur(i),
         }
     }
 }
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index b1545233f8a2b..279c9603703cd 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -15,7 +15,7 @@ use clean::{self, AttributesExt, NestedAttributesExt};
 use clean::Item;
 use fold;
 use fold::DocFolder;
-use fold::FoldItem::Strip;
+use fold::StripItem;
 use passes::ImplStripper;
 
 /// Strip items marked `#[doc(hidden)]`
@@ -49,7 +49,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                     // strip things like impl methods but when doing so
                     // we must not add any items to the `retained` set.
                     let old = mem::replace(&mut self.update_retained, false);
-                    let ret = Strip(self.fold_item_recur(i).unwrap()).fold();
+                    let ret = StripItem(self.fold_item_recur(i).unwrap()).strip();
                     self.update_retained = old;
                     return ret;
                 }