diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2023-01-21 18:47:37 +0100 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2023-01-21 19:03:36 +0100 |
| commit | f8ed4d7ae44e7a730f597f1f6618fb3b4aead01b (patch) | |
| tree | 32f3397e5a9cfaa3d88af26f94a12d4764abe381 | |
| parent | 15358818363f66fc8b99e3711e6eb99a5e8684b9 (diff) | |
| download | rust-f8ed4d7ae44e7a730f597f1f6618fb3b4aead01b.tar.gz rust-f8ed4d7ae44e7a730f597f1f6618fb3b4aead01b.zip | |
Use lang item resolution instead of known paths
| -rw-r--r-- | crates/hir-def/src/lib.rs | 1 | ||||
| -rw-r--r-- | crates/hir-ty/src/diagnostics/expr.rs | 41 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 52 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/traits.rs | 138 | ||||
| -rw-r--r-- | crates/ide-completion/src/tests/flyimport.rs | 6 | ||||
| -rw-r--r-- | crates/test-utils/src/minicore.rs | 8 |
6 files changed, 66 insertions, 180 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 9e4e0dcc96c..8eae2e92f42 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -634,6 +634,7 @@ pub trait Lookup { pub trait HasModule { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId; } + impl HasModule for ItemContainerId { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match *self { diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index c8df4c796ef..3286dcb5afd 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -5,7 +5,9 @@ use std::fmt; use std::sync::Arc; -use hir_def::{path::path, resolver::HasResolver, AdtId, AssocItemId, DefWithBodyId, HasModule}; +use hir_def::lang_item::LangItem; +use hir_def::{resolver::HasResolver, AdtId, AssocItemId, DefWithBodyId, HasModule}; +use hir_def::{ItemContainerId, Lookup}; use hir_expand::name; use itertools::Either; use itertools::Itertools; @@ -245,26 +247,25 @@ struct FilterMapNextChecker { impl FilterMapNextChecker { fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self { // Find and store the FunctionIds for Iterator::filter_map and Iterator::next - let iterator_path = path![core::iter::Iterator]; - let mut filter_map_function_id = None; - let mut next_function_id = None; - - if let Some(iterator_trait_id) = resolver.resolve_known_trait(db.upcast(), &iterator_path) { - let iterator_trait_items = &db.trait_data(iterator_trait_id).items; - for item in iterator_trait_items.iter() { - if let (name, AssocItemId::FunctionId(id)) = item { - if *name == name![filter_map] { - filter_map_function_id = Some(*id); + let (next_function_id, filter_map_function_id) = match db + .lang_item(resolver.krate(), LangItem::IteratorNext) + .and_then(|it| it.as_function()) + { + Some(next_function_id) => ( + Some(next_function_id), + match next_function_id.lookup(db.upcast()).container { + ItemContainerId::TraitId(iterator_trait_id) => { + let iterator_trait_items = &db.trait_data(iterator_trait_id).items; + iterator_trait_items.iter().find_map(|(name, it)| match it { + &AssocItemId::FunctionId(id) if *name == name![filter_map] => Some(id), + _ => None, + }) } - if *name == name![next] { - next_function_id = Some(*id); - } - } - if filter_map_function_id.is_some() && next_function_id.is_some() { - break; - } - } - } + _ => None, + }, + ), + None => (None, None), + }; Self { filter_map_function_id, next_function_id, prev_filter_map_expr_id: None } } diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index d06b22fff9a..4402c75947c 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -24,7 +24,7 @@ use hir_def::{ expr::{BindingAnnotation, ExprId, ExprOrPatId, PatId}, lang_item::{LangItem, LangItemTarget}, layout::Integer, - path::{path, Path}, + path::Path, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, type_ref::TypeRef, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, @@ -923,26 +923,24 @@ impl<'a> InferenceContext<'a> { } fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { - let path = path![core::iter::IntoIterator]; - let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; + let ItemContainerId::TraitId(trait_) = self.resolve_lang_item(LangItem::IntoIterIntoIter)? + .as_function()? + .lookup(self.db.upcast()).container + else { return None }; self.db.trait_data(trait_).associated_type_by_name(&name![IntoIter]) } fn resolve_iterator_item(&self) -> Option<TypeAliasId> { - let path = path![core::iter::Iterator]; - let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; + let ItemContainerId::TraitId(trait_) = self.resolve_lang_item(LangItem::IteratorNext)? + .as_function()? + .lookup(self.db.upcast()).container + else { return None }; self.db.trait_data(trait_).associated_type_by_name(&name![Item]) } fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { - // FIXME resolve via lang_item once try v2 is stable - let path = path![core::ops::Try]; - let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; - let trait_data = self.db.trait_data(trait_); - trait_data - // FIXME remove once try v2 is stable - .associated_type_by_name(&name![Ok]) - .or_else(|| trait_data.associated_type_by_name(&name![Output])) + let trait_ = self.resolve_lang_item(LangItem::Try)?.as_trait()?; + self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> { @@ -956,10 +954,12 @@ impl<'a> InferenceContext<'a> { } fn resolve_future_future_output(&self) -> Option<TypeAliasId> { - let trait_ = self - .resolver - .resolve_known_trait(self.db.upcast(), &path![core::future::IntoFuture]) - .or_else(|| self.resolve_lang_item(LangItem::Future)?.as_trait())?; + let ItemContainerId::TraitId(trait_) = self + .resolve_lang_item(LangItem::IntoFutureIntoFuture)? + .as_function()? + .lookup(self.db.upcast()) + .container + else { return None }; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } @@ -969,38 +969,32 @@ impl<'a> InferenceContext<'a> { } fn resolve_range_full(&self) -> Option<AdtId> { - let path = path![core::ops::RangeFull]; - let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; + let struct_ = self.resolve_lang_item(LangItem::RangeFull)?.as_struct()?; Some(struct_.into()) } fn resolve_range(&self) -> Option<AdtId> { - let path = path![core::ops::Range]; - let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; + let struct_ = self.resolve_lang_item(LangItem::Range)?.as_struct()?; Some(struct_.into()) } fn resolve_range_inclusive(&self) -> Option<AdtId> { - let path = path![core::ops::RangeInclusive]; - let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; + let struct_ = self.resolve_lang_item(LangItem::RangeInclusiveStruct)?.as_struct()?; Some(struct_.into()) } fn resolve_range_from(&self) -> Option<AdtId> { - let path = path![core::ops::RangeFrom]; - let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; + let struct_ = self.resolve_lang_item(LangItem::RangeFrom)?.as_struct()?; Some(struct_.into()) } fn resolve_range_to(&self) -> Option<AdtId> { - let path = path![core::ops::RangeTo]; - let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; + let struct_ = self.resolve_lang_item(LangItem::RangeTo)?.as_struct()?; Some(struct_.into()) } fn resolve_range_to_inclusive(&self) -> Option<AdtId> { - let path = path![core::ops::RangeToInclusive]; - let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; + let struct_ = self.resolve_lang_item(LangItem::RangeToInclusive)?.as_struct()?; Some(struct_.into()) } diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index 4c560702a1b..88670364bde 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -163,98 +163,22 @@ fn test() { } #[test] -fn infer_try() { +fn infer_try_trait() { check_types( r#" -//- /main.rs crate:main deps:core +//- minicore: try, result fn test() { let r: Result<i32, u64> = Result::Ok(1); let v = r?; v; } //^ i32 -//- /core.rs crate:core -pub mod ops { - pub trait Try { - type Ok; - type Error; - } +impl<O, E> core::ops::Try for Result<O, E> { + type Output = O; + type Error = Result<core::convert::Infallible, E>; } -pub mod result { - pub enum Result<O, E> { - Ok(O), - Err(E) - } - - impl<O, E> crate::ops::Try for Result<O, E> { - type Ok = O; - type Error = E; - } -} - -pub mod prelude { - pub mod rust_2018 { - pub use crate::{result::*, ops::*}; - } -} -"#, - ); -} - -#[test] -fn infer_try_trait_v2() { - check_types( - r#" -//- /main.rs crate:main deps:core -fn test() { - let r: Result<i32, u64> = Result::Ok(1); - let v = r?; - v; -} //^ i32 - -//- /core.rs crate:core -mod ops { - mod try_trait { - pub trait Try: FromResidual { - type Output; - type Residual; - } - pub trait FromResidual<R = <Self as Try>::Residual> {} - } - - pub use self::try_trait::FromResidual; - pub use self::try_trait::Try; -} - -mod convert { - pub trait From<T> {} - impl<T> From<T> for T {} -} - -pub mod result { - use crate::convert::From; - use crate::ops::{Try, FromResidual}; - - pub enum Infallible {} - pub enum Result<O, E> { - Ok(O), - Err(E) - } - - impl<O, E> Try for Result<O, E> { - type Output = O; - type Error = Result<Infallible, E>; - } - - impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {} -} - -pub mod prelude { - pub mod rust_2018 { - pub use crate::result::*; - } -} +impl<T, E, F: From<E>> core::ops::FromResidual<Result<core::convert::Infallible, E>> for Result<T, F> {} "#, ); } @@ -263,7 +187,8 @@ pub mod prelude { fn infer_for_loop() { check_types( r#" -//- /main.rs crate:main deps:core,alloc +//- minicore: iterator +//- /main.rs crate:main deps:alloc #![no_std] use alloc::collections::Vec; @@ -275,23 +200,7 @@ fn test() { } //^ &str } -//- /core.rs crate:core -pub mod iter { - pub trait IntoIterator { - type Item; - type IntoIter: Iterator<Item = Self::Item>; - } - pub trait Iterator { - type Item; - } -} -pub mod prelude { - pub mod rust_2018 { - pub use crate::iter::*; - } -} - -//- /alloc.rs crate:alloc deps:core +//- /alloc.rs crate:alloc #![no_std] pub mod collections { pub struct Vec<T> {} @@ -2999,40 +2908,17 @@ fn test() { fn integer_range_iterate() { check_types( r#" -//- /main.rs crate:main deps:core +//- minicore: range, iterator +//- /main.rs crate:main fn test() { for x in 0..100 { x; } } //^ i32 -//- /core.rs crate:core -pub mod ops { - pub struct Range<Idx> { - pub start: Idx, - pub end: Idx, - } -} - -pub mod iter { - pub trait Iterator { - type Item; - } - - pub trait IntoIterator { - type Item; - type IntoIter: Iterator<Item = Self::Item>; - } - - impl<T> IntoIterator for T where T: Iterator { - type Item = <T as Iterator>::Item; - type IntoIter = Self; - } -} - trait Step {} impl Step for i32 {} impl Step for i64 {} -impl<A: Step> iter::Iterator for ops::Range<A> { +impl<A: Step> core::iter::Iterator for core::ops::Range<A> { type Item = A; } "#, diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs index a63ef006875..0b485eb776d 100644 --- a/crates/ide-completion/src/tests/flyimport.rs +++ b/crates/ide-completion/src/tests/flyimport.rs @@ -541,9 +541,9 @@ fn main() { } "#, expect![[r#" - fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED - ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED - "#]], + ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED + fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED + "#]], ); } diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs index 3ca63fcab90..dff60914409 100644 --- a/crates/test-utils/src/minicore.rs +++ b/crates/test-utils/src/minicore.rs @@ -28,6 +28,7 @@ //! generator: pin //! hash: //! index: sized +//! infallible: //! iterator: option //! iterators: iterator, fn //! non_zero: @@ -40,7 +41,7 @@ //! sized: //! slice: //! sync: sized -//! try: +//! try: infallible //! unsize: sized pub mod marker { @@ -172,6 +173,9 @@ pub mod convert { fn as_ref(&self) -> &T; } // endregion:as_ref + // region:infallible + pub enum Infallibe {} + // endregion:infallible } pub mod ops { @@ -352,7 +356,7 @@ pub mod ops { #[lang = "from_residual"] fn from_residual(residual: R) -> Self; } - #[lang = "try"] + #[lang = "Try"] pub trait Try: FromResidual<Self::Residual> { type Output; type Residual; |
