Skip to content

Commit 2b201a1

Browse files
Fix a bug
The binders of the recovery value weren't correct.
1 parent fbdcafa commit 2b201a1

File tree

4 files changed

+78
-31
lines changed

4 files changed

+78
-31
lines changed

crates/hir-def/src/nameres/assoc.rs

+7
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ impl ImplItems {
112112
pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
113113
self.macro_calls.iter().flat_map(|it| it.iter()).copied()
114114
}
115+
116+
pub fn method_by_name(&self, name: &Name) -> Option<FunctionId> {
117+
self.items.iter().find_map(|(item_name, item)| match item {
118+
AssocItemId::FunctionId(t) if item_name == name => Some(*t),
119+
_ => None,
120+
})
121+
}
115122
}
116123

117124
struct AssocItemCollector<'a> {

crates/hir-ty/src/chalk_db.rs

+6-18
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use chalk_ir::{
1313
cast::{Cast, Caster},
1414
fold::shift::Shift,
1515
};
16-
use chalk_solve::rust_ir::{
17-
self, AssociatedTyDatumBound, AssociatedTyValueBound, OpaqueTyDatumBound, WellKnownTrait,
18-
};
16+
use chalk_solve::rust_ir::{self, AssociatedTyDatumBound, OpaqueTyDatumBound, WellKnownTrait};
1917

2018
use base_db::Crate;
2119
use hir_def::{
@@ -33,15 +31,16 @@ use crate::{
3331
db::{HirDatabase, InternedCoroutine},
3432
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
3533
generics::generics,
36-
lower::LifetimeElisionKind,
37-
lower::trait_fn_signature,
34+
lower::{LifetimeElisionKind, trait_fn_signature},
3835
make_binders, make_single_type_binders,
3936
mapping::{
4037
AnyImplAssocType, AnyTraitAssocType, ToChalk, from_assoc_type_value_id, from_chalk,
4138
to_assoc_type_id_rpitit, to_assoc_type_value_id, to_assoc_type_value_id_rpitit,
4239
},
4340
method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TraitImpls, TyFingerprint},
44-
rpitit::{RpititImplAssocTy, RpititImplAssocTyId, impl_method_rpitit_values},
41+
rpitit::{
42+
RpititImplAssocTy, RpititImplAssocTyId, impl_method_rpitit_values, recovery_rpitit_value,
43+
},
4544
to_assoc_type_id, to_chalk_trait_id,
4645
traits::ChalkContext,
4746
utils::ClosureSubst,
@@ -1020,18 +1019,7 @@ pub(crate) fn associated_ty_value_cycle(
10201019
AnyImplAssocType::Normal(type_alias) => {
10211020
type_alias_associated_ty_value(db, krate, type_alias)
10221021
}
1023-
AnyImplAssocType::Rpitit(assoc_type_id) => {
1024-
let assoc = assoc_type_id.loc(db);
1025-
let trait_assoc = assoc.trait_assoc.loc(db);
1026-
Arc::new(AssociatedTyValue {
1027-
associated_ty_id: to_assoc_type_id_rpitit(assoc.trait_assoc),
1028-
impl_id: assoc.impl_id.to_chalk(db),
1029-
value: trait_assoc
1030-
.bounds
1031-
.as_ref()
1032-
.map(|_| AssociatedTyValueBound { ty: TyKind::Error.intern(Interner) }),
1033-
})
1034-
}
1022+
AnyImplAssocType::Rpitit(assoc_type_id) => recovery_rpitit_value(db, assoc_type_id),
10351023
}
10361024
}
10371025

crates/hir-ty/src/rpitit.rs

