aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/db.rs12
-rw-r--r--crates/ra_hir_ty/src/infer.rs36
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs7
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs39
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs2
-rw-r--r--crates/ra_hir_ty/src/lib.rs15
-rw-r--r--crates/ra_hir_ty/src/lower.rs49
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs9
-rw-r--r--crates/ra_hir_ty/src/tests.rs106
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs15
10 files changed, 227 insertions, 63 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};
11use crate::{ 11use 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/infer.rs b/crates/ra_hir_ty/src/infer.rs
index f6283ab6d..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.
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
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{autoderef, db::HirDatabase, ImplTy, Substs, Ty, TypeCtor, TypeWalk}; 11use crate::{autoderef, db::HirDatabase, Substs, Ty, TypeCtor, TypeWalk};
12 12
13use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; 13use 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};
14use hir_expand::name::{self, Name}; 14use hir_expand::name::{self, Name};
15use ra_syntax::ast::RangeOp;
15 16
16use crate::{ 17use 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)]
490pub enum ImplTy {
491 Inherent(Ty),
492 TraitRef(TraitRef),
493}
494
495impl 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
34impl Ty { 34impl 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
535pub(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
535impl TraitEnvironment { 544impl 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
746pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty {
747 Ty::Unknown
748}
749
736pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { 750pub(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
746pub(crate) fn impl_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> ImplTy { 760pub(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())) { 766pub(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
774pub(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 3766ab981..a3cc5cf95 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -222,6 +222,56 @@ mod collections {
222} 222}
223 223
224#[test] 224#[test]
225fn infer_ranges() {
226 let (db, pos) = TestDB::with_position(
227 r#"
228//- /main.rs crate:main deps:std
229fn 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::*;
243mod prelude {}
244
245pub 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]
225fn infer_while_let() { 275fn 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
2108fn recursive_type_alias() { 2157fn recursive_type_alias() {
2109 assert_snapshot!( 2158 assert_snapshot!(
2110 infer(r#" 2159 infer(r#"
@@ -2113,7 +2162,10 @@ type Foo = Foo;
2113type Bar = A<Bar>; 2162type Bar = A<Bar>;
2114fn test(x: Foo) {} 2163fn test(x: Foo) {}
2115"#), 2164"#),
2116 @"" 2165 @r###"
2166 [59; 60) 'x': {unknown}
2167 [67; 69) '{}': ()
2168 "###
2117 ) 2169 )
2118} 2170}
2119 2171
@@ -4662,10 +4714,48 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
4662} 4714}
4663 4715
4664#[test] 4716#[test]
4665// FIXME this is currently a Salsa panic; it would be nicer if it just returned 4717fn trait_impl_self_ty() {
4666// in Unknown, and we should be able to do that once Salsa allows us to handle 4718 let t = type_at(
4667// the cycle. But at least it doesn't overflow for now. 4719 r#"
4668#[should_panic] 4720//- /main.rs
4721trait Trait<T> {
4722 fn foo(&self);
4723}
4724
4725struct S;
4726
4727impl Trait<Self> for S {}
4728
4729fn test() {
4730 S.foo()<|>;
4731}
4732"#,
4733 );
4734 assert_eq!(t, "()");
4735}
4736
4737#[test]
4738fn trait_impl_self_ty_cycle() {
4739 let t = type_at(
4740 r#"
4741//- /main.rs
4742trait Trait {
4743 fn foo(&self);
4744}
4745
4746struct S<T>;
4747
4748impl Trait for S<Self> {}
4749
4750fn test() {
4751 S.foo()<|>;
4752}
4753"#,
4754 );
4755 assert_eq!(t, "{unknown}");
4756}
4757
4758#[test]
4669fn unselected_projection_in_trait_env_cycle_1() { 4759fn unselected_projection_in_trait_env_cycle_1() {
4670 let t = type_at( 4760 let t = type_at(
4671 r#" 4761 r#"
@@ -4686,10 +4776,6 @@ fn test<T: Trait>() where T: Trait2<T::Item> {
4686} 4776}
4687 4777
4688#[test] 4778#[test]
4689// FIXME this is currently a Salsa panic; it would be nicer if it just returned
4690// in Unknown, and we should be able to do that once Salsa allows us to handle
4691// the cycle. But at least it doesn't overflow for now.
4692#[should_panic]
4693fn unselected_projection_in_trait_env_cycle_2() { 4779fn unselected_projection_in_trait_env_cycle_2() {
4694 let t = type_at( 4780 let t = type_at(
4695 r#" 4781 r#"
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
21use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 21use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
22use crate::{ 22use 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_)