mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-22 09:55:06 +00:00
51 lines
1.6 KiB
Rust
51 lines
1.6 KiB
Rust
//! Type cast logic. Basically coercion + additional casts.
|
|
|
|
use crate::{infer::unify::InferenceTable, Interner, Ty, TyExt, TyKind};
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub(super) struct CastCheck {
|
|
expr_ty: Ty,
|
|
cast_ty: Ty,
|
|
}
|
|
|
|
impl CastCheck {
|
|
pub(super) fn new(expr_ty: Ty, cast_ty: Ty) -> Self {
|
|
Self { expr_ty, cast_ty }
|
|
}
|
|
|
|
pub(super) fn check(self, table: &mut InferenceTable<'_>) {
|
|
// FIXME: This function currently only implements the bits that influence the type
|
|
// inference. We should return the adjustments on success and report diagnostics on error.
|
|
let expr_ty = table.resolve_ty_shallow(&self.expr_ty);
|
|
let cast_ty = table.resolve_ty_shallow(&self.cast_ty);
|
|
|
|
if expr_ty.contains_unknown() || cast_ty.contains_unknown() {
|
|
return;
|
|
}
|
|
|
|
if table.coerce(&expr_ty, &cast_ty).is_ok() {
|
|
return;
|
|
}
|
|
|
|
if check_ref_to_ptr_cast(expr_ty, cast_ty, table) {
|
|
// Note that this type of cast is actually split into a coercion to a
|
|
// pointer type and a cast:
|
|
// &[T; N] -> *[T; N] -> *T
|
|
}
|
|
|
|
// FIXME: Check other kinds of non-coercion casts and report error if any?
|
|
}
|
|
}
|
|
|
|
fn check_ref_to_ptr_cast(expr_ty: Ty, cast_ty: Ty, table: &mut InferenceTable<'_>) -> bool {
|
|
let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else {
|
|
return false;
|
|
};
|
|
let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else {
|
|
return false;
|
|
};
|
|
let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else {
|
|
return false;
|
|
};
|
|
table.coerce(expr_elt_ty, cast_inner_ty).is_ok()
|
|
}
|