Skip to content

Commit

Permalink
Merge #6154
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bors[bot] and Veykril authored Oct 7, 2020
2 parents 5359e8f + 783af17 commit 83a651b
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 56 deletions.
110 changes: 96 additions & 14 deletions crates/assists/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub(crate) mod insert_use;

use std::{iter, ops};

use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
use hir::{Adt, Crate, Enum, Module, ScopeDef, Semantics, Trait, Type};
use ide_db::RootDatabase;
use itertools::Itertools;
use rustc_hash::FxHashSet;
Expand Down Expand Up @@ -274,15 +274,79 @@ impl TryEnum {
/// somewhat similar to the known paths infra inside hir, but it different; We
/// want to make sure that IDE specific paths don't become interesting inside
/// the compiler itself as well.
pub(crate) struct FamousDefs<'a, 'b>(pub(crate) &'a Semantics<'b, RootDatabase>, pub(crate) Crate);
pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Crate);

#[allow(non_snake_case)]
impl FamousDefs<'_, '_> {
#[cfg(test)]
pub(crate) const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
pub mod convert {
pub trait From<T> {
fn from(T) -> Self;
fn from(t: T) -> Self;
}
}
pub mod iter {
pub use self::traits::{collect::IntoIterator, iterator::Iterator};
mod traits {
pub(crate) mod iterator {
use crate::option::Option;
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
fn by_ref(&mut self) -> &mut Self {
self
}
fn take(self, n: usize) -> crate::iter::Take<Self> {
crate::iter::Take { inner: self }
}
}
impl<I: Iterator> Iterator for &mut I {
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
(**self).next()
}
}
}
pub(crate) mod collect {
pub trait IntoIterator {
type Item;
}
}
}
pub use self::sources::*;
pub(crate) mod sources {
use super::Iterator;
use crate::option::Option::{self, *};
pub struct Repeat<A> {
element: A,
}
pub fn repeat<T>(elt: T) -> Repeat<T> {
Repeat { element: elt }
}
impl<A> Iterator for Repeat<A> {
type Item = A;
fn next(&mut self) -> Option<A> {
None
}
}
}
pub use self::adapters::*;
pub(crate) mod adapters {
use super::Iterator;
use crate::option::Option::{self, *};
pub struct Take<I> { pub(crate) inner: I }
impl<I> Iterator for Take<I> where I: Iterator {
type Item = <I as Iterator>::Item;
fn next(&mut self) -> Option<<I as Iterator>::Item> {
None
}
}
}
}
Expand All @@ -291,7 +355,7 @@ pub mod option {
}
pub mod prelude {
pub use crate::{convert::From, option::Option::{self, *}};
pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}};
}
#[prelude_import]
pub use prelude::*;
Expand All @@ -305,6 +369,14 @@ pub use prelude::*;
self.find_enum("core:option:Option")
}

pub fn core_iter_Iterator(&self) -> Option<Trait> {
self.find_trait("core:iter:traits:iterator:Iterator")
}

pub fn core_iter(&self) -> Option<Module> {
self.find_module("core:iter")
}

fn find_trait(&self, path: &str) -> Option<Trait> {
match self.find_def(path)? {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
Expand All @@ -319,31 +391,41 @@ pub use prelude::*;
}
}

fn find_module(&self, path: &str) -> Option<Module> {
match self.find_def(path)? {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(it)) => Some(it),
_ => None,
}
}

fn find_def(&self, path: &str) -> Option<ScopeDef> {
let db = self.0.db;
let mut path = path.split(':');
let trait_ = path.next_back()?;
let std_crate = path.next()?;
let std_crate = self
let std_crate = if self
.1
.dependencies(db)
.into_iter()
.find(|dep| &dep.name.to_string() == std_crate)?
.krate;

.declaration_name(db)
.map(|name| name.to_string() == std_crate)
.unwrap_or(false)
{
self.1
} else {
self.1.dependencies(db).into_iter().find(|dep| dep.name.to_string() == std_crate)?.krate
};
let mut module = std_crate.root_module(db);
for segment in path {
module = module.children(db).find_map(|child| {
let name = child.name(db)?;
if &name.to_string() == segment {
if name.to_string() == segment {
Some(child)
} else {
None
}
})?;
}
let def =
module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
module.scope(db, None).into_iter().find(|(name, _def)| name.to_string() == trait_)?.1;
Some(def)
}
}
Expand Down
37 changes: 35 additions & 2 deletions crates/hir/src/code_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ use hir_expand::{
use hir_ty::{
autoderef,
display::{HirDisplayError, HirFormatter},
method_resolution, ApplicationTy, CallableDefId, Canonical, FnSig, GenericPredicate,
InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
method_resolution,
traits::Solution,
traits::SolutionVariables,
ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty,
TyDefId, TyKind, TypeCtor,
};
use rustc_hash::FxHashSet;
use stdx::impl_from;
Expand Down Expand Up @@ -1362,6 +1366,35 @@ impl Type {
db.trait_solve(self.krate, goal).is_some()
}

pub fn normalize_trait_assoc_type(
&self,
db: &dyn HirDatabase,
r#trait: Trait,
args: &[Type],
alias: TypeAlias,
) -> Option<Ty> {
let subst = Substs::build_for_def(db, r#trait.id)
.push(self.ty.value.clone())
.fill(args.iter().map(|t| t.ty.value.clone()))
.build();
let predicate = ProjectionPredicate {
projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)),
};
let goal = Canonical {
value: InEnvironment::new(
self.ty.environment.clone(),
Obligation::Projection(predicate),
),
kinds: Arc::new([TyKind::General]),
};

match db.trait_solve(self.krate, goal)? {
Solution::Unique(SolutionVariables(subst)) => subst.value.first().cloned(),
Solution::Ambig(_) => None,
}
}

pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
let lang_item = db.lang_item(self.krate, SmolStr::new("copy"));
let copy_trait = match lang_item {
Expand Down
2 changes: 1 addition & 1 deletion crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub use hir_def::{
type_ref::{Mutability, TypeRef},
};
pub use hir_expand::{
name::AsName, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
name::known, name::AsName, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
/* FIXME */ MacroDefId, MacroFile, Origin,
};
pub use hir_ty::display::HirDisplay;
Expand Down
1 change: 1 addition & 0 deletions crates/hir_expand/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ pub mod known {
result,
boxed,
// Components of known path (type name)
Iterator,
IntoIterator,
Item,
Try,
Expand Down
Loading

0 comments on commit 83a651b

Please sign in to comment.