Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/expr.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 99 |
1 files changed, 8 insertions, 91 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 59ab50d071..f56108b26c 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -19,24 +19,24 @@ use hir_def::{ resolver::resolver_for_expr, ConstParamId, FieldId, ItemContainerId, Lookup, }; -use hir_expand::{name, name::Name}; +use hir_expand::name::Name; use stdx::always; use syntax::ast::RangeOp; use crate::{ autoderef::{self, Autoderef}, consteval, - infer::{coerce::CoerceMany, find_continuable, path, BreakableKind}, + infer::{coerce::CoerceMany, find_continuable, BreakableKind}, lower::{ const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode, }, mapping::{from_chalk, ToChalk}, method_resolution::{self, lang_names_for_bin_op, VisibleFromModule}, primitive::{self, UintTy}, - static_lifetime, to_assoc_type_id, to_chalk_trait_id, + static_lifetime, to_chalk_trait_id, utils::{generics, Generics}, - AdtId, AliasEq, AliasTy, Binders, CallableDefId, FnPointer, FnSig, FnSubst, Interner, - ProjectionTy, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, + AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar, + Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, }; use super::{ @@ -564,29 +564,9 @@ impl<'a> InferenceContext<'a> { let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); self.resolve_associated_type(inner_ty, self.resolve_future_future_output()) } - &Expr::Try { expr } => { - let inner_ty = self.infer_expr_inner(expr, &Expectation::none()); - match self.resolve_try_impl_for(inner_ty.clone()) { - Some((_, Some((output, residual)))) => { - if let Some((_trait, false)) = - self.implements_from_residual(self.return_ty.clone(), residual) - { - self.push_diagnostic(InferenceDiagnostic::IncorrectTryTarget { - expr: tgt_expr, - }); - } - output - } - Some((trait_, None)) => { - self.push_diagnostic(InferenceDiagnostic::DoesNotImplement { - expr, - trait_, - ty: inner_ty, - }); - self.err_ty() - } - None => self.err_ty(), - } + Expr::Try { expr } => { + let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); + self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()) } Expr::Cast { expr, type_ref } => { // FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary) @@ -1550,67 +1530,4 @@ impl<'a> InferenceContext<'a> { let ctx = self.breakables.pop().expect("breakable stack broken"); (ctx.may_break.then(|| ctx.coerce.complete()), res) } - - /// Check whether `ty` implements `FromResidual<r>` - fn implements_from_residual(&mut self, ty: Ty, r: Ty) -> Option<(hir_def::TraitId, bool)> { - let from_residual_trait = self - .resolver - .resolve_known_trait(self.db.upcast(), &(super::path![core::ops::FromResidual]))?; - let r = GenericArgData::Ty(r).intern(Interner); - let b = TyBuilder::trait_ref(self.db, from_residual_trait); - if b.remaining() != 2 { - return Some((from_residual_trait, false)); - } - let trait_ref = b.push(ty).push(r).build(); - Some((from_residual_trait, self.table.try_obligation(trait_ref.cast(Interner)).is_some())) - } - - fn resolve_try_impl_for(&mut self, ty: Ty) -> Option<(hir_def::TraitId, Option<(Ty, Ty)>)> { - let path = path![core::ops::Try]; - let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; - - let trait_ref = TyBuilder::trait_ref(self.db, trait_).push(ty).build(); - let substitution = trait_ref.substitution.clone(); - self.push_obligation(trait_ref.clone().cast(Interner)); - - let trait_data = self.db.trait_data(trait_); - let output = trait_data.associated_type_by_name(&name![Output]); - let residual = trait_data.associated_type_by_name(&name![Residual]); - - let output_ty = match output { - Some(output) => { - let output_ty = self.table.new_type_var(); - let alias_eq = AliasEq { - alias: AliasTy::Projection(ProjectionTy { - associated_ty_id: to_assoc_type_id(output), - substitution: substitution.clone(), - }), - ty: output_ty.clone(), - }; - self.push_obligation(alias_eq.cast(Interner)); - output_ty - } - None => self.err_ty(), - }; - let residual_ty = match residual { - Some(residual) => { - let residual_ty = self.table.new_type_var(); - let alias_eq = AliasEq { - alias: AliasTy::Projection(ProjectionTy { - associated_ty_id: to_assoc_type_id(residual), - substitution, - }), - ty: residual_ty.clone(), - }; - self.push_obligation(alias_eq.cast(Interner)); - residual_ty - } - None => self.err_ty(), - }; - // FIXME: We are doing the work twice here I think? - Some(( - trait_, - self.table.try_obligation(trait_ref.cast(Interner)).map(|_| (output_ty, residual_ty)), - )) - } } |