Skip to content

Commit 4b4eaba

Browse files
committed
Record method resolution for try expressions
1 parent a7f81e3 commit 4b4eaba

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

crates/hir-ty/src/infer.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -938,19 +938,24 @@ impl<'a> InferenceContext<'a> {
938938
self.db.trait_data(trait_).associated_type_by_name(&name![Item])
939939
}
940940

941-
fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
942-
let trait_ = self.resolve_lang_item(LangItem::Try)?.as_trait()?;
941+
fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
943942
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
944943
}
945944

945+
fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> {
946+
self.resolve_lang_item(lang)?.as_trait()
947+
}
948+
949+
fn resolve_ops_try_output(&self) -> Option<TypeAliasId> {
950+
self.resolve_output_on(self.resolve_lang_trait(LangItem::Try)?)
951+
}
952+
946953
fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
947-
let trait_ = self.resolve_lang_item(LangItem::Neg)?.as_trait()?;
948-
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
954+
self.resolve_output_on(self.resolve_lang_trait(LangItem::Neg)?)
949955
}
950956

951957
fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
952-
let trait_ = self.resolve_lang_item(LangItem::Not)?.as_trait()?;
953-
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
958+
self.resolve_output_on(self.resolve_lang_trait(LangItem::Not)?)
954959
}
955960

956961
fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
@@ -960,7 +965,7 @@ impl<'a> InferenceContext<'a> {
960965
.lookup(self.db.upcast())
961966
.container
962967
else { return None };
963-
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
968+
self.resolve_output_on(trait_)
964969
}
965970

966971
fn resolve_boxed_box(&self) -> Option<AdtId> {
@@ -998,13 +1003,8 @@ impl<'a> InferenceContext<'a> {
9981003
Some(struct_.into())
9991004
}
10001005

1001-
fn resolve_ops_index(&self) -> Option<TraitId> {
1002-
self.resolve_lang_item(LangItem::Index)?.as_trait()
1003-
}
1004-
10051006
fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
1006-
let trait_ = self.resolve_ops_index()?;
1007-
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
1007+
self.resolve_output_on(self.resolve_lang_trait(LangItem::Index)?)
10081008
}
10091009

10101010
fn resolve_va_list(&self) -> Option<AdtId> {

crates/hir-ty/src/infer/expr.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use hir_def::{
1313
ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
1414
},
1515
generics::TypeOrConstParamData,
16+
lang_item::LangItem,
1617
path::{GenericArg, GenericArgs},
1718
resolver::resolver_for_expr,
1819
ConstParamId, FieldId, ItemContainerId, Lookup,
@@ -157,7 +158,8 @@ impl<'a> InferenceContext<'a> {
157158
}
158159

159160
// The ok-ish type that is expected from the last expression
160-
let ok_ty = self.resolve_associated_type(try_ty.clone(), self.resolve_ops_try_ok());
161+
let ok_ty =
162+
self.resolve_associated_type(try_ty.clone(), self.resolve_ops_try_output());
161163

162164
self.with_breakable_ctx(BreakableKind::Block, ok_ty.clone(), None, |this| {
163165
this.infer_expr(*body, &Expectation::has_type(ok_ty));
@@ -593,9 +595,19 @@ impl<'a> InferenceContext<'a> {
593595
self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
594596
}
595597
Expr::Try { expr } => {
596-
// FIXME: Note down method resolution her
597598
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
598-
self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
599+
if let Some(trait_) = self.resolve_lang_trait(LangItem::Try) {
600+
if let Some(func) = self.db.trait_data(trait_).method_by_name(&name!(branch)) {
601+
let subst = TyBuilder::subst_for_def(self.db, trait_, None)
602+
.push(inner_ty.clone())
603+
.build();
604+
self.write_method_resolution(tgt_expr, func, subst.clone());
605+
}
606+
let try_output = self.resolve_output_on(trait_);
607+
self.resolve_associated_type(inner_ty, try_output)
608+
} else {
609+
self.err_ty()
610+
}
599611
}
600612
Expr::Cast { expr, type_ref } => {
601613
// FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary)
@@ -744,7 +756,7 @@ impl<'a> InferenceContext<'a> {
744756
let base_ty = self.infer_expr_inner(*base, &Expectation::none());
745757
let index_ty = self.infer_expr(*index, &Expectation::none());
746758

747-
if let Some(index_trait) = self.resolve_ops_index() {
759+
if let Some(index_trait) = self.resolve_lang_trait(LangItem::Index) {
748760
let canonicalized = self.canonicalize(base_ty.clone());
749761
let receiver_adjustments = method_resolution::resolve_indexing_op(
750762
self.db,

0 commit comments

Comments
 (0)