Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_ty/src/infer/closure.rs')
| -rw-r--r-- | crates/hir_ty/src/infer/closure.rs | 58 |
1 files changed, 25 insertions, 33 deletions
diff --git a/crates/hir_ty/src/infer/closure.rs b/crates/hir_ty/src/infer/closure.rs index 94dcff7f2a..d305cda70f 100644 --- a/crates/hir_ty/src/infer/closure.rs +++ b/crates/hir_ty/src/infer/closure.rs @@ -1,6 +1,6 @@ //! Inference of closure parameter types based on the closure's expected type. -use chalk_ir::{cast::Cast, AliasTy, FnSubst, WhereClause}; +use chalk_ir::{cast::Cast, AliasEq, AliasTy, FnSubst, WhereClause}; use hir_def::{expr::ExprId, HasModule}; use smallvec::SmallVec; @@ -42,46 +42,38 @@ impl InferenceContext<'_> { let fn_traits: SmallVec<[ChalkTraitId; 3]> = utils::fn_traits(self.db.upcast(), self.owner.module(self.db.upcast()).krate()) - .map(|tid| to_chalk_trait_id(tid)) + .map(to_chalk_trait_id) .collect(); let self_ty = TyKind::Error.intern(&Interner); let bounds = dyn_ty.bounds.clone().substitute(&Interner, &[self_ty.cast(&Interner)]); for bound in bounds.iter(&Interner) { // NOTE(skip_binders): the extracted types are rebound by the returned `FnPointer` - match bound.skip_binders() { - WhereClause::AliasEq(eq) => match &eq.alias { - AliasTy::Projection(projection) => { - let assoc_data = self.db.associated_ty_data(projection.associated_ty_id); - if !fn_traits.contains(&assoc_data.trait_id) { - return None; - } + if let WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection), ty }) = + bound.skip_binders() + { + let assoc_data = self.db.associated_ty_data(projection.associated_ty_id); + if !fn_traits.contains(&assoc_data.trait_id) { + return None; + } - // Skip `Self`, get the type argument. - let arg = projection.substitution.as_slice(&Interner).get(1)?; - if let Some(subst) = arg.ty(&Interner)?.as_tuple() { - let generic_args = subst.as_slice(&Interner); - let mut sig_tys = Vec::new(); - for arg in generic_args { - sig_tys.push(arg.ty(&Interner)?.clone()); - } - sig_tys.push(eq.ty.clone()); - - cov_mark::hit!(dyn_fn_param_informs_call_site_closure_signature); - return Some(FnPointer { - num_binders: bound.len(&Interner), - sig: FnSig { - abi: (), - safety: chalk_ir::Safety::Safe, - variadic: false, - }, - substitution: FnSubst(Substitution::from_iter(&Interner, sig_tys)), - }); - } + // Skip `Self`, get the type argument. + let arg = projection.substitution.as_slice(&Interner).get(1)?; + if let Some(subst) = arg.ty(&Interner)?.as_tuple() { + let generic_args = subst.as_slice(&Interner); + let mut sig_tys = Vec::new(); + for arg in generic_args { + sig_tys.push(arg.ty(&Interner)?.clone()); } - AliasTy::Opaque(_) => {} - }, - _ => {} + sig_tys.push(ty.clone()); + + cov_mark::hit!(dyn_fn_param_informs_call_site_closure_signature); + return Some(FnPointer { + num_binders: bound.len(&Interner), + sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, + substitution: FnSubst(Substitution::from_iter(&Interner, sig_tys)), + }); + } } } |