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 | 154 |
1 files changed, 41 insertions, 113 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 34fbaf6980..8732ca6a9a 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -8,8 +8,7 @@ use hir_def::{ expr_store::path::{GenericArgs as HirGenericArgs, Path}, hir::{ Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId, - InlineAsmKind, LabelId, Literal, Pat, PatId, RecordLitField, RecordSpread, Statement, - UnaryOp, + InlineAsmKind, LabelId, Pat, PatId, RecordLitField, RecordSpread, Statement, UnaryOp, }, resolver::ValueNs, signatures::VariantFields, @@ -27,7 +26,8 @@ use syntax::ast::RangeOp; use tracing::debug; use crate::{ - Adjust, Adjustment, CallableDefId, Rawness, Span, consteval, + Adjust, Adjustment, CallableDefId, Rawness, Span, + consteval::literal_ty, infer::{AllowTwoPhase, BreakableKind, coerce::CoerceMany, find_continuable, pat::PatOrigin}, lower::lower_mutability, method_resolution::{self, CandidateId, MethodCallee, MethodError}, @@ -648,7 +648,7 @@ impl<'db> InferenceContext<'_, 'db> { } else { let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes); let resolver_guard = - self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr); + self.resolver.update_to_inner_scope(self.db, self.store_owner, tgt_expr); self.inside_assignment = true; self.infer_top_pat(target, rhs_ty, PatOrigin::DestructuringAssignment); self.inside_assignment = false; @@ -758,106 +758,45 @@ impl<'db> InferenceContext<'_, 'db> { Expr::Array(Array::Repeat { initializer, repeat }) => { self.infer_array_repeat_expr(*initializer, *repeat, expected, tgt_expr) } - Expr::Literal(lit) => match lit { - Literal::Bool(..) => self.types.types.bool, - Literal::String(..) => self.types.types.static_str_ref, - Literal::ByteString(bs) => { - let byte_type = self.types.types.u8; - - let len = consteval::usize_const( - self.db, - Some(bs.len() as u128), - self.resolver.krate(), - ); - - let array_type = Ty::new_array_with_const_len(self.interner(), byte_type, len); - Ty::new_ref( - self.interner(), - self.types.regions.statik, - array_type, - Mutability::Not, - ) - } - Literal::CString(..) => Ty::new_ref( - self.interner(), - self.types.regions.statik, - self.lang_items.CStr.map_or_else( - || self.err_ty(), - |strukt| { - Ty::new_adt( - self.interner(), - strukt.into(), - self.types.empty.generic_args, - ) - }, - ), - Mutability::Not, - ), - Literal::Char(..) => self.types.types.char, - Literal::Int(_v, ty) => match ty { - Some(int_ty) => match int_ty { - hir_def::builtin_type::BuiltinInt::Isize => self.types.types.isize, - hir_def::builtin_type::BuiltinInt::I8 => self.types.types.i8, - hir_def::builtin_type::BuiltinInt::I16 => self.types.types.i16, - hir_def::builtin_type::BuiltinInt::I32 => self.types.types.i32, - hir_def::builtin_type::BuiltinInt::I64 => self.types.types.i64, - hir_def::builtin_type::BuiltinInt::I128 => self.types.types.i128, - }, - None => { - let expected_ty = expected.to_option(&mut self.table); - tracing::debug!(?expected_ty); - let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) { - Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty, - Some(TyKind::Char) => Some(self.types.types.u8), - Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => { - Some(self.types.types.usize) - } - _ => None, - }; - opt_ty.unwrap_or_else(|| self.table.next_int_var()) - } + Expr::Literal(lit) => literal_ty( + self.interner(), + lit, + |_| { + let expected_ty = expected.to_option(&self.table); + tracing::debug!(?expected_ty); + let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) { + Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty, + Some(TyKind::Char) => Some(self.types.types.u8), + Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => { + Some(self.types.types.usize) + } + _ => None, + }; + opt_ty.unwrap_or_else(|| self.table.next_int_var()) }, - Literal::Uint(_v, ty) => match ty { - Some(int_ty) => match int_ty { - hir_def::builtin_type::BuiltinUint::Usize => self.types.types.usize, - hir_def::builtin_type::BuiltinUint::U8 => self.types.types.u8, - hir_def::builtin_type::BuiltinUint::U16 => self.types.types.u16, - hir_def::builtin_type::BuiltinUint::U32 => self.types.types.u32, - hir_def::builtin_type::BuiltinUint::U64 => self.types.types.u64, - hir_def::builtin_type::BuiltinUint::U128 => self.types.types.u128, - }, - None => { - let expected_ty = expected.to_option(&mut self.table); - let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) { - Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty, - Some(TyKind::Char) => Some(self.types.types.u8), - Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => { - Some(self.types.types.usize) - } - _ => None, - }; - opt_ty.unwrap_or_else(|| self.table.next_int_var()) - } + |_| { + let expected_ty = expected.to_option(&self.table); + let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) { + Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty, + Some(TyKind::Char) => Some(self.types.types.u8), + Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => { + Some(self.types.types.usize) + } + _ => None, + }; + opt_ty.unwrap_or_else(|| self.table.next_int_var()) }, - Literal::Float(_v, ty) => match ty { - Some(float_ty) => match float_ty { - hir_def::builtin_type::BuiltinFloat::F16 => self.types.types.f16, - hir_def::builtin_type::BuiltinFloat::F32 => self.types.types.f32, - hir_def::builtin_type::BuiltinFloat::F64 => self.types.types.f64, - hir_def::builtin_type::BuiltinFloat::F128 => self.types.types.f128, - }, - None => { - let opt_ty = expected - .to_option(&mut self.table) - .filter(|ty| matches!(ty.kind(), TyKind::Float(_))); - opt_ty.unwrap_or_else(|| self.table.next_float_var()) - } + |_| { + let opt_ty = expected + .to_option(&self.table) + .filter(|ty| matches!(ty.kind(), TyKind::Float(_))); + opt_ty.unwrap_or_else(|| self.table.next_float_var()) }, - }, + ), Expr::Underscore => { // Underscore expression is an error, we render a specialized diagnostic // to let the user know what type is expected though. - let expected = expected.to_option(&mut self.table).unwrap_or_else(|| self.err_ty()); + let expected = expected.to_option(&self.table).unwrap_or_else(|| self.err_ty()); self.push_diagnostic(InferenceDiagnostic::TypedHole { expr: tgt_expr, expected: expected.store(), @@ -1317,7 +1256,7 @@ impl<'db> InferenceContext<'_, 'db> { } fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatId, scope_id: ExprId) -> Ty<'db> { - let g = self.resolver.update_to_inner_scope(self.db, self.owner, scope_id); + let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, scope_id); let ty = match self.infer_path(path, id) { Some((_, ty)) => ty, None => { @@ -1381,19 +1320,8 @@ impl<'db> InferenceContext<'_, 'db> { expr: ExprId, ) -> Ty<'db> { let interner = self.interner(); - let usize = self.types.types.usize; - let count_ct = match self.store[count] { - Expr::Underscore => { - self.write_expr_ty(count, usize); - self.table.next_const_var(count.into()) - } - _ => { - self.infer_expr(count, &Expectation::HasType(usize), ExprIsRead::Yes); - consteval::eval_to_const(count, self) - } - }; + let count_ct = self.create_body_anon_const(count, self.types.types.usize, true); let count = self.table.try_structurally_resolve_const(count.into(), count_ct); - let count = self.insert_const_vars_shallow(count); let uty = match expected { Expectation::HasType(uty) => uty.builtin_index(), @@ -1431,7 +1359,7 @@ impl<'db> InferenceContext<'_, 'db> { ) -> Ty<'db> { let element_ty = if !args.is_empty() { let coerce_to = expected - .to_option(&mut self.table) + .to_option(&self.table) .and_then(|uty| { self.table .resolve_vars_with_obligations(uty) @@ -1559,7 +1487,7 @@ impl<'db> InferenceContext<'_, 'db> { expected: &Expectation<'db>, ) -> Ty<'db> { let coerce_ty = expected.coercion_target_type(&mut self.table, expr.into()); - let g = self.resolver.update_to_inner_scope(self.db, self.owner, expr); + let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, expr); let (break_ty, ty) = self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| { |