diff options
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/Cargo.toml | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 57 |
5 files changed, 81 insertions, 37 deletions
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 65db6d1b0..5fc0ec5e3 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml | |||
@@ -27,9 +27,9 @@ test_utils = { path = "../test_utils" } | |||
27 | 27 | ||
28 | scoped-tls = "1" | 28 | scoped-tls = "1" |
29 | 29 | ||
30 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" } | 30 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } |
31 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" } | 31 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } |
32 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" } | 32 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } |
33 | 33 | ||
34 | [dev-dependencies] | 34 | [dev-dependencies] |
35 | insta = "0.16.0" | 35 | insta = "0.16.0" |
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] | ||
1101 | fn dyn_trait_super_trait_not_in_scope() { | ||
1102 | assert_snapshot!( | ||
1103 | infer(r#" | ||
1104 | mod m { | ||
1105 | pub trait SuperTrait { | ||
1106 | fn foo(&self) -> u32 { 0 } | ||
1107 | } | ||
1108 | } | ||
1109 | trait Trait: m::SuperTrait {} | ||
1110 | |||
1111 | struct S; | ||
1112 | impl m::SuperTrait for S {} | ||
1113 | impl Trait for S {} | ||
1114 | |||
1115 | fn 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 | ¶meter_kinds | 267 | ¶meter_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 | ||
897 | pub(crate) fn program_clauses_for_chalk_env_query( | 916 | pub(crate) fn program_clauses_for_chalk_env_query( |