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 | 128 |
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>, |