Skip to content

Commit

Permalink
fix: rust-lang#12247 fully qualified call required to determine trait…
Browse files Browse the repository at this point in the history
… method type
  • Loading branch information
bitgaoshu committed Dec 10, 2022
1 parent 398a71a commit 2c15597
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
2 changes: 2 additions & 0 deletions crates/hir-expand/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,13 @@ pub mod known {
IntoIter,
Try,
Ok,
Err,
Future,
IntoFuture,
Result,
Option,
Output,
Residual,
Target,
Box,
RangeFrom,
Expand Down
11 changes: 11 additions & 0 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,17 @@ impl<'a> InferenceContext<'a> {
.or_else(|| trait_data.associated_type_by_name(&name![Output]))
}

fn resolve_ops_try_err(&self) -> Option<TypeAliasId> {
// FIXME resolve via lang_item once try v2 is stable
let path = path![core::ops::Try];
let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
let trait_data = self.db.trait_data(trait_);
trait_data
// FIXME remove once try v2 is stable
.associated_type_by_name(&name![Err])
.or_else(|| trait_data.associated_type_by_name(&name![Residual]))
}

fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
let trait_ = self.resolve_lang_item(name![neg])?.as_trait()?;
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
Expand Down
8 changes: 8 additions & 0 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,14 @@ impl<'a> InferenceContext<'a> {
}
Expr::Try { expr } => {
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
let actual_ret = inner_ty.clone();
let residual = self.resolve_ops_try_err();
let expect_err = self.resolve_associated_type(self.return_ty.clone(), residual);
let actual_err = self.resolve_associated_type(actual_ret, residual);
match self.table.coerce(&actual_err, &expect_err) {
Err(_) => (),
Ok(_) => (),
}
self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
}
Expr::Cast { expr, type_ref } => {
Expand Down
51 changes: 51 additions & 0 deletions crates/hir-ty/src/tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,57 @@ fn clone_iter<T>(s: Iter<T>) {
)
}

#[test]
fn issue_12247() {
check_types(
r#"
//- minicore: result, try
fn aa() -> Result<i32, E3> {
let a : Result<i32, E1> = Err(E1);
let b = a.mapE()?;
//^ i32
}
struct E1;
struct E2;
struct E3;
impl From<E1> for E2 {
fn from(value: E1) -> Self {
E2
}
}
impl From<E1> for E3 {
fn from(value: E1) -> Self {
E3
}
}
trait MapErr<T, E> {
fn mapE(self) -> Result<T, E>;
}
impl <T, ET> MapErr<T, E2> for Result<T, ET>
where
ET: Into<E2>,
{
fn mapE(self) -> Result<T, E2> {
self.map_err(|e| e.into())
}
}
impl <T, ET> MapErr<T, E3> for Result<T, ET>
where
ET: Into<E3>,
{
fn mapE(self) -> Result<T, E3> {
self.map_err(|e| e.into())
}
}
"#,
)
}


#[test]
fn issue_8686() {
check_infer(
Expand Down

0 comments on commit 2c15597

Please sign in to comment.