Skip to content

Commit

Permalink
Hide ToString specializations behind a private trait
Browse files Browse the repository at this point in the history
  • Loading branch information
SkiFire13 committed Sep 25, 2021
1 parent 63cc2bb commit e42b1aa
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 38 deletions.
53 changes: 34 additions & 19 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2375,7 +2375,22 @@ impl<T: fmt::Display + ?Sized> ToString for T {
// See <https://github.com/rust-lang/rust/pull/74852>, 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<T: fmt::Display + ?Sized> 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
Expand All @@ -2386,19 +2401,19 @@ impl<T: fmt::Display + ?Sized> 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 {
Expand All @@ -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('-');
Expand All @@ -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()
}
}
Expand Down
40 changes: 21 additions & 19 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -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
Expand Down Expand Up @@ -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()
}
}
Expand Down Expand Up @@ -624,9 +626,9 @@ impl From<Literal> 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(),
Expand Down Expand Up @@ -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()
}
}
Expand Down Expand Up @@ -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()
}
}
Expand Down Expand Up @@ -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())
Expand All @@ -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()
}
}
Expand Down Expand Up @@ -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()
}
}
Expand Down

0 comments on commit e42b1aa

Please sign in to comment.