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.rs128
1 files changed, 9 insertions, 119 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 815a3d1459..4f3da82eaa 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -5,13 +5,13 @@ use std::{
mem,
};
-use chalk_ir::{DebruijnIndex, Mutability, TyVariableKind, cast::Cast, fold::Shift};
+use chalk_ir::{DebruijnIndex, Mutability, TyVariableKind, cast::Cast};
use either::Either;
use hir_def::{
BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
hir::{
- ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, ExprOrPatId,
- LabelId, Literal, Pat, PatId, Statement, UnaryOp,
+ ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, Expr, ExprId, ExprOrPatId, LabelId,
+ Literal, Pat, PatId, Statement, UnaryOp,
},
lang_item::{LangItem, LangItemTarget},
path::{GenericArg, GenericArgs, Path},
@@ -24,12 +24,10 @@ use syntax::ast::RangeOp;
use crate::{
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, DeclContext,
- DeclOrigin, FnAbi, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar, Substitution,
- TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind,
+ DeclOrigin, Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder,
+ TyExt, TyKind,
autoderef::{Autoderef, builtin_deref, deref_by_trait},
- consteval,
- db::{InternedClosure, InternedCoroutine},
- error_lifetime,
+ consteval, error_lifetime,
generics::{Generics, generics},
infer::{
BreakableKind,
@@ -378,116 +376,8 @@ impl InferenceContext<'_> {
None => self.result.standard_types.never.clone(),
}
}
- Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => {
- assert_eq!(args.len(), arg_types.len());
-
- let mut sig_tys = Vec::with_capacity(arg_types.len() + 1);
-
- // collect explicitly written argument types
- for arg_type in arg_types.iter() {
- let arg_ty = match arg_type {
- Some(type_ref) => self.make_body_ty(*type_ref),
- None => self.table.new_type_var(),
- };
- sig_tys.push(arg_ty);
- }
-
- // add return type
- let ret_ty = match ret_type {
- Some(type_ref) => self.make_body_ty(*type_ref),
- None => self.table.new_type_var(),
- };
- if let ClosureKind::Async = closure_kind {
- sig_tys.push(self.lower_async_block_type_impl_trait(ret_ty.clone(), *body));
- } else {
- sig_tys.push(ret_ty.clone());
- }
-
- let sig_ty = TyKind::Function(FnPointer {
- num_binders: 0,
- sig: FnSig {
- abi: FnAbi::RustCall,
- safety: chalk_ir::Safety::Safe,
- variadic: false,
- },
- substitution: FnSubst(
- Substitution::from_iter(Interner, sig_tys.iter().cloned())
- .shifted_in(Interner),
- ),
- })
- .intern(Interner);
-
- let (id, ty, resume_yield_tys) = match closure_kind {
- ClosureKind::Coroutine(_) => {
- // FIXME: report error when there are more than 1 parameter.
- let resume_ty = match sig_tys.first() {
- // When `sig_tys.len() == 1` the first type is the return type, not the
- // first parameter type.
- Some(ty) if sig_tys.len() > 1 => ty.clone(),
- _ => self.result.standard_types.unit.clone(),
- };
- let yield_ty = self.table.new_type_var();
-
- let subst = TyBuilder::subst_for_coroutine(self.db, self.owner)
- .push(resume_ty.clone())
- .push(yield_ty.clone())
- .push(ret_ty.clone())
- .build();
-
- let coroutine_id = self
- .db
- .intern_coroutine(InternedCoroutine(self.owner, tgt_expr))
- .into();
- let coroutine_ty = TyKind::Coroutine(coroutine_id, subst).intern(Interner);
-
- (None, coroutine_ty, Some((resume_ty, yield_ty)))
- }
- ClosureKind::Closure | ClosureKind::Async => {
- let closure_id =
- self.db.intern_closure(InternedClosure(self.owner, tgt_expr)).into();
- let closure_ty = TyKind::Closure(
- closure_id,
- TyBuilder::subst_for_closure(self.db, self.owner, sig_ty.clone()),
- )
- .intern(Interner);
- self.deferred_closures.entry(closure_id).or_default();
- if let Some(c) = self.current_closure {
- self.closure_dependencies.entry(c).or_default().push(closure_id);
- }
- (Some(closure_id), closure_ty, None)
- }
- };
-
- // Eagerly try to relate the closure type with the expected
- // type, otherwise we often won't have enough information to
- // infer the body.
- self.deduce_closure_type_from_expectations(tgt_expr, &ty, &sig_ty, expected);
-
- // Now go through the argument patterns
- for (arg_pat, arg_ty) in args.iter().zip(&sig_tys) {
- self.infer_top_pat(*arg_pat, arg_ty, None);
- }
-
- // FIXME: lift these out into a struct
- let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
- let prev_closure = mem::replace(&mut self.current_closure, id);
- let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
- let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(ret_ty));
- let prev_resume_yield_tys =
- mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
-
- self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
- this.infer_return(*body);
- });
-
- self.diverges = prev_diverges;
- self.return_ty = prev_ret_ty;
- self.return_coercion = prev_ret_coercion;
- self.current_closure = prev_closure;
- self.resume_yield_tys = prev_resume_yield_tys;
-
- ty
- }
+ Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self
+ .infer_closure(body, args, ret_type, arg_types, *closure_kind, tgt_expr, expected),
Expr::Call { callee, args, .. } => self.infer_call(tgt_expr, *callee, args, expected),
Expr::MethodCall { receiver, args, method_name, generic_args } => self
.infer_method_call(
@@ -2458,7 +2348,7 @@ impl InferenceContext<'_> {
}
}
- fn with_breakable_ctx<T>(
+ pub(super) fn with_breakable_ctx<T>(
&mut self,
kind: BreakableKind,
ty: Option<Ty>,