diff options
Diffstat (limited to 'crates/assists/src')
-rw-r--r-- | crates/assists/src/utils.rs | 61 |
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. |
277 | pub(crate) struct FamousDefs<'a, 'b>(pub(crate) &'a Semantics<'b, RootDatabase>, pub(crate) Crate); | 277 | pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Crate); |
278 | 278 | ||
279 | #[allow(non_snake_case)] | 279 | #[allow(non_snake_case)] |
280 | impl FamousDefs<'_, '_> { | 280 | impl 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 | ||
283 | pub mod convert { | 282 | pub 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 | ||
288 | pub 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 | |||
289 | pub mod option { | 319 | pub mod option { |
290 | pub enum Option<T> { None, Some(T)} | 320 | pub enum Option<T> { None, Some(T)} |
291 | } | 321 | } |
292 | 322 | ||
293 | pub mod prelude { | 323 | pub 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] |
297 | pub use prelude::*; | 327 | pub 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 | } |