From e42b1aa5f9ea53ad3dd86ef332c2e9eeb6c6ddd5 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 25 Sep 2021 20:49:25 +0200 Subject: [PATCH] Hide `ToString` specializations behind a private trait --- library/alloc/src/string.rs | 53 ++++++++++++++++++++++------------- library/proc_macro/src/lib.rs | 40 +++++++++++++------------- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 6568d9f9907b9..b78478e070a60 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2375,7 +2375,22 @@ impl ToString for T { // See , the last attempt // to try to remove it. #[inline] - default fn to_string(&self) -> String { + fn to_string(&self) -> String { + SpecToString::spec_to_string(self) + } +} + +#[unstable(issue = "none", feature = "spec_to_string")] +#[doc(hidden)] +pub trait SpecToString { + fn spec_to_string(&self) -> String; +} + +#[cfg(not(no_global_oom_handling))] +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for T { + #[inline] + default fn spec_to_string(&self) -> String { let mut buf = String::new(); let mut formatter = core::fmt::Formatter::new(&mut buf); // Bypass format_args!() to avoid write_str with zero-length strs @@ -2386,19 +2401,19 @@ impl ToString for T { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "char_to_string_specialization", since = "1.46.0")] -impl ToString for char { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for char { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { String::from(self.encode_utf8(&mut [0; 4])) } } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "u8_to_string_specialization", since = "1.54.0")] -impl ToString for u8 { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for u8 { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { let mut buf = String::with_capacity(3); let mut n = *self; if n >= 10 { @@ -2415,10 +2430,10 @@ impl ToString for u8 { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "i8_to_string_specialization", since = "1.54.0")] -impl ToString for i8 { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for i8 { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { let mut buf = String::with_capacity(4); if self.is_negative() { buf.push('-'); @@ -2438,28 +2453,28 @@ impl ToString for i8 { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "str_to_string_specialization", since = "1.9.0")] -impl ToString for str { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for str { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { String::from(self) } } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")] -impl ToString for Cow<'_, str> { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for Cow<'_, str> { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { self[..].to_owned() } } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "string_to_string_specialization", since = "1.17.0")] -impl ToString for String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for String { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { self.to_owned() } } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index e21a1507a62e2..dc2f41cc6f74f 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -31,6 +31,7 @@ #![feature(restricted_std)] #![feature(rustc_attrs)] #![feature(min_specialization)] +#![feature(spec_to_string)] #![recursion_limit = "256"] #[unstable(feature = "proc_macro_internals", issue = "27812")] @@ -46,6 +47,7 @@ use std::cmp::Ordering; use std::ops::RangeBounds; use std::path::PathBuf; use std::str::FromStr; +use std::string::SpecToString; use std::{error, fmt, iter, mem}; /// Determines whether proc_macro has been made accessible to the currently @@ -141,9 +143,9 @@ impl FromStr for TokenStream { // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for TokenStream { - fn to_string(&self) -> String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for TokenStream { + fn spec_to_string(&self) -> String { self.0.to_string() } } @@ -624,9 +626,9 @@ impl From for TokenTree { // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for TokenTree { - fn to_string(&self) -> String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for TokenTree { + fn spec_to_string(&self) -> String { match *self { TokenTree::Group(ref t) => t.to_string(), TokenTree::Ident(ref t) => t.to_string(), @@ -754,9 +756,9 @@ impl Group { // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for Group { - fn to_string(&self) -> String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for Group { + fn spec_to_string(&self) -> String { TokenStream::from(TokenTree::from(self.clone())).to_string() } } @@ -854,9 +856,9 @@ impl Punct { // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for Punct { - fn to_string(&self) -> String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for Punct { + fn spec_to_string(&self) -> String { TokenStream::from(TokenTree::from(self.clone())).to_string() } } @@ -935,7 +937,7 @@ impl Ident { } /// Returns the span of this `Ident`, encompassing the entire string returned - /// by [`to_string`](Self::to_string). + /// by [`to_string`](ToString::to_string). #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn span(&self) -> Span { Span(self.0.span()) @@ -950,9 +952,9 @@ impl Ident { // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for Ident { - fn to_string(&self) -> String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for Ident { + fn spec_to_string(&self) -> String { TokenStream::from(TokenTree::from(self.clone())).to_string() } } @@ -1210,9 +1212,9 @@ impl FromStr for Literal { // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for Literal { - fn to_string(&self) -> String { +#[unstable(issue = "none", feature = "spec_to_string")] +impl SpecToString for Literal { + fn spec_to_string(&self) -> String { self.0.to_string() } }