From 6a16ec52aa0d91945577c99cdf421b303b59301e Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Tue, 4 May 2021 14:10:49 +0300
Subject: [PATCH 1/2] internal: use API stabilized in 1.52

---
 crates/ide_completion/src/context.rs |  2 +-
 crates/ide_db/src/line_index.rs      |  7 ++-
 crates/project_model/src/cfg_flag.rs |  3 +-
 crates/stdx/src/lib.rs               | 78 ++--------------------------
 crates/test_utils/src/fixture.rs     | 10 ++--
 crates/test_utils/src/lib.rs         |  4 +-
 xtask/src/install.rs                 |  2 +-
 7 files changed, 16 insertions(+), 90 deletions(-)

diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index f3fcb712c7e..ae2900b5c2f 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -381,7 +381,7 @@ impl<'a> CompletionContext<'a> {
                         let def = self.sema.to_def(&it);
                         (def.map(|def| def.ret_type(self.db)), None)
                     },
-                    ast::Stmt(it) => (None, None),
+                    ast::Stmt(_) => (None, None),
                     _ => {
                         match node.parent() {
                             Some(n) => {
diff --git a/crates/ide_db/src/line_index.rs b/crates/ide_db/src/line_index.rs
index 8e9d8cca233..816edfe6a8e 100644
--- a/crates/ide_db/src/line_index.rs
+++ b/crates/ide_db/src/line_index.rs
@@ -3,7 +3,6 @@
 use std::iter;
 
 use rustc_hash::FxHashMap;
-use stdx::partition_point;
 use syntax::{TextRange, TextSize};
 
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -97,7 +96,7 @@ impl LineIndex {
     }
 
     pub fn line_col(&self, offset: TextSize) -> LineCol {
-        let line = partition_point(&self.newlines, |&it| it <= offset) - 1;
+        let line = self.newlines.partition_point(|&it| it <= offset) - 1;
         let line_start_offset = self.newlines[line];
         let col = offset - line_start_offset;
         LineCol { line: line as u32, col: col.into() }
@@ -118,8 +117,8 @@ impl LineIndex {
     }
 
     pub fn lines(&self, range: TextRange) -> impl Iterator<Item = TextRange> + '_ {
-        let lo = partition_point(&self.newlines, |&it| it < range.start());
-        let hi = partition_point(&self.newlines, |&it| it <= range.end());
+        let lo = self.newlines.partition_point(|&it| it < range.start());
+        let hi = self.newlines.partition_point(|&it| it <= range.end());
         let all = iter::once(range.start())
             .chain(self.newlines[lo..hi].iter().copied())
             .chain(iter::once(range.end()));
diff --git a/crates/project_model/src/cfg_flag.rs b/crates/project_model/src/cfg_flag.rs
index e92962cf672..bfdfd458fbf 100644
--- a/crates/project_model/src/cfg_flag.rs
+++ b/crates/project_model/src/cfg_flag.rs
@@ -4,7 +4,6 @@
 use std::str::FromStr;
 
 use cfg::CfgOptions;
-use stdx::split_once;
 
 #[derive(Clone, Eq, PartialEq, Debug)]
 pub enum CfgFlag {
@@ -15,7 +14,7 @@ pub enum CfgFlag {
 impl FromStr for CfgFlag {
     type Err = String;
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        let res = match split_once(s, '=') {
+        let res = match s.split_once('=') {
             Some((key, value)) => {
                 if !(value.starts_with('"') && value.ends_with('"')) {
                     return Err(format!("Invalid cfg ({:?}), value should be in quotes", s));
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index 1b6211044b4..340fcacfa3f 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -65,20 +65,6 @@ pub fn replace(buf: &mut String, from: char, to: &str) {
     *buf = buf.replace(from, to)
 }
 
-// https://github.com/rust-lang/rust/issues/74773
-pub fn split_once(haystack: &str, delim: char) -> Option<(&str, &str)> {
-    let mut split = haystack.splitn(2, delim);
-    let prefix = split.next()?;
-    let suffix = split.next()?;
-    Some((prefix, suffix))
-}
-pub fn rsplit_once(haystack: &str, delim: char) -> Option<(&str, &str)> {
-    let mut split = haystack.rsplitn(2, delim);
-    let suffix = split.next()?;
-    let prefix = split.next()?;
-    Some((prefix, suffix))
-}
-
 pub fn trim_indent(mut text: &str) -> String {
     if text.starts_with('\n') {
         text = &text[1..];
@@ -89,7 +75,7 @@ pub fn trim_indent(mut text: &str) -> String {
         .map(|it| it.len() - it.trim_start().len())
         .min()
         .unwrap_or(0);
-    lines_with_ends(text)
+    text.split_inclusive('\n')
         .map(
             |line| {
                 if line.len() <= indent {
@@ -102,70 +88,12 @@ pub fn trim_indent(mut text: &str) -> String {
         .collect()
 }
 
-pub fn lines_with_ends(text: &str) -> LinesWithEnds {
-    LinesWithEnds { text }
-}
-
-pub struct LinesWithEnds<'a> {
-    text: &'a str,
-}
-
-impl<'a> Iterator for LinesWithEnds<'a> {
-    type Item = &'a str;
-    fn next(&mut self) -> Option<&'a str> {
-        if self.text.is_empty() {
-            return None;
-        }
-        let idx = self.text.find('\n').map_or(self.text.len(), |it| it + 1);
-        let (res, next) = self.text.split_at(idx);
-        self.text = next;
-        Some(res)
-    }
-}
-
-/// Returns `idx` such that:
-///
-/// ```text
-///     ∀ x in slice[..idx]:  pred(x)
-///  && ∀ x in slice[idx..]: !pred(x)
-/// ```
-///
-/// https://github.com/rust-lang/rust/issues/73831
-pub fn partition_point<T, P>(slice: &[T], mut pred: P) -> usize
-where
-    P: FnMut(&T) -> bool,
-{
-    let mut left = 0;
-    let mut right = slice.len();
-
-    while left != right {
-        let mid = left + (right - left) / 2;
-        // SAFETY:
-        // When left < right, left <= mid < right.
-        // Therefore left always increases and right always decreases,
-        // and either of them is selected.
-        // In both cases left <= right is satisfied.
-        // Therefore if left < right in a step,
-        // left <= right is satisfied in the next step.
-        // Therefore as long as left != right, 0 <= left < right <= len is satisfied
-        // and if this case 0 <= mid < len is satisfied too.
-        let value = unsafe { slice.get_unchecked(mid) };
-        if pred(value) {
-            left = mid + 1;
-        } else {
-            right = mid;
-        }
-    }
-
-    left
-}
-
 pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize>
 where
     F: FnMut(&T) -> Ordering,
 {
-    let start = partition_point(slice, |it| key(it) == Ordering::Less);
-    let len = partition_point(&slice[start..], |it| key(it) == Ordering::Equal);
+    let start = slice.partition_point(|it| key(it) == Ordering::Less);
+    let len = slice[start..].partition_point(|it| key(it) == Ordering::Equal);
     start..start + len
 }
 
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index 099baeca2fc..d0bddf7d81f 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -62,7 +62,7 @@
 //! ```
 
 use rustc_hash::FxHashMap;
-use stdx::{lines_with_ends, split_once, trim_indent};
+use stdx::trim_indent;
 
 #[derive(Debug, Eq, PartialEq)]
 pub struct Fixture {
@@ -93,7 +93,7 @@ impl Fixture {
 
         let default = if ra_fixture.contains("//-") { None } else { Some("//- /main.rs") };
 
-        for (ix, line) in default.into_iter().chain(lines_with_ends(&fixture)).enumerate() {
+        for (ix, line) in default.into_iter().chain(fixture.split_inclusive('\n')).enumerate() {
             if line.contains("//-") {
                 assert!(
                     line.starts_with("//-"),
@@ -133,14 +133,14 @@ impl Fixture {
         let mut env = FxHashMap::default();
         let mut introduce_new_source_root = false;
         for component in components[1..].iter() {
-            let (key, value) = split_once(component, ':').unwrap();
+            let (key, value) = component.split_once(':').unwrap();
             match key {
                 "crate" => krate = Some(value.to_string()),
                 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
                 "edition" => edition = Some(value.to_string()),
                 "cfg" => {
                     for entry in value.split(',') {
-                        match split_once(entry, '=') {
+                        match entry.split_once('=') {
                             Some((k, v)) => cfg_key_values.push((k.to_string(), v.to_string())),
                             None => cfg_atoms.push(entry.to_string()),
                         }
@@ -148,7 +148,7 @@ impl Fixture {
                 }
                 "env" => {
                     for key in value.split(',') {
-                        if let Some((k, v)) = split_once(key, '=') {
+                        if let Some((k, v)) = key.split_once('=') {
                             env.insert(k.into(), v.into());
                         }
                     }
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 72466c9570f..fce4fd6bf2b 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -17,7 +17,7 @@ use std::{
 };
 
 use profile::StopWatch;
-use stdx::{is_ci, lines_with_ends};
+use stdx::is_ci;
 use text_size::{TextRange, TextSize};
 
 pub use dissimilar::diff as __diff;
@@ -181,7 +181,7 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
     let mut prev_line_start: Option<TextSize> = None;
     let mut line_start: TextSize = 0.into();
     let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new();
-    for line in lines_with_ends(text) {
+    for line in text.split_inclusive('\n') {
         let mut this_line_annotations = Vec::new();
         if let Some(idx) = line.find("//") {
             let annotation_offset = TextSize::of(&line[..idx + "//".len()]);
diff --git a/xtask/src/install.rs b/xtask/src/install.rs
index 91d6a28533e..7e2dccdfe09 100644
--- a/xtask/src/install.rs
+++ b/xtask/src/install.rs
@@ -8,7 +8,7 @@ use xshell::{cmd, pushd};
 use crate::flags;
 
 // Latest stable, feel free to send a PR if this lags behind.
-const REQUIRED_RUST_VERSION: u32 = 51;
+const REQUIRED_RUST_VERSION: u32 = 52;
 
 impl flags::Install {
     pub(crate) fn run(self) -> Result<()> {

From 607d8a2f61e56fabb7a3bc5132592917fcdca970 Mon Sep 17 00:00:00 2001
From: Kirill Bulatov <mail4score@gmail.com>
Date: Thu, 6 May 2021 20:12:30 +0300
Subject: [PATCH 2/2] Small macro fix

---
 crates/ide_completion/src/context.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index ae2900b5c2f..62ef4081828 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -381,7 +381,7 @@ impl<'a> CompletionContext<'a> {
                         let def = self.sema.to_def(&it);
                         (def.map(|def| def.ret_type(self.db)), None)
                     },
-                    ast::Stmt(_) => (None, None),
+                    ast::Stmt(_it) => (None, None),
                     _ => {
                         match node.parent() {
                             Some(n) => {