Skip to content

Commit 83a651b

Browse files
bors[bot]Veykril
andauthored
Merge #6154
6154: Shorten type hints for std::iter Iterators r=SomeoneToIgnore a=Veykril Fixes #3750. This re-exports the `hir_expand::name::known` module to be able to fetch the `Iterator` and `iter` names. I'm not sure if there is anything to do with `Solution::Ambig` in `normalize_trait_assoc_type` or whether discarding those results is always wanted. Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 5359e8f + 783af17 commit 83a651b

File tree

5 files changed

+295
-56
lines changed

5 files changed

+295
-56
lines changed

crates/assists/src/utils.rs

Lines changed: 96 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub(crate) mod insert_use;
33

44
use std::{iter, ops};
55

6-
use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
6+
use hir::{Adt, Crate, Enum, Module, ScopeDef, Semantics, Trait, Type};
77
use ide_db::RootDatabase;
88
use itertools::Itertools;
99
use rustc_hash::FxHashSet;
@@ -274,15 +274,79 @@ impl TryEnum {
274274
/// somewhat similar to the known paths infra inside hir, but it different; We
275275
/// want to make sure that IDE specific paths don't become interesting inside
276276
/// 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);
278278

279279
#[allow(non_snake_case)]
280280
impl FamousDefs<'_, '_> {
281-
#[cfg(test)]
282-
pub(crate) const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
281+
pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
283282
pub mod convert {
284283
pub trait From<T> {
285-
fn from(T) -> Self;
284+
fn from(t: T) -> Self;
285+
}
286+
}
287+
288+
pub mod iter {
289+
pub use self::traits::{collect::IntoIterator, iterator::Iterator};
290+
mod traits {
291+
pub(crate) mod iterator {
292+
use crate::option::Option;
293+
pub trait Iterator {
294+
type Item;
295+
fn next(&mut self) -> Option<Self::Item>;
296+
fn by_ref(&mut self) -> &mut Self {
297+
self
298+
}
299+
fn take(self, n: usize) -> crate::iter::Take<Self> {
300+
crate::iter::Take { inner: self }
301+
}
302+
}
303+
304+
impl<I: Iterator> Iterator for &mut I {
305+
type Item = I::Item;
306+
fn next(&mut self) -> Option<I::Item> {
307+
(**self).next()
308+
}
309+
}
310+
}
311+
pub(crate) mod collect {
312+
pub trait IntoIterator {
313+
type Item;
314+
}
315+
}
316+
}
317+
318+
pub use self::sources::*;
319+
pub(crate) mod sources {
320+
use super::Iterator;
321+
use crate::option::Option::{self, *};
322+
pub struct Repeat<A> {
323+
element: A,
324+
}
325+
326+
pub fn repeat<T>(elt: T) -> Repeat<T> {
327+
Repeat { element: elt }
328+
}
329+
330+
impl<A> Iterator for Repeat<A> {
331+
type Item = A;
332+
333+
fn next(&mut self) -> Option<A> {
334+
None
335+
}
336+
}
337+
}
338+
339+
pub use self::adapters::*;
340+
pub(crate) mod adapters {
341+
use super::Iterator;
342+
use crate::option::Option::{self, *};
343+
pub struct Take<I> { pub(crate) inner: I }
344+
impl<I> Iterator for Take<I> where I: Iterator {
345+
type Item = <I as Iterator>::Item;
346+
fn next(&mut self) -> Option<<I as Iterator>::Item> {
347+
None
348+
}
349+
}
286350
}
287351
}
288352
@@ -291,7 +355,7 @@ pub mod option {
291355
}
292356
293357
pub mod prelude {
294-
pub use crate::{convert::From, option::Option::{self, *}};
358+
pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}};
295359
}
296360
#[prelude_import]
297361
pub use prelude::*;
@@ -305,6 +369,14 @@ pub use prelude::*;
305369
self.find_enum("core:option:Option")
306370
}
307371

372+
pub fn core_iter_Iterator(&self) -> Option<Trait> {
373+
self.find_trait("core:iter:traits:iterator:Iterator")
374+
}
375+
376+
pub fn core_iter(&self) -> Option<Module> {
377+
self.find_module("core:iter")
378+
}
379+
308380
fn find_trait(&self, path: &str) -> Option<Trait> {
309381
match self.find_def(path)? {
310382
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
@@ -319,31 +391,41 @@ pub use prelude::*;
319391
}
320392
}
321393

