From fc3ab03af74cb94a5ec94d84ec15650314f613eb Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Sun, 29 Dec 2019 17:38:37 +0100 Subject: Add helpers for unpacking lang items --- crates/ra_hir_def/src/lang_item.rs | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index cef061837..37c861a87 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -22,6 +22,50 @@ pub enum LangItemTarget { TraitId(TraitId), } +impl LangItemTarget { + pub fn as_enum(self) -> Option { + match self { + LangItemTarget::EnumId(id) => Some(id), + _ => None, + } + } + + pub fn as_function(self) -> Option { + match self { + LangItemTarget::FunctionId(id) => Some(id), + _ => None, + } + } + + pub fn as_impl_block(self) -> Option { + match self { + LangItemTarget::ImplBlockId(id) => Some(id), + _ => None, + } + } + + pub fn as_static(self) -> Option { + match self { + LangItemTarget::StaticId(id) => Some(id), + _ => None, + } + } + + pub fn as_struct(self) -> Option { + match self { + LangItemTarget::StructId(id) => Some(id), + _ => None, + } + } + + pub fn as_trait(self) -> Option { + match self { + LangItemTarget::TraitId(id) => Some(id), + _ => None, + } + } +} + #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct LangItems { items: FxHashMap, -- cgit v1.2.3 From 8fad8e897a8d3a5c2e55d3a00fb8465fb87f86bb Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Sun, 29 Dec 2019 17:39:31 +0100 Subject: Resolve traits in infer using lang item infrastructure --- crates/ra_hir_ty/src/infer.rs | 23 +++++++++++++---------- crates/ra_hir_ty/src/tests/simple.rs | 1 + crates/ra_hir_ty/src/tests/traits.rs | 5 +++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 32c0d07a5..37e69599d 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -24,6 +24,7 @@ use hir_def::{ body::Body, data::{ConstData, FunctionData}, expr::{BindingAnnotation, ExprId, PatId}, + lang_item::LangItemTarget, path::{path, Path}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{Mutability, TypeRef}, @@ -32,6 +33,7 @@ use hir_def::{ use hir_expand::{diagnostics::DiagnosticSink, name::name}; use ra_arena::map::ArenaMap; use ra_prof::profile; +use ra_syntax::SmolStr; use test_utils::tested_by; use super::{ @@ -482,6 +484,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); } + fn resolve_lang_item(&self, name: &str) -> Option { + let krate = self.resolver.krate()?; + let name = SmolStr::new_inline_from_ascii(name.len(), name.as_bytes()); + self.db.lang_item(krate, name) + } + fn resolve_into_iter_item(&self) -> Option { let path = path![std::iter::IntoIterator]; let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; @@ -495,26 +503,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } fn resolve_ops_neg_output(&self) -> Option { - let path = path![std::ops::Neg]; - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_ = self.resolve_lang_item("neg")?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_ops_not_output(&self) -> Option { - let path = path![std::ops::Not]; - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_ = self.resolve_lang_item("not")?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_future_future_output(&self) -> Option { - let path = path![std::future::Future]; - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_ = self.resolve_lang_item("future_trait")?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } fn resolve_boxed_box(&self) -> Option { - let path = path![std::boxed::Box]; - let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; + let struct_ = self.resolve_lang_item("owned_box")?.as_struct()?; Some(struct_.into()) } @@ -555,8 +559,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } fn resolve_ops_index_output(&self) -> Option { - let path = path![std::ops::Index]; - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_ = self.resolve_lang_item("index")?.as_trait()?; self.db.trait_data(trait_).associated_type_by_name(&name![Output]) } } diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 00134c99b..f7e042c12 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -20,6 +20,7 @@ fn test() { mod prelude {} mod boxed { + #[lang = "owned_box"] pub struct Box { inner: *mut T, } diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 0bc72644a..4b268510c 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -27,6 +27,7 @@ fn test() { //- /std.rs crate:std #[prelude_import] use future::*; mod future { + #[lang = "future_trait"] trait Future { type Output; } @@ -56,6 +57,7 @@ fn test() { //- /std.rs crate:std #[prelude_import] use future::*; mod future { + #[lang = "future_trait"] trait Future { type Output; } @@ -198,6 +200,7 @@ fn test() { #[prelude_import] use ops::*; mod ops { + #[lang = "neg"] pub trait Neg { type Output; } @@ -230,6 +233,7 @@ fn test() { #[prelude_import] use ops::*; mod ops { + #[lang = "not"] pub trait Not { type Output; } @@ -506,6 +510,7 @@ fn test() { #[prelude_import] use ops::*; mod ops { + #[lang = "index"] pub trait Index { type Output; } -- cgit v1.2.3 From 8280795a85a9a6d5ec43fea00a023e0b7dc9aaa8 Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Sun, 29 Dec 2019 17:39:44 +0100 Subject: Remove unused hard-coded paths --- crates/ra_hir_def/src/path.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 107d2d799..82cfa67a9 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -260,12 +260,8 @@ macro_rules! __known_path { (std::ops::RangeTo) => {}; (std::ops::RangeToInclusive) => {}; (std::ops::RangeInclusive) => {}; - (std::boxed::Box) => {}; (std::future::Future) => {}; (std::ops::Try) => {}; - (std::ops::Neg) => {}; - (std::ops::Not) => {}; - (std::ops::Index) => {}; ($path:path) => { compile_error!("Please register your known path in the path module") }; -- cgit v1.2.3