aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src')
-rw-r--r--crates/assists/src/utils.rs61
1 files changed, 49 insertions, 12 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index eb69c49a4..0335969fd 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -274,24 +274,54 @@ impl TryEnum {
274/// somewhat similar to the known paths infra inside hir, but it different; We 274/// somewhat similar to the known paths infra inside hir, but it different; We
275/// want to make sure that IDE specific paths don't become interesting inside 275/// want to make sure that IDE specific paths don't become interesting inside
276/// the compiler itself as well. 276/// the compiler itself as well.
277pub(crate) struct FamousDefs<'a, 'b>(pub(crate) &'a Semantics<'b, RootDatabase>, pub(crate) Crate); 277pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Crate);
278 278
279#[allow(non_snake_case)] 279#[allow(non_snake_case)]
280impl FamousDefs<'_, '_> { 280impl FamousDefs<'_, '_> {
281 #[cfg(test)] 281 pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
282 pub(crate) const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
283pub mod convert { 282pub mod convert {
284 pub trait From<T> { 283 pub trait From<T> {
285 fn from(T) -> Self; 284 fn from(T) -> Self;
286 } 285 }
287} 286}
288 287
288pub mod iter {
289 pub use self::traits::iterator::Iterator;
290 mod traits { mod iterator {
291 use crate::option::Option;
292 pub trait Iterator {
293 type Item;
294 fn next(&mut self) -> Option<Self::Item>;
295 }
296 } }
297
298 pub use self::sources::*;
299 mod sources {
300 use super::Iterator;
301 pub struct Repeat<A> {
302 element: A,
303 }
304
305 pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
306 Repeat { element: elt }
307 }
308
309 impl<A: Clone> Iterator for Repeat<A> {
310 type Item = A;
311
312 fn next(&mut self) -> Option<A> {
313 Some(self.element.clone())
314 }
315 }
316 }
317}
318
289pub mod option { 319pub mod option {
290 pub enum Option<T> { None, Some(T)} 320 pub enum Option<T> { None, Some(T)}
291} 321}
292 322
293pub mod prelude { 323pub mod prelude {
294 pub use crate::{convert::From, option::Option::{self, *}}; 324 pub use crate::{convert::From, iter::Iterator, option::Option::{self, *}};
295} 325}
296#[prelude_import] 326#[prelude_import]
297pub use prelude::*; 327pub use prelude::*;
@@ -305,6 +335,10 @@ pub use prelude::*;
305 self.find_enum("core:option:Option") 335 self.find_enum("core:option:Option")
306 } 336 }
307 337
338 pub fn core_iter_Iterator(&self) -> Option<Trait> {
339 self.find_trait("core:iter:traits:iterator:Iterator")
340 }
341
308 fn find_trait(&self, path: &str) -> Option<Trait> { 342 fn find_trait(&self, path: &str) -> Option<Trait> {
309 match self.find_def(path)? { 343 match self.find_def(path)? {
310 hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), 344 hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
@@ -324,18 +358,21 @@ pub use prelude::*;
324 let mut path = path.split(':'); 358 let mut path = path.split(':');
325 let trait_ = path.next_back()?; 359 let trait_ = path.next_back()?;
326 let std_crate = path.next()?; 360 let std_crate = path.next()?;
327 let std_crate = self 361 let std_crate = if self
328 .1 362 .1
329 .dependencies(db) 363 .declaration_name(db)
330 .into_iter() 364 .map(|name| name.to_string() == std_crate)
331 .find(|dep| &dep.name.to_string() == std_crate)? 365 .unwrap_or(false)
332 .krate; 366 {
333 367 self.1
368 } else {
369 self.1.dependencies(db).into_iter().find(|dep| dep.name.to_string() == std_crate)?.krate
370 };
334 let mut module = std_crate.root_module(db); 371 let mut module = std_crate.root_module(db);
335 for segment in path { 372 for segment in path {
336 module = module.children(db).find_map(|child| { 373 module = module.children(db).find_map(|child| {
337 let name = child.name(db)?; 374 let name = child.name(db)?;
338 if &name.to_string() == segment { 375 if name.to_string() == segment {
339 Some(child) 376 Some(child)
340 } else { 377 } else {
341 None 378 None
@@ -343,7 +380,7 @@ pub use prelude::*;
343 })?; 380 })?;
344 } 381 }
345 let def = 382 let def =
346 module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1; 383 module.scope(db, None).into_iter().find(|(name, _def)| name.to_string() == trait_)?.1;
347 Some(def) 384 Some(def)
348 } 385 }
349} 386}