diff options
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/db.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 39 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 49 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 110 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 15 |
11 files changed, 237 insertions, 73 deletions
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index 9ce154593..222a36a9f 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs | |||
@@ -11,7 +11,7 @@ use ra_db::{salsa, CrateId}; | |||
11 | use crate::{ | 11 | use crate::{ |
12 | method_resolution::CrateImplBlocks, | 12 | method_resolution::CrateImplBlocks, |
13 | traits::{AssocTyValue, Impl}, | 13 | traits::{AssocTyValue, Impl}, |
14 | CallableDef, FnSig, GenericPredicate, ImplTy, InferenceResult, Substs, Ty, TyDefId, TypeCtor, | 14 | CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor, |
15 | ValueTyDefId, | 15 | ValueTyDefId, |
16 | }; | 16 | }; |
17 | 17 | ||
@@ -22,13 +22,18 @@ pub trait HirDatabase: DefDatabase { | |||
22 | fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>; | 22 | fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>; |
23 | 23 | ||
24 | #[salsa::invoke(crate::lower::ty_query)] | 24 | #[salsa::invoke(crate::lower::ty_query)] |
25 | #[salsa::cycle(crate::lower::ty_recover)] | ||
25 | fn ty(&self, def: TyDefId) -> Ty; | 26 | fn ty(&self, def: TyDefId) -> Ty; |
26 | 27 | ||
27 | #[salsa::invoke(crate::lower::value_ty_query)] | 28 | #[salsa::invoke(crate::lower::value_ty_query)] |
28 | fn value_ty(&self, def: ValueTyDefId) -> Ty; | 29 | fn value_ty(&self, def: ValueTyDefId) -> Ty; |
29 | 30 | ||
30 | #[salsa::invoke(crate::lower::impl_ty_query)] | 31 | #[salsa::invoke(crate::lower::impl_self_ty_query)] |
31 | fn impl_ty(&self, def: ImplId) -> ImplTy; | 32 | #[salsa::cycle(crate::lower::impl_self_ty_recover)] |
33 | fn impl_self_ty(&self, def: ImplId) -> Ty; | ||
34 | |||
35 | #[salsa::invoke(crate::lower::impl_trait_query)] | ||
36 | fn impl_trait(&self, def: ImplId) -> Option<TraitRef>; | ||
32 | 37 | ||
33 | #[salsa::invoke(crate::lower::field_types_query)] | 38 | #[salsa::invoke(crate::lower::field_types_query)] |
34 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; | 39 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; |
@@ -37,6 +42,7 @@ pub trait HirDatabase: DefDatabase { | |||
37 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | 42 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; |
38 | 43 | ||
39 | #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] | 44 | #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] |
45 | #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] | ||
40 | fn generic_predicates_for_param( | 46 | fn generic_predicates_for_param( |
41 | &self, | 47 | &self, |
42 | def: GenericDefId, | 48 | def: GenericDefId, |
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index 4a13fac23..5054189cc 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::any::Any; | 3 | use std::any::Any; |
4 | 4 | ||
5 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, Source}; | 5 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; |
6 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; | 6 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; |
7 | 7 | ||
8 | pub use hir_def::diagnostics::UnresolvedModule; | 8 | pub use hir_def::diagnostics::UnresolvedModule; |
@@ -19,8 +19,8 @@ impl Diagnostic for NoSuchField { | |||
19 | "no such field".to_string() | 19 | "no such field".to_string() |
20 | } | 20 | } |
21 | 21 | ||
22 | fn source(&self) -> Source<SyntaxNodePtr> { | 22 | fn source(&self) -> InFile<SyntaxNodePtr> { |
23 | Source { file_id: self.file, value: self.field.into() } | 23 | InFile { file_id: self.file, value: self.field.into() } |
24 | } | 24 | } |
25 | 25 | ||
26 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 26 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
@@ -44,8 +44,8 @@ impl Diagnostic for MissingFields { | |||
44 | } | 44 | } |
45 | message | 45 | message |
46 | } | 46 | } |
47 | fn source(&self) -> Source<SyntaxNodePtr> { | 47 | fn source(&self) -> InFile<SyntaxNodePtr> { |
48 | Source { file_id: self.file, value: self.field_list.into() } | 48 | InFile { file_id: self.file, value: self.field_list.into() } |
49 | } | 49 | } |
50 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 50 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
51 | self | 51 | self |
@@ -72,8 +72,8 @@ impl Diagnostic for MissingOkInTailExpr { | |||
72 | fn message(&self) -> String { | 72 | fn message(&self) -> String { |
73 | "wrap return expression in Ok".to_string() | 73 | "wrap return expression in Ok".to_string() |
74 | } | 74 | } |
75 | fn source(&self) -> Source<SyntaxNodePtr> { | 75 | fn source(&self) -> InFile<SyntaxNodePtr> { |
76 | Source { file_id: self.file, value: self.expr.into() } | 76 | InFile { file_id: self.file, value: self.expr.into() } |
77 | } | 77 | } |
78 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 78 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
79 | self | 79 | self |
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 1e9f4b208..fe259371f 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -577,6 +577,42 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
577 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | 577 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; |
578 | Some(struct_.into()) | 578 | Some(struct_.into()) |
579 | } | 579 | } |
580 | |||
581 | fn resolve_range_full(&self) -> Option<AdtId> { | ||
582 | let path = known::std_ops_range_full(); | ||
583 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
584 | Some(struct_.into()) | ||
585 | } | ||
586 | |||
587 | fn resolve_range(&self) -> Option<AdtId> { | ||
588 | let path = known::std_ops_range(); | ||
589 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
590 | Some(struct_.into()) | ||
591 | } | ||
592 | |||
593 | fn resolve_range_inclusive(&self) -> Option<AdtId> { | ||
594 | let path = known::std_ops_range_inclusive(); | ||
595 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
596 | Some(struct_.into()) | ||
597 | } | ||
598 | |||
599 | fn resolve_range_from(&self) -> Option<AdtId> { | ||
600 | let path = known::std_ops_range_from(); | ||
601 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
602 | Some(struct_.into()) | ||
603 | } | ||
604 | |||
605 | fn resolve_range_to(&self) -> Option<AdtId> { | ||
606 | let path = known::std_ops_range_to(); | ||
607 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
608 | Some(struct_.into()) | ||
609 | } | ||
610 | |||
611 | fn resolve_range_to_inclusive(&self) -> Option<AdtId> { | ||
612 | let path = known::std_ops_range_to_inclusive(); | ||
613 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
614 | Some(struct_.into()) | ||
615 | } | ||
580 | } | 616 | } |
581 | 617 | ||
582 | /// The ID of a type variable. | 618 | /// The ID of a type variable. |
@@ -693,7 +729,7 @@ impl Expectation { | |||
693 | } | 729 | } |
694 | 730 | ||
695 | mod diagnostics { | 731 | mod diagnostics { |
696 | use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup}; | 732 | use hir_def::{expr::ExprId, src::HasSource, FunctionId, Lookup}; |
697 | use hir_expand::diagnostics::DiagnosticSink; | 733 | use hir_expand::diagnostics::DiagnosticSink; |
698 | 734 | ||
699 | use crate::{db::HirDatabase, diagnostics::NoSuchField}; | 735 | use crate::{db::HirDatabase, diagnostics::NoSuchField}; |
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 719a0f395..064993d34 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -8,7 +8,7 @@ use hir_def::{lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutabilit | |||
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
10 | 10 | ||
11 | use crate::{autoderef, db::HirDatabase, ImplTy, Substs, Ty, TypeCtor, TypeWalk}; | 11 | use crate::{autoderef, db::HirDatabase, Substs, Ty, TypeCtor, TypeWalk}; |
12 | 12 | ||
13 | use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; | 13 | use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; |
14 | 14 | ||
@@ -54,10 +54,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
54 | impls | 54 | impls |
55 | .iter() | 55 | .iter() |
56 | .filter_map(|&impl_id| { | 56 | .filter_map(|&impl_id| { |
57 | let trait_ref = match db.impl_ty(impl_id) { | 57 | let trait_ref = db.impl_trait(impl_id)?; |
58 | ImplTy::TraitRef(it) => it, | ||
59 | ImplTy::Inherent(_) => return None, | ||
60 | }; | ||
61 | 58 | ||
62 | // `CoerseUnsized` has one generic parameter for the target type. | 59 | // `CoerseUnsized` has one generic parameter for the target type. |
63 | let cur_from_ty = trait_ref.substs.0.get(0)?; | 60 | let cur_from_ty = trait_ref.substs.0.get(0)?; |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 2f9ca4bbb..4014f4732 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -12,6 +12,7 @@ use hir_def::{ | |||
12 | AdtId, ContainerId, Lookup, StructFieldId, | 12 | AdtId, ContainerId, Lookup, StructFieldId, |
13 | }; | 13 | }; |
14 | use hir_expand::name::{self, Name}; | 14 | use hir_expand::name::{self, Name}; |
15 | use ra_syntax::ast::RangeOp; | ||
15 | 16 | ||
16 | use crate::{ | 17 | use crate::{ |
17 | autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data, | 18 | autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data, |
@@ -415,6 +416,44 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
415 | } | 416 | } |
416 | _ => Ty::Unknown, | 417 | _ => Ty::Unknown, |
417 | }, | 418 | }, |
419 | Expr::Range { lhs, rhs, range_type } => { | ||
420 | let lhs_ty = lhs.map(|e| self.infer_expr(e, &Expectation::none())); | ||
421 | let rhs_expect = lhs_ty | ||
422 | .as_ref() | ||
423 | .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone())); | ||
424 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | ||
425 | match (range_type, lhs_ty, rhs_ty) { | ||
426 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | ||
427 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | ||
428 | None => Ty::Unknown, | ||
429 | }, | ||
430 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | ||
431 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
432 | None => Ty::Unknown, | ||
433 | }, | ||
434 | (RangeOp::Inclusive, None, Some(ty)) => { | ||
435 | match self.resolve_range_to_inclusive() { | ||
436 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
437 | None => Ty::Unknown, | ||
438 | } | ||
439 | } | ||
440 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | ||
441 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
442 | None => Ty::Unknown, | ||
443 | }, | ||
444 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | ||
445 | match self.resolve_range_inclusive() { | ||
446 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
447 | None => Ty::Unknown, | ||
448 | } | ||
449 | } | ||
450 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | ||
451 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
452 | None => Ty::Unknown, | ||
453 | }, | ||
454 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | ||
455 | } | ||
456 | } | ||
418 | Expr::Index { base, index } => { | 457 | Expr::Index { base, index } => { |
419 | let _base_ty = self.infer_expr(*base, &Expectation::none()); | 458 | let _base_ty = self.infer_expr(*base, &Expectation::none()); |
420 | let _index_ty = self.infer_expr(*index, &Expectation::none()); | 459 | let _index_ty = self.infer_expr(*index, &Expectation::none()); |
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs index 14be66836..bbf146418 100644 --- a/crates/ra_hir_ty/src/infer/path.rs +++ b/crates/ra_hir_ty/src/infer/path.rs | |||
@@ -244,7 +244,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
244 | ContainerId::ImplId(it) => it, | 244 | ContainerId::ImplId(it) => it, |
245 | _ => return None, | 245 | _ => return None, |
246 | }; | 246 | }; |
247 | let self_ty = self.db.impl_ty(impl_id).self_type().clone(); | 247 | let self_ty = self.db.impl_self_ty(impl_id).clone(); |
248 | let self_ty_substs = self_ty.substs()?; | 248 | let self_ty_substs = self_ty.substs()?; |
249 | let actual_substs = actual_def_ty.substs()?; | 249 | let actual_substs = actual_def_ty.substs()?; |
250 | 250 | ||
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index b45c8f82f..3c1f738df 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -486,21 +486,6 @@ impl TypeWalk for TraitRef { | |||
486 | } | 486 | } |
487 | } | 487 | } |
488 | 488 | ||
489 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
490 | pub enum ImplTy { | ||
491 | Inherent(Ty), | ||
492 | TraitRef(TraitRef), | ||
493 | } | ||
494 | |||
495 | impl ImplTy { | ||
496 | pub(crate) fn self_type(&self) -> &Ty { | ||
497 | match self { | ||
498 | ImplTy::Inherent(it) => it, | ||
499 | ImplTy::TraitRef(tr) => &tr.substs[0], | ||
500 | } | ||
501 | } | ||
502 | } | ||
503 | |||
504 | /// Like `generics::WherePredicate`, but with resolved types: A condition on the | 489 | /// Like `generics::WherePredicate`, but with resolved types: A condition on the |
505 | /// parameters of a generic item. | 490 | /// parameters of a generic item. |
506 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 491 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 091c60f4f..32569ac66 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -27,8 +27,8 @@ use crate::{ | |||
27 | all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, | 27 | all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, |
28 | variant_data, | 28 | variant_data, |
29 | }, | 29 | }, |
30 | FnSig, GenericPredicate, ImplTy, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, | 30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
31 | TraitRef, Ty, TypeCtor, TypeWalk, | 31 | Ty, TypeCtor, TypeWalk, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | impl Ty { | 34 | impl Ty { |
@@ -179,7 +179,7 @@ impl Ty { | |||
179 | let name = resolved_segment.name.clone(); | 179 | let name = resolved_segment.name.clone(); |
180 | Ty::Param { idx, name } | 180 | Ty::Param { idx, name } |
181 | } | 181 | } |
182 | TypeNs::SelfType(impl_id) => db.impl_ty(impl_id).self_type().clone(), | 182 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), |
183 | TypeNs::AdtSelfType(adt) => db.ty(adt.into()), | 183 | TypeNs::AdtSelfType(adt) => db.ty(adt.into()), |
184 | 184 | ||
185 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), | 185 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), |
@@ -532,6 +532,15 @@ pub(crate) fn generic_predicates_for_param_query( | |||
532 | .collect() | 532 | .collect() |
533 | } | 533 | } |
534 | 534 | ||
535 | pub(crate) fn generic_predicates_for_param_recover( | ||
536 | _db: &impl HirDatabase, | ||
537 | _cycle: &[String], | ||
538 | _def: &GenericDefId, | ||
539 | _param_idx: &u32, | ||
540 | ) -> Arc<[GenericPredicate]> { | ||
541 | Arc::new([]) | ||
542 | } | ||
543 | |||
535 | impl TraitEnvironment { | 544 | impl TraitEnvironment { |
536 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { | 545 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { |
537 | let predicates = resolver | 546 | let predicates = resolver |
@@ -733,6 +742,11 @@ pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { | |||
733 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), | 742 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), |
734 | } | 743 | } |
735 | } | 744 | } |
745 | |||
746 | pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty { | ||
747 | Ty::Unknown | ||
748 | } | ||
749 | |||
736 | pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | 750 | pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { |
737 | match def { | 751 | match def { |
738 | ValueTyDefId::FunctionId(it) => type_for_fn(db, it), | 752 | ValueTyDefId::FunctionId(it) => type_for_fn(db, it), |
@@ -743,17 +757,24 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | |||
743 | } | 757 | } |
744 | } | 758 | } |
745 | 759 | ||
746 | pub(crate) fn impl_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> ImplTy { | 760 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { |
747 | let impl_data = db.impl_data(impl_id); | 761 | let impl_data = db.impl_data(impl_id); |
748 | let resolver = impl_id.resolver(db); | 762 | let resolver = impl_id.resolver(db); |
749 | let self_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | 763 | Ty::from_hir(db, &resolver, &impl_data.target_type) |
750 | match impl_data.target_trait.as_ref() { | 764 | } |
751 | Some(trait_ref) => { | 765 | |
752 | match TraitRef::from_hir(db, &resolver, trait_ref, Some(self_ty.clone())) { | 766 | pub(crate) fn impl_self_ty_recover( |
753 | Some(it) => ImplTy::TraitRef(it), | 767 | _db: &impl HirDatabase, |
754 | None => ImplTy::Inherent(self_ty), | 768 | _cycle: &[String], |
755 | } | 769 | _impl_id: &ImplId, |
756 | } | 770 | ) -> Ty { |
757 | None => ImplTy::Inherent(self_ty), | 771 | Ty::Unknown |
758 | } | 772 | } |
773 | |||
774 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { | ||
775 | let impl_data = db.impl_data(impl_id); | ||
776 | let resolver = impl_id.resolver(db); | ||
777 | let self_ty = db.impl_self_ty(impl_id); | ||
778 | let target_trait = impl_data.target_trait.as_ref()?; | ||
779 | TraitRef::from_hir(db, &resolver, target_trait, Some(self_ty.clone())) | ||
759 | } | 780 | } |
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index ee1936b0e..2bded3dbd 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | db::HirDatabase, | 19 | db::HirDatabase, |
20 | primitive::{FloatBitness, Uncertain}, | 20 | primitive::{FloatBitness, Uncertain}, |
21 | utils::all_super_traits, | 21 | utils::all_super_traits, |
22 | Canonical, ImplTy, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, | 22 | Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | /// This is used as a key for indexing impls. | 25 | /// This is used as a key for indexing impls. |
@@ -58,11 +58,12 @@ impl CrateImplBlocks { | |||
58 | let crate_def_map = db.crate_def_map(krate); | 58 | let crate_def_map = db.crate_def_map(krate); |
59 | for (_module_id, module_data) in crate_def_map.modules.iter() { | 59 | for (_module_id, module_data) in crate_def_map.modules.iter() { |
60 | for &impl_id in module_data.impls.iter() { | 60 | for &impl_id in module_data.impls.iter() { |
61 | match db.impl_ty(impl_id) { | 61 | match db.impl_trait(impl_id) { |
62 | ImplTy::TraitRef(tr) => { | 62 | Some(tr) => { |
63 | res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); | 63 | res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); |
64 | } | 64 | } |
65 | ImplTy::Inherent(self_ty) => { | 65 | None => { |
66 | let self_ty = db.impl_self_ty(impl_id); | ||
66 | if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) { | 67 | if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) { |
67 | res.impls.entry(self_ty_fp).or_default().push(impl_id); | 68 | res.impls.entry(self_ty_fp).or_default().push(impl_id); |
68 | } | 69 | } |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index c8461b447..c856d6afd 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -8,7 +8,7 @@ use hir_def::{ | |||
8 | body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId, | 8 | body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId, |
9 | LocalModuleId, Lookup, ModuleDefId, | 9 | LocalModuleId, Lookup, ModuleDefId, |
10 | }; | 10 | }; |
11 | use hir_expand::Source; | 11 | use hir_expand::InFile; |
12 | use insta::assert_snapshot; | 12 | use insta::assert_snapshot; |
13 | use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; | 13 | use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; |
14 | use ra_syntax::{ | 14 | use ra_syntax::{ |
@@ -222,6 +222,56 @@ mod collections { | |||
222 | } | 222 | } |
223 | 223 | ||
224 | #[test] | 224 | #[test] |
225 | fn infer_ranges() { | ||
226 | let (db, pos) = TestDB::with_position( | ||
227 | r#" | ||
228 | //- /main.rs crate:main deps:std | ||
229 | fn test() { | ||
230 | let a = ..; | ||
231 | let b = 1..; | ||
232 | let c = ..2u32; | ||
233 | let d = 1..2usize; | ||
234 | let e = ..=10; | ||
235 | let f = 'a'..='z'; | ||
236 | |||
237 | let t = (a, b, c, d, e, f); | ||
238 | t<|>; | ||
239 | } | ||
240 | |||
241 | //- /std.rs crate:std | ||
242 | #[prelude_import] use prelude::*; | ||
243 | mod prelude {} | ||
244 | |||
245 | pub mod ops { | ||
246 | pub struct Range<Idx> { | ||
247 | pub start: Idx, | ||
248 | pub end: Idx, | ||
249 | } | ||
250 | pub struct RangeFrom<Idx> { | ||
251 | pub start: Idx, | ||
252 | } | ||
253 | struct RangeFull; | ||
254 | pub struct RangeInclusive<Idx> { | ||
255 | start: Idx, | ||
256 | end: Idx, | ||
257 | is_empty: u8, | ||
258 | } | ||
259 | pub struct RangeTo<Idx> { | ||
260 | pub end: Idx, | ||
261 | } | ||
262 | pub struct RangeToInclusive<Idx> { | ||
263 | pub end: Idx, | ||
264 | } | ||
265 | } | ||
266 | "#, | ||
267 | ); | ||
268 | assert_eq!( | ||
269 | "(RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)", | ||
270 | type_at_pos(&db, pos), | ||
271 | ); | ||
272 | } | ||
273 | |||
274 | #[test] | ||
225 | fn infer_while_let() { | 275 | fn infer_while_let() { |
226 | let (db, pos) = TestDB::with_position( | 276 | let (db, pos) = TestDB::with_position( |
227 | r#" | 277 | r#" |
@@ -2104,7 +2154,6 @@ fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) { | |||
2104 | } | 2154 | } |
2105 | 2155 | ||
2106 | #[test] | 2156 | #[test] |
2107 | #[should_panic] // we currently can't handle this | ||
2108 | fn recursive_type_alias() { | 2157 | fn recursive_type_alias() { |
2109 | assert_snapshot!( | 2158 | assert_snapshot!( |
2110 | infer(r#" | 2159 | infer(r#" |
@@ -2113,7 +2162,10 @@ type Foo = Foo; | |||
2113 | type Bar = A<Bar>; | 2162 | type Bar = A<Bar>; |
2114 | fn test(x: Foo) {} | 2163 | fn test(x: Foo) {} |
2115 | "#), | 2164 | "#), |
2116 | @"" | 2165 | @r###" |
2166 | [59; 60) 'x': {unknown} | ||
2167 | [67; 69) '{}': () | ||
2168 | "### | ||
2117 | ) | 2169 | ) |
2118 | } | 2170 | } |
2119 | 2171 | ||
@@ -4626,10 +4678,48 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { | |||
4626 | } | 4678 | } |
4627 | 4679 | ||
4628 | #[test] | 4680 | #[test] |
4629 | // FIXME this is currently a Salsa panic; it would be nicer if it just returned | 4681 | fn trait_impl_self_ty() { |
4630 | // in Unknown, and we should be able to do that once Salsa allows us to handle | 4682 | let t = type_at( |
4631 | // the cycle. But at least it doesn't overflow for now. | 4683 | r#" |
4632 | #[should_panic] | 4684 | //- /main.rs |
4685 | trait Trait<T> { | ||
4686 | fn foo(&self); | ||
4687 | } | ||
4688 | |||
4689 | struct S; | ||
4690 | |||
4691 | impl Trait<Self> for S {} | ||
4692 | |||
4693 | fn test() { | ||
4694 | S.foo()<|>; | ||
4695 | } | ||
4696 | "#, | ||
4697 | ); | ||
4698 | assert_eq!(t, "()"); | ||
4699 | } | ||
4700 | |||
4701 | #[test] | ||
4702 | fn trait_impl_self_ty_cycle() { | ||
4703 | let t = type_at( | ||
4704 | r#" | ||
4705 | //- /main.rs | ||
4706 | trait Trait { | ||
4707 | fn foo(&self); | ||
4708 | } | ||
4709 | |||
4710 | struct S<T>; | ||
4711 | |||
4712 | impl Trait for S<Self> {} | ||
4713 | |||
4714 | fn test() { | ||
4715 | S.foo()<|>; | ||
4716 | } | ||
4717 | "#, | ||
4718 | ); | ||
4719 | assert_eq!(t, "{unknown}"); | ||
4720 | } | ||
4721 | |||
4722 | #[test] | ||
4633 | fn unselected_projection_in_trait_env_cycle_1() { | 4723 | fn unselected_projection_in_trait_env_cycle_1() { |
4634 | let t = type_at( | 4724 | let t = type_at( |
4635 | r#" | 4725 | r#" |
@@ -4650,10 +4740,6 @@ fn test<T: Trait>() where T: Trait2<T::Item> { | |||
4650 | } | 4740 | } |
4651 | 4741 | ||
4652 | #[test] | 4742 | #[test] |
4653 | // FIXME this is currently a Salsa panic; it would be nicer if it just returned | ||
4654 | // in Unknown, and we should be able to do that once Salsa allows us to handle | ||
4655 | // the cycle. But at least it doesn't overflow for now. | ||
4656 | #[should_panic] | ||
4657 | fn unselected_projection_in_trait_env_cycle_2() { | 4743 | fn unselected_projection_in_trait_env_cycle_2() { |
4658 | let t = type_at( | 4744 | let t = type_at( |
4659 | r#" | 4745 | r#" |
@@ -4680,7 +4766,7 @@ fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { | |||
4680 | for decl in crate_def_map[module.local_id].scope.declarations() { | 4766 | for decl in crate_def_map[module.local_id].scope.declarations() { |
4681 | if let ModuleDefId::FunctionId(func) = decl { | 4767 | if let ModuleDefId::FunctionId(func) = decl { |
4682 | let (_body, source_map) = db.body_with_source_map(func.into()); | 4768 | let (_body, source_map) = db.body_with_source_map(func.into()); |
4683 | if let Some(expr_id) = source_map.node_expr(Source::new(pos.file_id.into(), &expr)) { | 4769 | if let Some(expr_id) = source_map.node_expr(InFile::new(pos.file_id.into(), &expr)) { |
4684 | let infer = db.infer(func.into()); | 4770 | let infer = db.infer(func.into()); |
4685 | let ty = &infer[expr_id]; | 4771 | let ty = &infer[expr_id]; |
4686 | return ty.display(db).to_string(); | 4772 | return ty.display(db).to_string(); |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 35de37e6b..104346ada 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -20,8 +20,8 @@ use ra_db::salsa::{InternId, InternKey}; | |||
20 | 20 | ||
21 | use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; | 21 | use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; |
22 | use crate::{ | 22 | use crate::{ |
23 | db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ImplTy, ProjectionTy, | 23 | db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ProjectionTy, Substs, |
24 | Substs, TraitRef, Ty, TypeCtor, TypeWalk, | 24 | TraitRef, Ty, TypeCtor, TypeWalk, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | /// This represents a trait whose name we could not resolve. | 27 | /// This represents a trait whose name we could not resolve. |
@@ -630,10 +630,7 @@ fn impl_block_datum( | |||
630 | chalk_id: chalk_ir::ImplId, | 630 | chalk_id: chalk_ir::ImplId, |
631 | impl_id: ImplId, | 631 | impl_id: ImplId, |
632 | ) -> Option<Arc<ImplDatum<ChalkIr>>> { | 632 | ) -> Option<Arc<ImplDatum<ChalkIr>>> { |
633 | let trait_ref = match db.impl_ty(impl_id) { | 633 | let trait_ref = db.impl_trait(impl_id)?; |
634 | ImplTy::TraitRef(it) => it, | ||
635 | ImplTy::Inherent(_) => return None, | ||
636 | }; | ||
637 | let impl_data = db.impl_data(impl_id); | 634 | let impl_data = db.impl_data(impl_id); |
638 | 635 | ||
639 | let generic_params = db.generic_params(impl_id.into()); | 636 | let generic_params = db.generic_params(impl_id.into()); |
@@ -787,11 +784,7 @@ fn type_alias_associated_ty_value( | |||
787 | _ => panic!("assoc ty value should be in impl"), | 784 | _ => panic!("assoc ty value should be in impl"), |
788 | }; | 785 | }; |
789 | 786 | ||
790 | let trait_ref = match db.impl_ty(impl_id) { | 787 | let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved |
791 | ImplTy::TraitRef(it) => it, | ||
792 | // we don't return any assoc ty values if the impl'd trait can't be resolved | ||
793 | ImplTy::Inherent(_) => panic!("assoc ty value should not exist"), | ||
794 | }; | ||
795 | 788 | ||
796 | let assoc_ty = db | 789 | let assoc_ty = db |
797 | .trait_data(trait_ref.trait_) | 790 | .trait_data(trait_ref.trait_) |