aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-07-03 16:39:06 +0100
committerFlorian Diebold <[email protected]>2020-07-03 17:17:06 +0100
commit57feb323f79d1d7f7dd6251d4606ba12a800953a (patch)
treecd24fdeb7f4ee5cfb8c074c73721c53f2c3ccdd0
parentdceec6176b49f886b94f1e149887fc9542702971 (diff)
Fix inference of indexing argument (partly)
We need to add the `T: Index<Arg>` obligation to be resolved later as well, otherwise we can't make inferences about `Arg` later based on the `Index` impls. This still doesn't fix indexing with integer variables though; there's a further problem with Chalk floundering because of the variable, I think.
-rw-r--r--crates/ra_hir_ty/src/infer.rs20
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs36
2 files changed, 48 insertions, 8 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 3719f76a6..5c56c2eb0 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -28,8 +28,8 @@ use hir_def::{
28 path::{path, Path}, 28 path::{path, Path},
29 resolver::{HasResolver, Resolver, TypeNs}, 29 resolver::{HasResolver, Resolver, TypeNs},
30 type_ref::{Mutability, TypeRef}, 30 type_ref::{Mutability, TypeRef},
31 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, TraitId, TypeAliasId, 31 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId,
32 VariantId, 32 TypeAliasId, VariantId,
33}; 33};
34use hir_expand::{diagnostics::DiagnosticSink, name::name}; 34use hir_expand::{diagnostics::DiagnosticSink, name::name};
35use ra_arena::map::ArenaMap; 35use ra_arena::map::ArenaMap;
@@ -376,17 +376,21 @@ impl<'a> InferenceContext<'a> {
376 ) -> Ty { 376 ) -> Ty {
377 match assoc_ty { 377 match assoc_ty {
378 Some(res_assoc_ty) => { 378 Some(res_assoc_ty) => {
379 let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container {
380 hir_def::AssocContainerId::TraitId(trait_) => trait_,
381 _ => panic!("resolve_associated_type called with non-associated type"),
382 };
379 let ty = self.table.new_type_var(); 383 let ty = self.table.new_type_var();
380 let builder = Substs::build_for_def(self.db, res_assoc_ty) 384 let substs = Substs::build_for_def(self.db, res_assoc_ty)
381 .push(inner_ty) 385 .push(inner_ty)
382 .fill(params.iter().cloned()); 386 .fill(params.iter().cloned())
387 .build();
388 let trait_ref = TraitRef { trait_, substs: substs.clone() };
383 let projection = ProjectionPredicate { 389 let projection = ProjectionPredicate {
384 ty: ty.clone(), 390 ty: ty.clone(),
385 projection_ty: ProjectionTy { 391 projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs },
386 associated_ty: res_assoc_ty,
387 parameters: builder.build(),
388 },
389 }; 392 };
393 self.obligations.push(Obligation::Trait(trait_ref));
390 self.obligations.push(Obligation::Projection(projection)); 394 self.obligations.push(Obligation::Projection(projection));
391 self.resolve_ty_as_possible(ty) 395 self.resolve_ty_as_possible(ty)
392 } 396 }
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 766790576..529d9e253 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -541,6 +541,42 @@ mod ops {
541} 541}
542 542
543#[test] 543#[test]
544fn infer_ops_index_int() {
545 check_types(
546 r#"
547//- /main.rs crate:main deps:std
548struct Bar;
549struct Foo;
550
551impl std::ops::Index<u32> for Bar {
552 type Output = Foo;
553}
554
555struct Range;
556impl std::ops::Index<Range> for Bar {
557 type Output = Bar;
558}
559
560fn test() {
561 let a = Bar;
562 let b = a[1];
563 b;
564 //^ Foo
565}
566
567//- /std.rs crate:std
568#[prelude_import] use ops::*;
569mod ops {
570 #[lang = "index"]
571 pub trait Index<Idx> {
572 type Output;
573 }
574}
575"#,
576 );
577}
578
579#[test]
544fn infer_ops_index_autoderef() { 580fn infer_ops_index_autoderef() {
545 check_types( 581 check_types(
546 r#" 582 r#"