394+
fn find_module(&self, path: &str) -> Option<Module> {
395+
match self.find_def(path)? {
396+
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(it)) => Some(it),
397+
_ => None,
398+
}
399+
}
400+
322401
fn find_def(&self, path: &str) -> Option<ScopeDef> {
323402
let db = self.0.db;
324403
let mut path = path.split(':');
325404
let trait_ = path.next_back()?;
326405
let std_crate = path.next()?;
327-
let std_crate = self
406+
let std_crate = if self
328407
.1
329-
.dependencies(db)
330-
.into_iter()
331-
.find(|dep| &dep.name.to_string() == std_crate)?
332-
.krate;
333-
408+
.declaration_name(db)
409+
.map(|name| name.to_string() == std_crate)
410+
.unwrap_or(false)
411+
{
412+
self.1
413+
} else {
414+
self.1.dependencies(db).into_iter().find(|dep| dep.name.to_string() == std_crate)?.krate
415+
};
334416
let mut module = std_crate.root_module(db);
335417
for segment in path {
336418
module = module.children(db).find_map(|child| {
337419
let name = child.name(db)?;
338-
if &name.to_string() == segment {
420+
if name.to_string() == segment {
339421
Some(child)
340422
} else {
341423
None
342424
}
343425
})?;
344426
}
345427
let def =
346-
module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
428+
module.scope(db, None).into_iter().find(|(name, _def)| name.to_string() == trait_)?.1;
347429
Some(def)
348430
}
349431
}

crates/hir/src/code_model.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ use hir_expand::{
3030
use hir_ty::{
3131
autoderef,
3232
display::{HirDisplayError, HirFormatter},
33-
method_resolution, ApplicationTy, CallableDefId, Canonical, FnSig, GenericPredicate,
34-
InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
33+
method_resolution,
34+
traits::Solution,
35+
traits::SolutionVariables,
36+
ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
37+
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty,
38+
TyDefId, TyKind, TypeCtor,
3539
};
3640
use rustc_hash::FxHashSet;
3741
use stdx::impl_from;
@@ -1362,6 +1366,35 @@ impl Type {
13621366
db.trait_solve(self.krate, goal).is_some()
13631367
}
13641368

1369+
pub fn normalize_trait_assoc_type(
1370+
&self,
1371+
db: &dyn HirDatabase,
1372+
r#trait: Trait,
1373+
args: &[Type],
1374+
alias: TypeAlias,
1375+
) -> Option<Ty> {
1376+
let subst = Substs::build_for_def(db, r#trait.id)
1377+
.push(self.ty.value.clone())
1378+
.fill(args.iter().map(|t| t.ty.value.clone()))
1379+
.build();
1380+
let predicate = ProjectionPredicate {
1381+
projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
1382+
ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)),
1383+
};
1384+
let goal = Canonical {
1385+
value: InEnvironment::new(
1386+
self.ty.environment.clone(),
1387+
Obligation::Projection(predicate),
1388+
),
1389+
kinds: Arc::new([TyKind::General]),
1390+
};
1391+
1392+
match db.trait_solve(self.krate, goal)? {
1393+
Solution::Unique(SolutionVariables(subst)) => subst.value.first().cloned(),
1394+
Solution::Ambig(_) => None,
1395+
}
1396+
}
1397+
13651398
pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
13661399
let lang_item = db.lang_item(self.krate, SmolStr::new("copy"));
13671400
let copy_trait = match lang_item {

crates/hir/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub use hir_def::{
5555
type_ref::{Mutability, TypeRef},
5656
};
5757
pub use hir_expand::{
58-
name::AsName, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
58+
name::known, name::AsName, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
5959
/* FIXME */ MacroDefId, MacroFile, Origin,
6060
};
6161
pub use hir_ty::display::HirDisplay;

crates/hir_expand/src/name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ pub mod known {
164164
result,
165165
boxed,
166166
// Components of known path (type name)
167+
Iterator,
167168
IntoIterator,
168169
Item,
169170
Try,

0 commit comments

Comments
 (0)