Skip to content

Commit 7ad7f3c

Browse files
Merge #5211
5211: Fix inference of indexing argument (partly) r=flodiebold a=flodiebold 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. Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
2 parents 0f68fed + 57feb32 commit 7ad7f3c

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

crates/ra_hir_ty/src/infer.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use hir_def::{
2828
path::{path, Path},
2929
resolver::{HasResolver, Resolver, TypeNs},
3030
type_ref::{Mutability, TypeRef},
31-
AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, TraitId, TypeAliasId,
32-
VariantId,
31+
AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId,
32+
TypeAliasId, VariantId,
3333
};
3434
use hir_expand::{diagnostics::DiagnosticSink, name::name};
3535
use ra_arena::map::ArenaMap;
@@ -376,17 +376,21 @@ impl<'a> InferenceContext<'a> {
376376
) -> Ty {
377377
match assoc_ty {
378378
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+
};
379383
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)
381385
.push(inner_ty)
382-
.fill(params.iter().cloned());
386+
.fill(params.iter().cloned())
387+
.build();
388+
let trait_ref = TraitRef { trait_, substs: substs.clone() };
383389
let projection = ProjectionPredicate {
384390
ty: ty.clone(),
385-
projection_ty: ProjectionTy {
386-
associated_ty: res_assoc_ty,
387-
parameters: builder.build(),
388-
},
391+
projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs },
389392
};
393+
self.obligations.push(Obligation::Trait(trait_ref));
390394
self.obligations.push(Obligation::Projection(projection));
391395
self.resolve_ty_as_possible(ty)
392396
}

crates/ra_hir_ty/src/tests/traits.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,42 @@ mod ops {
540540
);
541541
}
542542

543+
#[test]
544+
fn infer_ops_index_int() {
545+
check_types(
546+
r#"
547+
//- /main.rs crate:main deps:std
548+
struct Bar;
549+
struct Foo;
550+
551+
impl std::ops::Index<u32> for Bar {
552+
type Output = Foo;
553+
}
554+
555+
struct Range;
556+
impl std::ops::Index<Range> for Bar {
557+
type Output = Bar;
558+
}
559+
560+
fn 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::*;
569+
mod ops {
570+
#[lang = "index"]
571+
pub trait Index<Idx> {
572+
type Output;
573+
}
574+
}
575+
"#,
576+
);
577+
}
578+
543579
#[test]
544580
fn infer_ops_index_autoderef() {
545581
check_types(

0 commit comments

Comments
 (0)