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(-) (limited to 'crates/ra_hir_ty') 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