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/lib.rs14
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs10
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs31
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs57
4 files changed, 78 insertions, 34 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index ccc4348f4..daea02f88 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -808,15 +808,13 @@ impl Ty {
808 } 808 }
809 } 809 }
810 810
811 /// If this is an `impl Trait` or `dyn Trait`, returns that trait. 811 /// If this is a `dyn Trait`, returns that trait.
812 pub fn inherent_trait(&self) -> Option<TraitId> { 812 pub fn dyn_trait(&self) -> Option<TraitId> {
813 match self { 813 match self {
814 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 814 Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred {
815 predicates.iter().find_map(|pred| match pred { 815 GenericPredicate::Implemented(tr) => Some(tr.trait_),
816 GenericPredicate::Implemented(tr) => Some(tr.trait_), 816 _ => None,
817 _ => None, 817 }),
818 })
819 }
820 _ => None, 818 _ => None,
821 } 819 }
822 } 820 }
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 657284fd0..0851e16a8 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -408,8 +408,9 @@ fn iterate_trait_method_candidates<T>(
408 receiver_ty: Option<&Canonical<Ty>>, 408 receiver_ty: Option<&Canonical<Ty>>,
409 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, 409 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
410) -> Option<T> { 410) -> Option<T> {
411 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope 411 // if ty is `dyn Trait`, the trait doesn't need to be in scope
412 let inherent_trait = self_ty.value.inherent_trait().into_iter(); 412 let inherent_trait =
413 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
413 let env_traits = if let Ty::Placeholder(_) = self_ty.value { 414 let env_traits = if let Ty::Placeholder(_) = self_ty.value {
414 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 415 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
415 env.trait_predicates_for_self_ty(&self_ty.value) 416 env.trait_predicates_for_self_ty(&self_ty.value)
@@ -601,11 +602,6 @@ pub fn implements_trait(
601 krate: CrateId, 602 krate: CrateId,
602 trait_: TraitId, 603 trait_: TraitId,
603) -> bool { 604) -> bool {
604 if ty.value.inherent_trait() == Some(trait_) {
605 // FIXME this is a bit of a hack, since Chalk should say the same thing
606 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
607 return true;
608 }
609 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 605 let goal = generic_implements_goal(db, env, trait_, ty.clone());
610 let solution = db.trait_solve(krate, goal); 606 let solution = db.trait_solve(krate, goal);
611 607
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 67f964ab5..9c2c9e1d2 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -1096,3 +1096,34 @@ fn test() { (S {}).method()<|>; }
1096 ); 1096 );
1097 assert_eq!(t, "()"); 1097 assert_eq!(t, "()");
1098} 1098}
1099
1100#[test]
1101fn dyn_trait_super_trait_not_in_scope() {
1102 assert_snapshot!(
1103 infer(r#"
1104mod m {
1105 pub trait SuperTrait {
1106 fn foo(&self) -> u32 { 0 }
1107 }
1108}
1109trait Trait: m::SuperTrait {}
1110
1111struct S;
1112impl m::SuperTrait for S {}
1113impl Trait for S {}
1114
1115fn test(d: &dyn Trait) {
1116 d.foo();
1117}
1118"#),
1119 @r###"
1120 52..56 'self': &Self
1121 65..70 '{ 0 }': u32
1122 67..68 '0': u32
1123 177..178 'd': &dyn Trait
1124 192..208 '{ ...o(); }': ()
1125 198..199 'd': &dyn Trait
1126 198..205 'd.foo()': u32
1127 "###
1128 );
1129}
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 1ccb7c3b4..5870618a0 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -182,7 +182,10 @@ impl chalk_ir::interner::Interner for Interner {
182 Arc::new(goal) 182 Arc::new(goal)
183 } 183 }
184 184
185 fn intern_goals(&self, data: impl IntoIterator<Item = Goal<Self>>) -> Self::InternedGoals { 185 fn intern_goals<E>(
186 &self,
187 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
188 ) -> Result<Self::InternedGoals, E> {
186 data.into_iter().collect() 189 data.into_iter().collect()
187 } 190 }
188 191
@@ -222,10 +225,10 @@ impl chalk_ir::interner::Interner for Interner {
222 clause 225 clause
223 } 226 }
224 227
225 fn intern_program_clauses( 228 fn intern_program_clauses<E>(
226 &self, 229 &self,
227 data: impl IntoIterator<Item = chalk_ir::ProgramClause<Self>>, 230 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
228 ) -> Arc<[chalk_ir::ProgramClause<Self>]> { 231 ) -> Result<Arc<[chalk_ir::ProgramClause<Self>]>, E> {
229 data.into_iter().collect() 232 data.into_iter().collect()
230 } 233 }
231 234
@@ -236,10 +239,10 @@ impl chalk_ir::interner::Interner for Interner {
236 &clauses 239 &clauses
237 } 240 }
238 241
239 fn intern_quantified_where_clauses( 242 fn intern_quantified_where_clauses<E>(
240 &self, 243 &self,
241 data: impl IntoIterator<Item = chalk_ir::QuantifiedWhereClause<Self>>, 244 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
242 ) -> Self::InternedQuantifiedWhereClauses { 245 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
243 data.into_iter().collect() 246 data.into_iter().collect()
244 } 247 }
245 248
@@ -250,10 +253,10 @@ impl chalk_ir::interner::Interner for Interner {
250 clauses 253 clauses
251 } 254 }
252 255
253 fn intern_parameter_kinds( 256 fn intern_parameter_kinds<E>(
254 &self, 257 &self,
255 data: impl IntoIterator<Item = chalk_ir::ParameterKind<()>>, 258 data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<()>, E>>,
256 ) -> Self::InternedParameterKinds { 259 ) -> Result<Self::InternedParameterKinds, E> {
257 data.into_iter().collect() 260 data.into_iter().collect()
258 } 261 }
259 262
@@ -264,10 +267,10 @@ impl chalk_ir::interner::Interner for Interner {
264 &parameter_kinds 267 &parameter_kinds
265 } 268 }
266 269
267 fn intern_canonical_var_kinds( 270 fn intern_canonical_var_kinds<E>(
268 &self, 271 &self,
269 data: impl IntoIterator<Item = chalk_ir::ParameterKind<UniverseIndex>>, 272 data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<UniverseIndex>, E>>,
270 ) -> Self::InternedCanonicalVarKinds { 273 ) -> Result<Self::InternedCanonicalVarKinds, E> {
271 data.into_iter().collect() 274 data.into_iter().collect()
272 } 275 }
273 276
@@ -460,6 +463,14 @@ impl ToChalk for TypeCtor {
460 TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 463 TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
461 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 464 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
462 TypeName::OpaqueType(_) => unreachable!(), 465 TypeName::OpaqueType(_) => unreachable!(),
466
467 TypeName::Scalar(_) => unreachable!(),
468 TypeName::Tuple(_) => unreachable!(),
469 TypeName::Raw(_) => unreachable!(),
470 TypeName::Slice => unreachable!(),
471 TypeName::Ref(_) => unreachable!(),
472 TypeName::Str => unreachable!(),
473
463 TypeName::Error => { 474 TypeName::Error => {
464 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 475 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
465 unreachable!() 476 unreachable!()
@@ -862,12 +873,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
862 // We don't do coherence checking (yet) 873 // We don't do coherence checking (yet)
863 unimplemented!() 874 unimplemented!()
864 } 875 }
865 fn as_struct_id(&self, id: &TypeName<Interner>) -> Option<StructId> {
866 match id {
867 TypeName::Struct(struct_id) => Some(*struct_id),
868 _ => None,
869 }
870 }
871 fn interner(&self) -> &Interner { 876 fn interner(&self) -> &Interner {
872 &Interner 877 &Interner
873 } 878 }
@@ -892,6 +897,20 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
892 ) -> Arc<chalk_rust_ir::OpaqueTyDatum<Interner>> { 897 ) -> Arc<chalk_rust_ir::OpaqueTyDatum<Interner>> {
893 unimplemented!() 898 unimplemented!()
894 } 899 }
900
901 fn force_impl_for(
902 &self,
903 _well_known: chalk_rust_ir::WellKnownTrait,
904 _ty: &chalk_ir::TyData<Interner>,
905 ) -> Option<bool> {
906 // this method is mostly for rustc
907 None
908 }
909
910 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
911 // FIXME: implement actual object safety
912 true
913 }
895} 914}
896 915
897pub(crate) fn program_clauses_for_chalk_env_query( 916pub(crate) fn program_clauses_for_chalk_env_query(