},
Some(TypeNs::GenericParam(param_id)) => {
let predicates = ctx.db.generic_predicates_for_param(param_id);
- predicates
+ let mut traits_: Vec<_> = predicates
.iter()
.filter_map(|pred| match &pred.value {
GenericPredicate::Implemented(tr) => Some(tr.trait_),
_ => None,
})
- .collect()
+ .collect();
+ // Handle `Self::Type` referring to own associated type in trait definitions
+ if let GenericDefId::TraitId(trait_id) = param_id.parent {
+ let generics = generics(ctx.db.upcast(), trait_id.into());
+ if generics.params.types[param_id.local_id].provenance
+ == TypeParamProvenance::TraitSelf
+ {
+ traits_.push(trait_id);
+ }
+ }
+ traits_
}
_ => return Ty::Unknown,
};
"#,
);
- // should be Option<char>, but currently not because of Chalk ambiguity problem
- assert_eq!("(Option<{unknown}>, Option<{unknown}>)", super::type_at_pos(&db, pos));
+ assert_eq!("(Option<char>, Option<char>)", super::type_at_pos(&db, pos));
}
#[test]
}
#[test]
-fn unselected_projection_on_trait_self() {
+fn unselected_projection_on_impl_self() {
assert_snapshot!(infer(
r#"
//- /main.rs
"###);
}
+#[test]
+fn unselected_projection_on_trait_self() {
+ let t = type_at(
+ r#"
+//- /main.rs
+trait Trait {
+ type Item;
+
+ fn f(&self) -> Self::Item { loop {} }
+}
+
+struct S;
+impl Trait for S {
+ type Item = u32;
+}
+
+fn test() {
+ S.f()<|>;
+}
+"#,
+ );
+ assert_eq!(t, "u32");
+}
+
#[test]
fn trait_impl_self_ty() {
let t = type_at(