+25-13
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use chalk_ir::{
1010
};
1111
use chalk_solve::rust_ir::AssociatedTyValueBound;
1212
use hir_def::{
13-
AssocItemId, ConstParamId, FunctionId, GenericDefId, GenericParamId, ImplId, ItemContainerId,
14-
TraitId,
13+
ConstParamId, FunctionId, GenericDefId, GenericParamId, ImplId, ItemContainerId, TraitId,
1514
hir::generics::{GenericParams, TypeOrConstParamData},
1615
resolver::HasResolver,
1716
};
@@ -78,16 +77,7 @@ pub(crate) fn impl_method_rpitit_values(
7877
let trait_method_generics = generics(db, trait_method_id.into());
7978
let trait_method = db.function_signature(trait_method_id);
8079
let impl_trait_ref = db.impl_trait(impl_id).expect("invalid impl passed to Chalk");
81-
let impl_method = impl_items.items.iter().find_map(|(name, id)| {
82-
if *name == trait_method.name {
83-
match *id {
84-
AssocItemId::FunctionId(it) => Some(it),
85-
_ => None,
86-
}
87-
} else {
88-
None
89-
}
90-
});
80+
let impl_method = impl_items.method_by_name(&trait_method.name);
9181
let impl_method = match impl_method {
9282
Some(impl_method) => impl_method,
9383
None => {
@@ -244,7 +234,7 @@ fn defaulted_impl_method_rpitit_values(
244234
Interner,
245235
variable_kinds_from_generics(
246236
db,
247-
trait_method_generics.iter_self_id().chain(impl_generics.iter_id()),
237+
impl_generics.iter_id().chain(trait_method_generics.iter_self_id()),
248238
),
249239
);
250240
defaulted_rpitit_values
@@ -640,3 +630,25 @@ pub(crate) fn add_method_body_rpitit_clauses(
640630
_ => {}
641631
}
642632
}
633+
634+
pub(crate) fn recovery_rpitit_value(
635+
db: &dyn HirDatabase,
636+
impl_assoc: RpititImplAssocTyId,
637+
) -> Arc<AssociatedTyValue> {
638+
let impl_assoc = impl_assoc.loc(db);
639+
let trait_assoc = impl_assoc.trait_assoc.loc(db);
640+
let impl_generics = generics(db, impl_assoc.impl_id.into());
641+
let trait_method_generics = generics(db, trait_assoc.synthesized_from_method.into());
642+
let binders = VariableKinds::from_iter(
643+
Interner,
644+
variable_kinds_from_generics(
645+
db,
646+
impl_generics.iter_id().chain(trait_method_generics.iter_self_id()),
647+
),
648+
);
649+
Arc::new(AssociatedTyValue {
650+
associated_ty_id: to_assoc_type_id_rpitit(impl_assoc.trait_assoc),
651+
impl_id: impl_assoc.impl_id.to_chalk(db),
652+
value: Binders::new(binders, AssociatedTyValueBound { ty: TyKind::Error.intern(Interner) }),
653+
})
654+
}

crates/hir-ty/src/tests/traits.rs

+40
Original file line numberDiff line numberDiff line change
@@ -5190,3 +5190,43 @@ trait Trait {
51905190
"#]],
51915191
);
51925192
}
5193+
5194+
#[test]
5195+
fn rpitit_cycle_with_impl_generics() {
5196+
check_infer(
5197+
r#"
5198+
//- minicore: sized, iterator
5199+
pub trait HasAttrs: Sized {
5200+
fn foo(self) -> impl Iterator<Item = ()> {
5201+
loop {}
5202+
}
5203+
}
5204+
enum Either<L, R> {
5205+
Left(L),
5206+
Right(R),
5207+
}
5208+
impl<L, R> HasAttrs for Either<L, R>
5209+
where
5210+
L: HasAttrs,
5211+
R: HasAttrs,
5212+
{
5213+
}
5214+
struct AnyHasAttrs;
5215+
impl HasAttrs for AnyHasAttrs {}
5216+
5217+
fn foo(v: AnyHasAttrs) {
5218+
v.foo();
5219+
}
5220+
"#,
5221+
expect![[r#"
5222+
39..43 'self': Self
5223+
73..96 '{ ... }': !
5224+
83..90 'loop {}': !
5225+
88..90 '{}': ()
5226+
290..291 'v': AnyHasAttrs
5227+
306..322 '{ ...o(); }': ()
5228+
312..313 'v': AnyHasAttrs
5229+
312..319 'v.foo()': {unknown}
5230+
"#]],
5231+
);
5232+
}

0 commit comments

Comments
 (0)