Skip to content

Commit d45d82f

Browse files
author
Lukas Markeffsky
committed
[WIP] check ptr-to-ptr casts via traits
1 parent 4b6e46e commit d45d82f

File tree

1 file changed

+23
-2
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+23
-2
lines changed

compiler/rustc_hir_typeck/src/cast.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ use super::FnCtxt;
3232

3333
use crate::errors;
3434
use crate::type_error_struct;
35-
use hir::ExprKind;
35+
use hir::{ExprKind, LangItem};
3636
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
3737
use rustc_hir as hir;
38+
use rustc_infer::traits::Obligation;
3839
use rustc_macros::{TypeFoldable, TypeVisitable};
3940
use rustc_middle::mir::Mutability;
4041
use rustc_middle::ty::adjustment::AllowTwoPhase;
@@ -45,7 +46,8 @@ use rustc_session::lint;
4546
use rustc_span::def_id::{DefId, LOCAL_CRATE};
4647
use rustc_span::symbol::sym;
4748
use rustc_span::Span;
48-
use rustc_trait_selection::infer::InferCtxtExt;
49+
use rustc_trait_selection::infer::InferCtxtExt as _;
50+
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
4951

5052
/// Reifies a cast check to be checked once we have full type information for
5153
/// a function context.
@@ -787,6 +789,23 @@ impl<'a, 'tcx> CastCheck<'tcx> {
787789
) -> Result<(), CastError> {
788790
debug!(?expr, ?cast, "check_ptr_ptr_cast");
789791

792+
let meta_did = fcx.tcx.require_lang_item(LangItem::Metadata, Some(self.span));
793+
let expr_meta = Ty::new_projection(fcx.tcx, meta_did, [expr]);
794+
let cast_meta = Ty::new_projection(fcx.tcx, meta_did, [cast]);
795+
let expr_meta = fcx.normalize(self.span, expr_meta);
796+
let cast_meta = fcx.normalize(self.span, cast_meta);
797+
798+
let pred = ty::TraitRef::from_lang_item(
799+
fcx.tcx,
800+
LangItem::MetadataCast,
801+
self.span,
802+
[expr_meta, cast_meta],
803+
);
804+
let obligation = Obligation::new(fcx.tcx, fcx.misc(self.span), fcx.param_env, pred);
805+
if fcx.predicate_must_hold_modulo_regions(&obligation) {
806+
return Ok(());
807+
}
808+
790809
let expr_kind = fcx.pointer_kind(expr, self.span)?;
791810
let cast_kind = fcx.pointer_kind(cast, self.span)?;
792811

@@ -797,6 +816,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
797816

798817
// Cast to thin pointer is OK
799818
if cast_kind == PointerKind::Thin {
819+
fcx.tcx.dcx().span_err(self.span, format!("{pred}"));
800820
return Ok(());
801821
}
802822

@@ -812,6 +832,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
812832

813833
// vtable kinds must match
814834
if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) {
835+
fcx.tcx.dcx().span_err(self.span, format!("{pred}"));
815836
Ok(())
816837
} else {
817838
Err(CastError::DifferingKinds)

0 commit comments

Comments
 (0)