]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / hir-ty / src / infer / cast.rs
CommitLineData
add651ee
FG
1//! Type cast logic. Basically coercion + additional casts.
2
3use crate::{infer::unify::InferenceTable, Interner, Ty, TyExt, TyKind};
4
5#[derive(Clone, Debug)]
6pub(super) struct CastCheck {
7 expr_ty: Ty,
8 cast_ty: Ty,
9}
10
11impl CastCheck {
12 pub(super) fn new(expr_ty: Ty, cast_ty: Ty) -> Self {
13 Self { expr_ty, cast_ty }
14 }
15
16 pub(super) fn check(self, table: &mut InferenceTable<'_>) {
17 // FIXME: This function currently only implements the bits that influence the type
18 // inference. We should return the adjustments on success and report diagnostics on error.
19 let expr_ty = table.resolve_ty_shallow(&self.expr_ty);
20 let cast_ty = table.resolve_ty_shallow(&self.cast_ty);
21
22 if expr_ty.contains_unknown() || cast_ty.contains_unknown() {
23 return;
24 }
25
26 if table.coerce(&expr_ty, &cast_ty).is_ok() {
27 return;
28 }
29
30 if check_ref_to_ptr_cast(expr_ty, cast_ty, table) {
31 // Note that this type of cast is actually split into a coercion to a
32 // pointer type and a cast:
33 // &[T; N] -> *[T; N] -> *T
34 return;
35 }
36
37 // FIXME: Check other kinds of non-coercion casts and report error if any?
38 }
39}
40
41fn check_ref_to_ptr_cast(expr_ty: Ty, cast_ty: Ty, table: &mut InferenceTable<'_>) -> bool {
781aab86
FG
42 let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else {
43 return false;
44 };
45 let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else {
46 return false;
47 };
48 let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else {
49 return false;
50 };
add651ee
FG
51 table.coerce(expr_elt_ty, cast_inner_ty).is_ok()
52}