Auto merge of #103390 - compiler-errors:metadata-mod-regions, r=eholk
Check fat pointer metadata compatibility modulo regions Regions don't really mean anything anyways during hir typeck. If this `erase_regions` makes anyone nervous, it's probably equally valid to just equate the types using a type relation, but regardless we should _not_ be using strict type equality while region variables are present. Fixes #103384
This commit is contained in:
commit
9cdfe03b06
@ -33,6 +33,7 @@
|
||||
use crate::type_error_struct;
|
||||
use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::mir::Mutability;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::cast::{CastKind, CastTy};
|
||||
@ -67,7 +68,7 @@ pub struct CastCheck<'tcx> {
|
||||
/// The kind of pointer and associated metadata (thin, length or vtable) - we
|
||||
/// only allow casts between fat pointers if their metadata have the same
|
||||
/// kind.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, TypeVisitable, TypeFoldable)]
|
||||
enum PointerKind<'tcx> {
|
||||
/// No metadata attached, ie pointer to sized type or foreign type
|
||||
Thin,
|
||||
@ -76,11 +77,11 @@ enum PointerKind<'tcx> {
|
||||
/// Slice
|
||||
Length,
|
||||
/// The unsize info of this projection
|
||||
OfProjection(&'tcx ty::ProjectionTy<'tcx>),
|
||||
OfProjection(ty::ProjectionTy<'tcx>),
|
||||
/// The unsize info of this opaque ty
|
||||
OfOpaque(DefId, SubstsRef<'tcx>),
|
||||
/// The unsize info of this parameter
|
||||
OfParam(&'tcx ty::ParamTy),
|
||||
OfParam(ty::ParamTy),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -118,9 +119,9 @@ fn pointer_kind(
|
||||
// Pointers to foreign types are thin, despite being unsized
|
||||
ty::Foreign(..) => Some(PointerKind::Thin),
|
||||
// We should really try to normalize here.
|
||||
ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)),
|
||||
ty::Projection(pi) => Some(PointerKind::OfProjection(pi)),
|
||||
ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
|
||||
ty::Param(ref p) => Some(PointerKind::OfParam(p)),
|
||||
ty::Param(p) => Some(PointerKind::OfParam(p)),
|
||||
// Insufficient type information.
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
|
||||
|
||||
@ -909,7 +910,7 @@ fn check_ptr_ptr_cast(
|
||||
}
|
||||
|
||||
// vtable kinds must match
|
||||
if cast_kind == expr_kind {
|
||||
if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) {
|
||||
Ok(CastKind::PtrPtrCast)
|
||||
} else {
|
||||
Err(CastError::DifferingKinds)
|
||||
|
17
src/test/ui/cast/cast-pointee-projection.rs
Normal file
17
src/test/ui/cast/cast-pointee-projection.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// check-pass
|
||||
|
||||
trait Tag<'a> {
|
||||
type Type: ?Sized;
|
||||
}
|
||||
|
||||
trait IntoRaw: for<'a> Tag<'a> {
|
||||
fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type;
|
||||
}
|
||||
|
||||
impl<T: for<'a> Tag<'a>> IntoRaw for T {
|
||||
fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type {
|
||||
this as *mut T::Type
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user