diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 7da2b372f6c..ce594180c03 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1856,6 +1856,11 @@ impl str { let mut s = String::with_capacity(self.len()); for (i, c) in self[..].char_indices() { if c == 'Σ' { + // Σ maps to σ, except at the end of a word where it maps to ς. + // This is the only conditional (contextual) but language-independent mapping + // in `SpecialCasing.txt`, + // so hard-code it rather than have a generic "condition" mechanim. + // See https://github.com/rust-lang/rust/issues/26035 map_uppercase_sigma(self, i, &mut s) } else { s.extend(c.to_lowercase()); @@ -1863,9 +1868,9 @@ impl str { } return s; - #[cold] - #[inline(never)] fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) { + // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 + // for the definition of `Final_Sigma`. debug_assert!('Σ'.len_utf8() == 2); let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) && diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 0b7a4953edf..1042ec0d86f 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -1690,8 +1690,34 @@ fn trim_ws() { #[test] fn to_lowercase() { assert_eq!("".to_lowercase(), ""); + assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé "); + // https://github.com/rust-lang/rust/issues/26035 - assert_eq!("'Σ AÉΣ'Σ'' Σ DžΣ".to_lowercase(), "'σ aéσ'ς'' σ džς"); + assert_eq!("ΑΣ".to_lowercase(), "ας"); + assert_eq!("Α'Σ".to_lowercase(), "α'ς"); + assert_eq!("Α''Σ".to_lowercase(), "α''ς"); + + assert_eq!("ΑΣ Α".to_lowercase(), "ας α"); + assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α"); + assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α"); + + assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α"); + assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α"); + + assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α"); + assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α"); + + assert_eq!("Α Σ".to_lowercase(), "α σ"); + assert_eq!("Α 'Σ".to_lowercase(), "α 'σ"); + assert_eq!("Α ''Σ".to_lowercase(), "α ''σ"); + + assert_eq!("Σ".to_lowercase(), "σ"); + assert_eq!("'Σ".to_lowercase(), "'σ"); + assert_eq!("''Σ".to_lowercase(), "''σ"); + + assert_eq!("ΑΣΑ".to_lowercase(), "ασα"); + assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α"); + assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α"); } #[test] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 1343453d103..1737de827e3 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -32,7 +32,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(collections)] +#![cfg_attr(stage0, feature(collections))] #![feature(core)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 196ee45979b..5b1300b18b6 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -70,7 +70,7 @@ impl Iterator for ToUppercase { /// An iterator over the titlecase mapping of a given character, returned from /// the [`to_titlecase` method](../primitive.char.html#method.to_titlecase) on /// characters. -#[stable(feature = "unicode_case_mapping", since = "1.2.0")] +#[unstable(feature = "unicode", reason = "recently added")] pub struct ToTitlecase(CaseMappingIter); #[stable(feature = "unicode_case_mapping", since = "1.2.0")] @@ -481,7 +481,7 @@ impl char { /// Returns an iterator which yields the characters corresponding to the /// lowercase equivalent of the character. If no conversion is possible then /// an iterator with just the input character is returned. - #[stable(feature = "unicode_case_mapping", since = "1.2.0")] + #[unstable(feature = "unicode", reason = "recently added")] #[inline] pub fn to_titlecase(self) -> ToTitlecase { ToTitlecase(CaseMappingIter::new(conversions::to_title(self)))