aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-06 18:29:30 +0100
committerGitHub <[email protected]>2021-05-06 18:29:30 +0100
commitb37b709459a4ff881a91965ebf0c39e3a449c304 (patch)
tree49eba918834c5a4fec5a8d5de39589219c81c846 /crates
parent3b4d5df840f1c6a077ad1886a98ef453811a599f (diff)
parent607d8a2f61e56fabb7a3bc5132592917fcdca970 (diff)
Merge #8718
8718: 1.52.0 r=SomeoneToIgnore a=matklad A lot of APIs we use in this release! Co-authored-by: Aleksey Kladov <[email protected]> Co-authored-by: Kirill Bulatov <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ide_completion/src/context.rs2
-rw-r--r--crates/ide_db/src/line_index.rs7
-rw-r--r--crates/project_model/src/cfg_flag.rs3
-rw-r--r--crates/stdx/src/lib.rs78
-rw-r--r--crates/test_utils/src/fixture.rs10
-rw-r--r--crates/test_utils/src/lib.rs4
6 files changed, 15 insertions, 89 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index f3fcb712c..62ef40818 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -381,7 +381,7 @@ impl<'a> CompletionContext<'a> {
381 let def = self.sema.to_def(&it); 381 let def = self.sema.to_def(&it);
382 (def.map(|def| def.ret_type(self.db)), None) 382 (def.map(|def| def.ret_type(self.db)), None)
383 }, 383 },
384 ast::Stmt(it) => (None, None), 384 ast::Stmt(_it) => (None, None),
385 _ => { 385 _ => {
386 match node.parent() { 386 match node.parent() {
387 Some(n) => { 387 Some(n) => {
diff --git a/crates/ide_db/src/line_index.rs b/crates/ide_db/src/line_index.rs
index 8e9d8cca2..816edfe6a 100644
--- a/crates/ide_db/src/line_index.rs
+++ b/crates/ide_db/src/line_index.rs
@@ -3,7 +3,6 @@
3use std::iter; 3use std::iter;
4 4
5use rustc_hash::FxHashMap; 5use rustc_hash::FxHashMap;
6use stdx::partition_point;
7use syntax::{TextRange, TextSize}; 6use syntax::{TextRange, TextSize};
8 7
9#[derive(Clone, Debug, PartialEq, Eq)] 8#[derive(Clone, Debug, PartialEq, Eq)]
@@ -97,7 +96,7 @@ impl LineIndex {
97 } 96 }
98 97
99 pub fn line_col(&self, offset: TextSize) -> LineCol { 98 pub fn line_col(&self, offset: TextSize) -> LineCol {
100 let line = partition_point(&self.newlines, |&it| it <= offset) - 1; 99 let line = self.newlines.partition_point(|&it| it <= offset) - 1;
101 let line_start_offset = self.newlines[line]; 100 let line_start_offset = self.newlines[line];
102 let col = offset - line_start_offset; 101 let col = offset - line_start_offset;
103 LineCol { line: line as u32, col: col.into() } 102 LineCol { line: line as u32, col: col.into() }
@@ -118,8 +117,8 @@ impl LineIndex {
118 } 117 }
119 118
120 pub fn lines(&self, range: TextRange) -> impl Iterator<Item = TextRange> + '_ { 119 pub fn lines(&self, range: TextRange) -> impl Iterator<Item = TextRange> + '_ {
121 let lo = partition_point(&self.newlines, |&it| it < range.start()); 120 let lo = self.newlines.partition_point(|&it| it < range.start());
122 let hi = partition_point(&self.newlines, |&it| it <= range.end()); 121 let hi = self.newlines.partition_point(|&it| it <= range.end());
123 let all = iter::once(range.start()) 122 let all = iter::once(range.start())
124 .chain(self.newlines[lo..hi].iter().copied()) 123 .chain(self.newlines[lo..hi].iter().copied())
125 .chain(iter::once(range.end())); 124 .chain(iter::once(range.end()));
diff --git a/crates/project_model/src/cfg_flag.rs b/crates/project_model/src/cfg_flag.rs
index e92962cf6..bfdfd458f 100644
--- a/crates/project_model/src/cfg_flag.rs
+++ b/crates/project_model/src/cfg_flag.rs
@@ -4,7 +4,6 @@
4use std::str::FromStr; 4use std::str::FromStr;
5 5
6use cfg::CfgOptions; 6use cfg::CfgOptions;
7use stdx::split_once;
8 7
9#[derive(Clone, Eq, PartialEq, Debug)] 8#[derive(Clone, Eq, PartialEq, Debug)]
10pub enum CfgFlag { 9pub enum CfgFlag {
@@ -15,7 +14,7 @@ pub enum CfgFlag {
15impl FromStr for CfgFlag { 14impl FromStr for CfgFlag {
16 type Err = String; 15 type Err = String;
17 fn from_str(s: &str) -> Result<Self, Self::Err> { 16 fn from_str(s: &str) -> Result<Self, Self::Err> {
18 let res = match split_once(s, '=') { 17 let res = match s.split_once('=') {
19 Some((key, value)) => { 18 Some((key, value)) => {
20 if !(value.starts_with('"') && value.ends_with('"')) { 19 if !(value.starts_with('"') && value.ends_with('"')) {
21 return Err(format!("Invalid cfg ({:?}), value should be in quotes", s)); 20 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 1b6211044..340fcacfa 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) {
65 *buf = buf.replace(from, to) 65 *buf = buf.replace(from, to)
66} 66}
67 67
68// https://github.com/rust-lang/rust/issues/74773
69pub fn split_once(haystack: &str, delim: char) -> Option<(&str, &str)> {
70 let mut split = haystack.splitn(2, delim);
71 let prefix = split.next()?;
72 let suffix = split.next()?;
73 Some((prefix, suffix))
74}
75pub fn rsplit_once(haystack: &str, delim: char) -> Option<(&str, &str)> {
76 let mut split = haystack.rsplitn(2, delim);
77 let suffix = split.next()?;
78 let prefix = split.next()?;
79 Some((prefix, suffix))
80}
81
82pub fn trim_indent(mut text: &str) -> String { 68pub fn trim_indent(mut text: &str) -> String {
83 if text.starts_with('\n') { 69 if text.starts_with('\n') {
84 text = &text[1..]; 70 text = &text[1..];
@@ -89,7 +75,7 @@ pub fn trim_indent(mut text: &str) -> String {
89 .map(|it| it.len() - it.trim_start().len()) 75 .map(|it| it.len() - it.trim_start().len())
90 .min() 76 .min()
91 .unwrap_or(0); 77 .unwrap_or(0);
92 lines_with_ends(text) 78 text.split_inclusive('\n')
93 .map( 79 .map(
94 |line| { 80 |line| {
95 if line.len() <= indent { 81 if line.len() <= indent {
@@ -102,70 +88,12 @@ pub fn trim_indent(mut text: &str) -> String {
102 .collect() 88 .collect()
103} 89}
104 90
105pub fn lines_with_ends(text: &str) -> LinesWithEnds {
106 LinesWithEnds { text }
107}
108
109pub struct LinesWithEnds<'a> {
110 text: &'a str,
111}
112
113impl<'a> Iterator for LinesWithEnds<'a> {
114 type Item = &'a str;
115 fn next(&mut self) -> Option<&'a str> {
116 if self.text.is_empty() {
117 return None;
118 }
119 let idx = self.text.find('\n').map_or(self.text.len(), |it| it + 1);
120 let (res, next) = self.text.split_at(idx);
121 self.text = next;
122 Some(res)
123 }
124}
125
126/// Returns `idx` such that:
127///
128/// ```text
129/// ∀ x in slice[..idx]: pred(x)
130/// && ∀ x in slice[idx..]: !pred(x)
131/// ```
132///
133/// https://github.com/rust-lang/rust/issues/73831
134pub fn partition_point<T, P>(slice: &[T], mut pred: P) -> usize
135where
136 P: FnMut(&T) -> bool,
137{
138 let mut left = 0;
139 let mut right = slice.len();
140
141 while left != right {
142 let mid = left + (right - left) / 2;
143 // SAFETY:
144 // When left < right, left <= mid < right.
145 // Therefore left always increases and right always decreases,
146 // and either of them is selected.
147 // In both cases left <= right is satisfied.
148 // Therefore if left < right in a step,
149 // left <= right is satisfied in the next step.
150 // Therefore as long as left != right, 0 <= left < right <= len is satisfied
151 // and if this case 0 <= mid < len is satisfied too.
152 let value = unsafe { slice.get_unchecked(mid) };
153 if pred(value) {
154 left = mid + 1;
155 } else {
156 right = mid;
157 }
158 }
159
160 left
161}
162
163pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize> 91pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize>
164where 92where
165 F: FnMut(&T) -> Ordering, 93 F: FnMut(&T) -> Ordering,
166{ 94{
167 let start = partition_point(slice, |it| key(it) == Ordering::Less); 95 let start = slice.partition_point(|it| key(it) == Ordering::Less);
168 let len = partition_point(&slice[start..], |it| key(it) == Ordering::Equal); 96 let len = slice[start..].partition_point(|it| key(it) == Ordering::Equal);
169 start..start + len 97 start..start + len
170} 98}
171 99
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index 099baeca2..d0bddf7d8 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -62,7 +62,7 @@
62//! ``` 62//! ```
63 63
64use rustc_hash::FxHashMap; 64use rustc_hash::FxHashMap;
65use stdx::{lines_with_ends, split_once, trim_indent}; 65use stdx::trim_indent;
66 66
67#[derive(Debug, Eq, PartialEq)] 67#[derive(Debug, Eq, PartialEq)]
68pub struct Fixture { 68pub struct Fixture {
@@ -93,7 +93,7 @@ impl Fixture {
93 93
94 let default = if ra_fixture.contains("//-") { None } else { Some("//- /main.rs") }; 94 let default = if ra_fixture.contains("//-") { None } else { Some("//- /main.rs") };
95 95
96 for (ix, line) in default.into_iter().chain(lines_with_ends(&fixture)).enumerate() { 96 for (ix, line) in default.into_iter().chain(fixture.split_inclusive('\n')).enumerate() {
97 if line.contains("//-") { 97 if line.contains("//-") {
98 assert!( 98 assert!(
99 line.starts_with("//-"), 99 line.starts_with("//-"),
@@ -133,14 +133,14 @@ impl Fixture {
133 let mut env = FxHashMap::default(); 133 let mut env = FxHashMap::default();
134 let mut introduce_new_source_root = false; 134 let mut introduce_new_source_root = false;
135 for component in components[1..].iter() { 135 for component in components[1..].iter() {
136 let (key, value) = split_once(component, ':').unwrap(); 136 let (key, value) = component.split_once(':').unwrap();
137 match key { 137 match key {
138 "crate" => krate = Some(value.to_string()), 138 "crate" => krate = Some(value.to_string()),
139 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), 139 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
140 "edition" => edition = Some(value.to_string()), 140 "edition" => edition = Some(value.to_string()),
141 "cfg" => { 141 "cfg" => {
142 for entry in value.split(',') { 142 for entry in value.split(',') {
143 match split_once(entry, '=') { 143 match entry.split_once('=') {
144 Some((k, v)) => cfg_key_values.push((k.to_string(), v.to_string())), 144 Some((k, v)) => cfg_key_values.push((k.to_string(), v.to_string())),
145 None => cfg_atoms.push(entry.to_string()), 145 None => cfg_atoms.push(entry.to_string()),
146 } 146 }
@@ -148,7 +148,7 @@ impl Fixture {
148 } 148 }
149 "env" => { 149 "env" => {
150 for key in value.split(',') { 150 for key in value.split(',') {
151 if let Some((k, v)) = split_once(key, '=') { 151 if let Some((k, v)) = key.split_once('=') {
152 env.insert(k.into(), v.into()); 152 env.insert(k.into(), v.into());
153 } 153 }
154 } 154 }
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 72466c957..fce4fd6bf 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -17,7 +17,7 @@ use std::{
17}; 17};
18 18
19use profile::StopWatch; 19use profile::StopWatch;
20use stdx::{is_ci, lines_with_ends}; 20use stdx::is_ci;
21use text_size::{TextRange, TextSize}; 21use text_size::{TextRange, TextSize};
22 22
23pub use dissimilar::diff as __diff; 23pub use dissimilar::diff as __diff;
@@ -181,7 +181,7 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
181 let mut prev_line_start: Option<TextSize> = None; 181 let mut prev_line_start: Option<TextSize> = None;
182 let mut line_start: TextSize = 0.into(); 182 let mut line_start: TextSize = 0.into();
183 let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new(); 183 let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new();
184 for line in lines_with_ends(text) { 184 for line in text.split_inclusive('\n') {
185 let mut this_line_annotations = Vec::new(); 185 let mut this_line_annotations = Vec::new();
186 if let Some(idx) = line.find("//") { 186 if let Some(idx) = line.find("//") {
187 let annotation_offset = TextSize::of(&line[..idx + "//".len()]); 187 let annotation_offset = TextSize::of(&line[..idx + "//".len()]);