Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make char and u8 methods const #79549

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,9 @@ impl char {
/// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_char_escape_unicode", since = "1.49.0")]
#[inline]
pub fn escape_unicode(self) -> EscapeUnicode {
pub const fn escape_unicode(self) -> EscapeUnicode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When would this ever be called in a const context given that it returns an iterator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I didn't really consider the practicality for making it const. I'm not sure about the downsides of making it callable in const context, but I'm totally fine with removing it. It'll probably be a good while before const iterators happen anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the downsides of making it callable in const context, but I'm totally fine with removing it.

Yeah, please remove the iterator functions.

let c = self as u32;

// or-ing 1 ensures that for c==0 the code computes that one
Expand Down Expand Up @@ -517,8 +518,9 @@ impl char {
/// assert_eq!('"'.escape_default().to_string(), "\\\"");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_char_escape_default", since = "1.49.0")]
jyn514 marked this conversation as resolved.
Show resolved Hide resolved
#[inline]
pub fn escape_default(self) -> EscapeDefault {
pub const fn escape_default(self) -> EscapeDefault {
Copy link
Contributor

@oli-obk oli-obk Dec 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here. I think we should not make functions const fn for now unless their result can actually be used for anything during const eval or there's a good reason to have a constant version of it. Unfortunately we are not yet at the "because we can" stage of making things const

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This concern seems to still be outstanding.

let init_state = match self {
'\t' => EscapeDefaultState::Backslash('t'),
'\r' => EscapeDefaultState::Backslash('r'),
Expand Down Expand Up @@ -576,8 +578,9 @@ impl char {
/// assert_eq!(len, tokyo.len());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_char_len_utf", since = "1.49.0")]
#[inline]
pub fn len_utf8(self) -> usize {
pub const fn len_utf8(self) -> usize {
len_utf8(self as u32)
}

Expand All @@ -601,8 +604,9 @@ impl char {
/// assert_eq!(len, 2);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_char_len_utf", since = "1.49.0")]
#[inline]
pub fn len_utf16(self) -> usize {
pub const fn len_utf16(self) -> usize {
let ch = self as u32;
if (ch & 0xFFFF) == ch { 1 } else { 2 }
}
Expand Down Expand Up @@ -1093,8 +1097,9 @@ impl char {
/// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
/// [`to_uppercase`]: #method.to_uppercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.49.0")]
#[inline]
pub fn to_ascii_uppercase(&self) -> char {
pub const fn to_ascii_uppercase(&self) -> char {
if self.is_ascii() { (*self as u8).to_ascii_uppercase() as char } else { *self }
}

Expand All @@ -1121,8 +1126,9 @@ impl char {
/// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
/// [`to_lowercase`]: #method.to_lowercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.49.0")]
#[inline]
pub fn to_ascii_lowercase(&self) -> char {
pub const fn to_ascii_lowercase(&self) -> char {
if self.is_ascii() { (*self as u8).to_ascii_lowercase() as char } else { *self }
}

Expand All @@ -1142,8 +1148,9 @@ impl char {
/// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.49.0")]
#[inline]
pub fn eq_ignore_ascii_case(&self, other: &char) -> bool {
pub const fn eq_ignore_ascii_case(&self, other: &char) -> bool {
self.to_ascii_lowercase() == other.to_ascii_lowercase()
}

Expand Down Expand Up @@ -1560,7 +1567,7 @@ impl char {
}

#[inline]
fn len_utf8(code: u32) -> usize {
const fn len_utf8(code: u32) -> usize {
if code < MAX_ONE_B {
1
} else if code < MAX_TWO_B {
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,9 @@ impl u8 {
///
/// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.49.0")]
#[inline]
pub fn to_ascii_uppercase(&self) -> u8 {
pub const fn to_ascii_uppercase(&self) -> u8 {
// Unset the fifth bit if this is a lowercase letter
*self & !((self.is_ascii_lowercase() as u8) << 5)
}
Expand All @@ -222,8 +223,9 @@ impl u8 {
///
/// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.49.0")]
#[inline]
pub fn to_ascii_lowercase(&self) -> u8 {
pub const fn to_ascii_lowercase(&self) -> u8 {
// Set the fifth bit if this is an uppercase letter
*self | ((self.is_ascii_uppercase() as u8) << 5)
}
Expand All @@ -241,8 +243,9 @@ impl u8 {
/// assert!(lowercase_a.eq_ignore_ascii_case(&uppercase_a));
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.49.0")]
#[inline]
pub fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
pub const fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
self.to_ascii_lowercase() == other.to_ascii_lowercase()
}

Expand Down