be even more precise about "cast" vs "coercion"

This commit is contained in:
Lukas Markeffsky 2024-09-15 19:35:06 +02:00
parent 5e60d1f87e
commit bd31e3ed70
90 changed files with 291 additions and 233 deletions

View File

@ -333,8 +333,10 @@ pub(crate) fn add_explanation_to_diagnostic(
}
}
if let ConstraintCategory::Cast { is_coercion: true, unsize_to: Some(unsize_ty) } =
category
if let ConstraintCategory::Cast {
is_implicit_coercion: true,
unsize_to: Some(unsize_ty),
} = category
{
self.add_object_lifetime_default_note(tcx, err, unsize_ty);
}
@ -742,7 +744,7 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
// If we see an unsized cast, then if it is our data we should check
// whether it is being cast to a trait object.
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
CastKind::PointerCoercion(PointerCoercion::Unsize, _),
operand,
ty,
) => {

View File

@ -47,8 +47,8 @@ fn description(&self) -> &'static str {
ConstraintCategory::Yield => "yielding this value ",
ConstraintCategory::UseAsConst => "using this value as a constant ",
ConstraintCategory::UseAsStatic => "using this value as a static ",
ConstraintCategory::Cast { is_coercion: false, .. } => "cast ",
ConstraintCategory::Cast { is_coercion: true, .. } => "coercion ",
ConstraintCategory::Cast { is_implicit_coercion: false, .. } => "cast ",
ConstraintCategory::Cast { is_implicit_coercion: true, .. } => "coercion ",
ConstraintCategory::CallArgument(_) => "argument ",
ConstraintCategory::TypeAnnotation => "type annotation ",
ConstraintCategory::ClosureBounds => "closure body ",

View File

@ -1975,8 +1975,9 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
Rvalue::Cast(cast_kind, op, ty) => {
self.check_operand(op, location);
match cast_kind {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
match *cast_kind {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => {
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
let src_sig = op.ty(body, tcx).fn_sig(tcx);
// HACK: This shouldn't be necessary... We can remove this when we actually
@ -2007,7 +2008,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
self.prove_predicate(
ty::ClauseKind::WellFormed(src_ty.into()),
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
);
let src_ty = self.normalize(src_ty, location);
@ -2015,7 +2016,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
src_ty,
*ty,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
) {
span_mirbug!(
self,
@ -2036,7 +2037,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
self.prove_predicate(
ty::ClauseKind::WellFormed(src_ty.into()),
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
);
// The type that we see in the fcx is like
@ -2049,7 +2050,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
src_ty,
*ty,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
) {
span_mirbug!(
self,
@ -2062,19 +2063,23 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
}
}
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(safety)) => {
CastKind::PointerCoercion(
PointerCoercion::ClosureFnPointer(safety),
coercion_source,
) => {
let sig = match op.ty(body, tcx).kind() {
ty::Closure(_, args) => args.as_closure().sig(),
_ => bug!(),
};
let ty_fn_ptr_from =
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, safety));
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
if let Err(terr) = self.sub_types(
ty_fn_ptr_from,
*ty,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
) {
span_mirbug!(
self,
@ -2087,7 +2092,10 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
}
}
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
CastKind::PointerCoercion(
PointerCoercion::UnsafeFnPointer,
coercion_source,
) => {
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
@ -2099,11 +2107,12 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
if let Err(terr) = self.sub_types(
ty_fn_ptr_from,
*ty,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
) {
span_mirbug!(
self,
@ -2116,7 +2125,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
}
}
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
CastKind::PointerCoercion(PointerCoercion::Unsize, coercion_source) => {
let &ty = ty;
let trait_ref = ty::TraitRef::new(
tcx,
@ -2124,23 +2133,21 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
[op.ty(body, tcx), ty],
);
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
let unsize_to = tcx.fold_regions(ty, |r, _| {
if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r }
});
self.prove_trait_ref(
trait_ref,
location.to_locations(),
ConstraintCategory::Cast {
is_coercion: true,
unsize_to: Some(tcx.fold_regions(ty, |r, _| {
if let ty::ReVar(_) = r.kind() {
tcx.lifetimes.re_erased
} else {
r
}
})),
is_implicit_coercion,
unsize_to: Some(unsize_to),
},
);
}
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
CastKind::PointerCoercion(PointerCoercion::DynStar, coercion_source) => {
// get the constraints from the target type (`dyn* Clone`)
//
// apply them to prove that the source type `Foo` implements `Clone` etc
@ -2151,12 +2158,13 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
let self_ty = op.ty(body, tcx);
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
self.prove_predicates(
existential_predicates
.iter()
.map(|predicate| predicate.with_self_ty(tcx, self_ty)),
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
);
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
@ -2167,11 +2175,14 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
self.prove_predicate(
outlives_predicate,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
);
}
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer,
coercion_source,
) => {
let ty::RawPtr(ty_from, hir::Mutability::Mut) = op.ty(body, tcx).kind()
else {
span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,);
@ -2181,11 +2192,12 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,);
return;
};
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
if let Err(terr) = self.sub_types(
*ty_from,
*ty_to,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
) {
span_mirbug!(
self,
@ -2198,7 +2210,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
}
}
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => {
let ty_from = op.ty(body, tcx);
let opt_ty_elem_mut = match ty_from.kind() {
@ -2243,11 +2255,12 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
return;
}
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
if let Err(terr) = self.sub_types(
*ty_elem,
*ty_to,
location.to_locations(),
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
) {
span_mirbug!(
self,
@ -2429,7 +2442,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
dst_obj,
location.to_locations(),
ConstraintCategory::Cast {
is_coercion: false,
is_implicit_coercion: false,
unsize_to: None,
},
)

View File

@ -652,7 +652,7 @@ fn codegen_stmt<'tcx>(
lval.write_cvalue(fx, res);
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _),
ref operand,
to_ty,
) => {
@ -677,7 +677,7 @@ fn codegen_stmt<'tcx>(
}
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer),
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _),
ref operand,
to_ty,
) => {
@ -688,6 +688,7 @@ fn codegen_stmt<'tcx>(
Rvalue::Cast(
CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
_,
),
..,
) => {
@ -741,7 +742,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
}
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _),
ref operand,
_to_ty,
) => {
@ -763,7 +764,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
}
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
CastKind::PointerCoercion(PointerCoercion::Unsize, _),
ref operand,
_to_ty,
) => {
@ -771,7 +772,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
crate::unsize::coerce_unsized_into(fx, operand, lval);
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::DynStar),
CastKind::PointerCoercion(PointerCoercion::DynStar, _),
ref operand,
_,
) => {

View File

@ -34,7 +34,7 @@ pub(crate) fn codegen_rvalue(
}
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _),
ref source,
_,
) => {
@ -465,7 +465,7 @@ pub(crate) fn codegen_rvalue_operand(
let lladdr = bx.ptrtoint(llptr, llcast_ty);
OperandValue::Immediate(lladdr)
}
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => {
match *operand.layout.ty.kind() {
ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr(
@ -481,7 +481,7 @@ pub(crate) fn codegen_rvalue_operand(
_ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty),
}
}
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => {
match *operand.layout.ty.kind() {
ty::Closure(def_id, args) => {
let instance = Instance::resolve_closure(
@ -496,11 +496,11 @@ pub(crate) fn codegen_rvalue_operand(
_ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty),
}
}
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
// This is a no-op at the LLVM level.
operand.val
}
mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => {
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) => {
assert!(bx.cx().is_backend_scalar_pair(cast));
let (lldata, llextra) = operand.val.pointer_parts();
let (lldata, llextra) =
@ -508,7 +508,7 @@ pub(crate) fn codegen_rvalue_operand(
OperandValue::Pair(lldata, llextra)
}
mir::CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _
) => {
bug!("{kind:?} is for borrowck, and should never appear in codegen");
}
@ -526,7 +526,7 @@ pub(crate) fn codegen_rvalue_operand(
bug!("unexpected non-pair operand");
}
}
mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => {
mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _) => {
let (lldata, llextra) = operand.val.pointer_parts();
let (lldata, llextra) =
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);

View File

@ -440,6 +440,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
| PointerCoercion::UnsafeFnPointer
| PointerCoercion::ClosureFnPointer(_)
| PointerCoercion::ReifyFnPointer,
_,
),
_,
_,
@ -448,7 +449,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar),
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar, _),
_,
_,
) => {

View File

@ -32,7 +32,7 @@ pub fn cast(
if cast_ty == dest.layout.ty { dest.layout } else { self.layout_of(cast_ty)? };
// FIXME: In which cases should we trigger UB when the source is uninit?
match cast_kind {
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
CastKind::PointerCoercion(PointerCoercion::Unsize, _) => {
self.unsize_into(src, cast_layout, dest)?;
}
@ -68,11 +68,12 @@ pub fn cast(
CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
_,
) => {
bug!("{cast_kind:?} casts are for borrowck only, not runtime MIR");
}
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
@ -94,7 +95,7 @@ pub fn cast(
}
}
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
let src = self.read_immediate(src)?;
match cast_ty.kind() {
ty::FnPtr(..) => {
@ -105,7 +106,7 @@ pub fn cast(
}
}
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
@ -125,7 +126,7 @@ pub fn cast(
}
}
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
CastKind::PointerCoercion(PointerCoercion::DynStar, _) => {
if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src.layout.ty, data)?;

View File

@ -234,8 +234,8 @@ pub enum ConstraintCategory<'tcx> {
UseAsStatic,
TypeAnnotation,
Cast {
/// Whether this cast is a coercion.
is_coercion: bool,
/// Whether this cast is a coercion that was automatically inserted by the compiler.
is_implicit_coercion: bool,
/// Whether this is an unsizing coercion and if yes, this contains the target type.
/// Region variables are erased to ReErased.
#[derive_where(skip)]

View File

@ -432,7 +432,7 @@ pub fn is_safe_to_remove(&self) -> bool {
| CastKind::IntToFloat
| CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::PointerCoercion(_)
| CastKind::PointerCoercion(_, _)
| CastKind::PointerWithExposedProvenance
| CastKind::Transmute,
_,

View File

@ -579,7 +579,7 @@ pub struct CopyNonOverlapping<'tcx> {
pub count: Operand<'tcx>,
}
/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics
/// Represents how a [`TerminatorKind::Call`] was constructed, used for diagnostics.
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum CallSource {
@ -1403,7 +1403,7 @@ pub enum CastKind {
/// * [`PointerCoercion::MutToConstPointer`]
///
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
PointerCoercion(PointerCoercion),
PointerCoercion(PointerCoercion, CoercionSource),
IntToInt,
FloatToInt,
FloatToFloat,
@ -1419,6 +1419,15 @@ pub enum CastKind {
Transmute,
}
/// Represents how a [`CastKind::PointerCoercion`] was constructed, used for diagnostics.
#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum CoercionSource {
/// The coercion was manually written by the user with an `as` cast.
AsCast,
/// The coercion was automatically inserted by the compiler.
Implicit,
}
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum AggregateKind<'tcx> {

View File

@ -338,6 +338,8 @@ pub enum ExprKind<'tcx> {
PointerCoercion {
cast: PointerCoercion,
source: ExprId,
/// Whether this coercion is written with an `as` cast in the source code.
is_from_as_cast: bool,
},
/// A `loop` expression.
Loop {

View File

@ -68,7 +68,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
Use { source } => visitor.visit_expr(&visitor.thir()[source]),
NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
PointerCoercion { source, cast: _, is_from_as_cast: _ } => {
visitor.visit_expr(&visitor.thir()[source])
}
Let { expr, ref pat } => {
visitor.visit_expr(&visitor.thir()[expr]);
visitor.visit_pat(pat);

View File

@ -292,7 +292,7 @@ pub(crate) fn as_rvalue(
let cast_kind = mir_cast_kind(ty, expr.ty);
block.and(Rvalue::Cast(cast_kind, source, expr.ty))
}
ExprKind::PointerCoercion { cast, source } => {
ExprKind::PointerCoercion { cast, source, is_from_as_cast } => {
let source = unpack!(
block = this.as_operand(
block,
@ -302,7 +302,9 @@ pub(crate) fn as_rvalue(
NeedsTemporary::No
)
);
block.and(Rvalue::Cast(CastKind::PointerCoercion(cast), source, expr.ty))
let origin =
if is_from_as_cast { CoercionSource::AsCast } else { CoercionSource::Implicit };
block.and(Rvalue::Cast(CastKind::PointerCoercion(cast, origin), source, expr.ty))
}
ExprKind::Array { ref fields } => {
// (*) We would (maybe) be closer to codegen if we

View File

@ -407,7 +407,10 @@ fn non_scalar_compare(
source_info,
temp,
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
CastKind::PointerCoercion(
PointerCoercion::Unsize,
CoercionSource::Implicit,
),
Operand::Copy(val),
ty,
),
@ -421,7 +424,10 @@ fn non_scalar_compare(
source_info,
slice,
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
CastKind::PointerCoercion(
PointerCoercion::Unsize,
CoercionSource::Implicit,
),
expect,
ty,
),

View File

@ -104,15 +104,28 @@ fn apply_adjustment(
};
let kind = match adjustment.kind {
Adjust::Pointer(PointerCoercion::Unsize) => {
adjust_span(&mut expr);
ExprKind::PointerCoercion {
cast: PointerCoercion::Unsize,
source: self.thir.exprs.push(expr),
}
}
Adjust::Pointer(cast) => {
ExprKind::PointerCoercion { cast, source: self.thir.exprs.push(expr) }
if cast == PointerCoercion::Unsize {
adjust_span(&mut expr);
}
let is_from_as_cast = if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Cast(..),
span: cast_span,
..
}) = self.tcx.parent_hir_node(hir_expr.hir_id)
{
// Use the whole span of the `x as T` expression for the coercion.
span = *cast_span;
true
} else {
false
};
ExprKind::PointerCoercion {
cast,
source: self.thir.exprs.push(expr),
is_from_as_cast,
}
}
Adjust::NeverToAny if adjustment.target.is_never() => return expr,
Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
@ -235,6 +248,7 @@ fn mirror_expr_cast(
ExprKind::PointerCoercion {
source: self.mirror_expr(source),
cast: PointerCoercion::ArrayToPointer,
is_from_as_cast: true,
}
} else if let hir::ExprKind::Path(ref qpath) = source.kind
&& let res = self.typeck_results().qpath_res(qpath, source.hir_id)

View File

@ -292,9 +292,14 @@ fn print_expr_kind(&mut self, expr_kind: &ExprKind<'tcx>, depth_lvl: usize) {
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
PointerCoercion { cast, source } => {
PointerCoercion { cast, is_from_as_cast, source } => {
print_indented!(self, "Pointer {", depth_lvl);
print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1);
print_indented!(
self,
format!("is_from_as_cast: {:?}", is_from_as_cast),
depth_lvl + 1
);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);

View File

@ -42,6 +42,7 @@ fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
ref mut cast_kind @ CastKind::PointerCoercion(
PointerCoercion::ArrayToPointer
| PointerCoercion::MutToConstPointer,
_,
),
..,
),

View File

@ -189,7 +189,7 @@ fn handle_assign(
}
}
Rvalue::Cast(
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize),
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _),
operand,
_,
) => {

View File

@ -576,7 +576,7 @@ fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
}
value.offset(Size::ZERO, to, &self.ecx).ok()?
}
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) => {
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) => {
let src = self.evaluated[value].as_ref()?;
let to = self.ecx.layout_of(to).ok()?;
let dest = self.ecx.allocate(to, MemoryKind::Stack).ok()?;
@ -593,7 +593,7 @@ fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
ret.into()
}
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => {
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer, _) => {
let src = self.evaluated[value].as_ref()?;
let src = self.ecx.read_immediate(src).ok()?;
let to = self.ecx.layout_of(to).ok()?;
@ -1138,7 +1138,7 @@ fn simplify_unary(
(
UnOp::PtrMetadata,
Value::Cast {
kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize),
kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _),
from,
to,
..
@ -1342,7 +1342,7 @@ fn simplify_cast(
return Some(value);
}
if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_)) = kind {
if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_), _) = kind {
// Each reification of a generic fn may get a different pointer.
// Do not try to merge them.
return self.new_opaque();
@ -1429,7 +1429,7 @@ fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Optio
// We have an unsizing cast, which assigns the length to fat pointer metadata.
if let Value::Cast { kind, from, to, .. } = self.get(inner)
&& let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) = kind
&& let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind
&& let Some(from) = from.builtin_deref(true)
&& let ty::Array(_, len) = from.kind()
&& let Some(to) = to.builtin_deref(true)

View File

@ -70,8 +70,8 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
match *rvalue {
// We need to detect unsizing casts that required vtables.
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::Unsize)
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar),
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _)
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _),
ref operand,
target_ty,
) => {
@ -96,7 +96,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
}
// Similarly, record closures that are turned into function pointers.
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _),
ref operand,
_,
) => {
@ -106,7 +106,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
}
// And finally, function pointer reification casts.
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _),
ref operand,
_,
) => {

View File

@ -7,9 +7,10 @@
use rustc_hir::lang_items::LangItem;
use rustc_index::{Idx, IndexVec};
use rustc_middle::mir::{
BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local,
LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue, SourceInfo, Statement,
StatementKind, Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason,
BasicBlock, BasicBlockData, Body, CallSource, CastKind, CoercionSource, Const, ConstOperand,
ConstValue, Local, LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue,
SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnwindAction,
UnwindTerminateReason,
};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr};
@ -329,7 +330,7 @@ fn put_self(&mut self) {
fn put_array_as_slice(&mut self, elem_ty: Ty<'tcx>) {
let slice_ptr_ty = Ty::new_mut_ptr(self.tcx, Ty::new_slice(self.tcx, elem_ty));
self.put_temp_rvalue(Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
CastKind::PointerCoercion(PointerCoercion::Unsize, CoercionSource::Implicit),
Operand::Copy(Self::SELF_PTR.into()),
slice_ptr_ty,
))

View File

@ -1130,7 +1130,7 @@ macro_rules! check_kinds {
match kind {
// FIXME: Add Checks for these
CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {}
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => {
// FIXME: check signature compatibility.
check_kinds!(
op_ty,
@ -1143,7 +1143,7 @@ macro_rules! check_kinds {
ty::FnPtr(..)
);
}
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
// FIXME: check safety and signature compatibility.
check_kinds!(
op_ty,
@ -1156,7 +1156,7 @@ macro_rules! check_kinds {
ty::FnPtr(..)
);
}
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => {
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..), _) => {
// FIXME: check safety, captures, and signature compatibility.
check_kinds!(
op_ty,
@ -1169,7 +1169,7 @@ macro_rules! check_kinds {
ty::FnPtr(..)
);
}
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer, _) => {
// FIXME: check same pointee?
check_kinds!(
op_ty,
@ -1185,7 +1185,7 @@ macro_rules! check_kinds {
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
}
}
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, _) => {
// FIXME: Check pointee types
check_kinds!(
op_ty,
@ -1201,11 +1201,11 @@ macro_rules! check_kinds {
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
}
}
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
CastKind::PointerCoercion(PointerCoercion::Unsize, _) => {
// This is used for all `CoerceUnsized` types,
// not just pointers/references, so is hard to check.
}
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
CastKind::PointerCoercion(PointerCoercion::DynStar, _) => {
// FIXME(dyn-star): make sure nothing needs to be done here.
}
CastKind::IntToInt | CastKind::IntToFloat => {

View File

@ -665,8 +665,8 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
// have to instantiate all methods of the trait being cast to, so we
// can build the appropriate vtable.
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::Unsize)
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar),
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _)
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _),
ref operand,
target_ty,
) => {
@ -694,7 +694,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
}
}
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _),
ref operand,
_,
) => {
@ -705,7 +705,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
visit_fn_use(self.tcx, fn_ty, false, span, self.used_items);
}
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _),
ref operand,
_,
) => {

View File

@ -286,8 +286,8 @@ fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
match self {
PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
PointerCoercion(PointerCoercion::DynStar) => stable_mir::mir::CastKind::DynStar,
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
PointerCoercion(PointerCoercion::DynStar, _) => stable_mir::mir::CastKind::DynStar,
PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
IntToInt => stable_mir::mir::CastKind::IntToInt,
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,

View File

@ -123,7 +123,7 @@ fn check_rvalue<'tcx>(
| CastKind::FloatToFloat
| CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer),
| CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _),
operand,
_,
) => check_operand(tcx, operand, span, body, msrv),
@ -131,12 +131,12 @@ fn check_rvalue<'tcx>(
CastKind::PointerCoercion(
PointerCoercion::UnsafeFnPointer
| PointerCoercion::ClosureFnPointer(_)
| PointerCoercion::ReifyFnPointer,
| PointerCoercion::ReifyFnPointer, _
),
_,
_,
) => Err((span, "function pointer casts are not allowed in const fn".into())),
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), op, cast_ty) => {
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize, _), op, cast_ty) => {
let Some(pointee_ty) = cast_ty.builtin_deref(true) else {
// We cannot allow this for now.
return Err((span, "unsizing casts are only allowed for references right now".into()));
@ -154,7 +154,7 @@ fn check_rvalue<'tcx>(
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
Err((span, "casting pointers to ints is unstable in const fn".into()))
},
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar), _, _) => {
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar, _), _, _) => {
// FIXME(dyn-star)
unimplemented!()
},

View File

@ -2,7 +2,7 @@ error: Undefined Behavior: using vtable for `Baz` but `Bar` was expected
--> tests/fail/dyn-upcast-trait-mismatch.rs:LL:CC
|
LL | let _err = baz_fake as *const dyn Foo;
| ^^^^^^^^ using vtable for `Baz` but `Bar` was expected
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ using vtable for `Baz` but `Bar` was expected
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

View File

@ -150,7 +150,7 @@ fn address_of_reborrow() -> () {
StorageLive(_9);
StorageLive(_10);
_10 = &raw const (*_1);
_9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize));
_9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_10);
AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] });
_8 = copy _9;
@ -159,13 +159,13 @@ fn address_of_reborrow() -> () {
StorageLive(_11);
StorageLive(_12);
_12 = &raw const (*_1);
_11 = move _12 as *const [i32] (PointerCoercion(Unsize));
_11 = move _12 as *const [i32] (PointerCoercion(Unsize, AsCast));
StorageDead(_12);
StorageDead(_11);
StorageLive(_13);
StorageLive(_14);
_14 = &raw const (*_1);
_13 = move _14 as *const i32 (PointerCoercion(ArrayToPointer));
_13 = move _14 as *const i32 (PointerCoercion(ArrayToPointer, AsCast));
StorageDead(_14);
StorageDead(_13);
StorageLive(_15);
@ -179,14 +179,14 @@ fn address_of_reborrow() -> () {
StorageLive(_17);
StorageLive(_18);
_18 = &raw const (*_1);
_17 = move _18 as *const dyn std::marker::Send (PointerCoercion(Unsize));
_17 = move _18 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
StorageDead(_18);
FakeRead(ForLet(None), _17);
AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] });
StorageLive(_19);
StorageLive(_20);
_20 = &raw const (*_1);
_19 = move _20 as *const [i32] (PointerCoercion(Unsize));
_19 = move _20 as *const [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_20);
FakeRead(ForLet(None), _19);
AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] });
@ -204,7 +204,7 @@ fn address_of_reborrow() -> () {
StorageLive(_25);
StorageLive(_26);
_26 = &raw const (*_3);
_25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize));
_25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_26);
AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] });
_24 = copy _25;
@ -213,7 +213,7 @@ fn address_of_reborrow() -> () {
StorageLive(_27);
StorageLive(_28);
_28 = &raw const (*_3);
_27 = move _28 as *const [i32] (PointerCoercion(Unsize));
_27 = move _28 as *const [i32] (PointerCoercion(Unsize, AsCast));
StorageDead(_28);
StorageDead(_27);
StorageLive(_29);
@ -227,14 +227,14 @@ fn address_of_reborrow() -> () {
StorageLive(_31);
StorageLive(_32);
_32 = &raw const (*_3);
_31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize));
_31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
StorageDead(_32);
FakeRead(ForLet(None), _31);
AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] });
StorageLive(_33);
StorageLive(_34);
_34 = &raw const (*_3);
_33 = move _34 as *const [i32] (PointerCoercion(Unsize));
_33 = move _34 as *const [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_34);
FakeRead(ForLet(None), _33);
AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] });
@ -252,7 +252,7 @@ fn address_of_reborrow() -> () {
StorageLive(_39);
StorageLive(_40);
_40 = &raw mut (*_3);
_39 = move _40 as *mut dyn std::marker::Send (PointerCoercion(Unsize));
_39 = move _40 as *mut dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_40);
AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] });
_38 = copy _39;
@ -261,7 +261,7 @@ fn address_of_reborrow() -> () {
StorageLive(_41);
StorageLive(_42);
_42 = &raw mut (*_3);
_41 = move _42 as *mut [i32] (PointerCoercion(Unsize));
_41 = move _42 as *mut [i32] (PointerCoercion(Unsize, AsCast));
StorageDead(_42);
StorageDead(_41);
StorageLive(_43);
@ -275,14 +275,14 @@ fn address_of_reborrow() -> () {
StorageLive(_45);
StorageLive(_46);
_46 = &raw mut (*_3);
_45 = move _46 as *mut dyn std::marker::Send (PointerCoercion(Unsize));
_45 = move _46 as *mut dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
StorageDead(_46);
FakeRead(ForLet(None), _45);
AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] });
StorageLive(_47);
StorageLive(_48);
_48 = &raw mut (*_3);
_47 = move _48 as *mut [i32] (PointerCoercion(Unsize));
_47 = move _48 as *mut [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_48);
FakeRead(ForLet(None), _47);
AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] });

View File

@ -9,7 +9,7 @@ fn main() -> () {
bb0: {
StorageLive(_1);
_1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer));
_1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer, AsCast));
FakeRead(ForLet(None), _1);
_0 = const ();
StorageDead(_1);

View File

@ -39,7 +39,7 @@ fn main() -> () {
StorageLive(_3);
StorageLive(_4);
_4 = copy _1;
_3 = move _4 as *const Test (PointerCoercion(MutToConstPointer));
_3 = move _4 as *const Test (PointerCoercion(MutToConstPointer, Implicit));
StorageDead(_4);
_2 = Test::x(move _3) -> [return: bb2, unwind: bb4];
}
@ -64,7 +64,7 @@ fn main() -> () {
StorageLive(_11);
StorageLive(_12);
_12 = copy (*(*(*(*_5))));
_11 = move _12 as *const Test (PointerCoercion(MutToConstPointer));
_11 = move _12 as *const Test (PointerCoercion(MutToConstPointer, Implicit));
StorageDead(_12);
_10 = Test::x(move _11) -> [return: bb3, unwind: bb4];
}

View File

@ -187,7 +187,7 @@ static XXX: &Foo = {
StorageDead(_7);
_5 = &_6;
_4 = &(*_5);
_3 = move _4 as &[(u32, u32)] (PointerCoercion(Unsize));
_3 = move _4 as &[(u32, u32)] (PointerCoercion(Unsize, Implicit));
StorageDead(_4);
_2 = Foo { tup: const "hi", data: move _3 };
StorageDead(_3);

View File

@ -22,7 +22,7 @@
- _2 = &_3;
+ _6 = const BAR::promoted[0];
+ _2 = &(*_6);
_1 = move _2 as &[&i32] (PointerCoercion(Unsize));
_1 = move _2 as &[&i32] (PointerCoercion(Unsize, Implicit));
- StorageDead(_4);
StorageDead(_2);
_0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2];

View File

@ -22,7 +22,7 @@
- _2 = &_3;
+ _6 = const FOO::promoted[0];
+ _2 = &(*_6);
_1 = move _2 as &[&i32] (PointerCoercion(Unsize));
_1 = move _2 as &[&i32] (PointerCoercion(Unsize, Implicit));
- StorageDead(_4);
StorageDead(_2);
_0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2];

View File

@ -26,7 +26,7 @@
_9 = const main::promoted[0];
_3 = &(*_9);
_2 = &raw const (*_3);
_1 = move _2 as *const [i32] (PointerCoercion(Unsize));
_1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_2);
StorageDead(_3);
StorageLive(_5);

View File

@ -26,7 +26,7 @@
_9 = const main::promoted[0];
_3 = &(*_9);
_2 = &raw const (*_3);
_1 = move _2 as *const [i32] (PointerCoercion(Unsize));
_1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_2);
StorageDead(_3);
StorageLive(_5);

View File

@ -26,7 +26,7 @@
_9 = const main::promoted[0];
_3 = &(*_9);
_2 = &raw const (*_3);
_1 = move _2 as *const [i32] (PointerCoercion(Unsize));
_1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_2);
StorageDead(_3);
StorageLive(_5);

View File

@ -26,7 +26,7 @@
_9 = const main::promoted[0];
_3 = &(*_9);
_2 = &raw const (*_3);
_1 = move _2 as *const [i32] (PointerCoercion(Unsize));
_1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_2);
StorageDead(_3);
StorageLive(_5);

View File

@ -13,7 +13,7 @@
StorageLive(_1);
StorageLive(_2);
StorageLive(_3);
_3 = main as fn() (PointerCoercion(ReifyFnPointer));
_3 = main as fn() (PointerCoercion(ReifyFnPointer, AsCast));
_2 = move _3 as usize (PointerExposeProvenance);
StorageDead(_3);
_1 = move _2 as *const fn() (PointerWithExposedProvenance);

View File

@ -3,7 +3,7 @@
fn main() {
// CHECK-LABEL: fn main(
// CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer));
// CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer, AsCast));
// CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeProvenance);
// CHECK: [[back:_.*]] = move [[addr]] as *const fn() (PointerWithExposedProvenance);
let _ = main as usize as *const fn();

View File

@ -24,9 +24,9 @@
_9 = const main::promoted[0];
_4 = copy _9;
- _3 = copy _4;
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+ _3 = copy _9;
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize));
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -24,9 +24,9 @@
_9 = const main::promoted[0];
_4 = copy _9;
- _3 = copy _4;
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+ _3 = copy _9;
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize));
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -24,9 +24,9 @@
_9 = const main::promoted[0];
_4 = copy _9;
- _3 = copy _4;
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+ _3 = copy _9;
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize));
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -24,9 +24,9 @@
_9 = const main::promoted[0];
_4 = copy _9;
- _3 = copy _4;
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+ _3 = copy _9;
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize));
+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -7,7 +7,7 @@
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug a => [[a:_.*]];
// CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize));
// CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize, AsCast));
// CHECK: assert(const true,
// CHECK: [[a]] = const 2_u32;
let a = (&[1u32, 2, 3] as &[u32])[1];

View File

@ -47,7 +47,7 @@
StorageLive(_6);
StorageLive(_7);
_7 = &_2;
_6 = move _7 as &[i32] (PointerCoercion(Unsize));
_6 = move _7 as &[i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_7);
_5 = core::slice::<impl [i32]>::len(move _6) -> [return: bb1, unwind unreachable];
}

View File

@ -47,7 +47,7 @@
StorageLive(_6);
StorageLive(_7);
_7 = &_2;
_6 = move _7 as &[i32] (PointerCoercion(Unsize));
_6 = move _7 as &[i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_7);
_5 = core::slice::<impl [i32]>::len(move _6) -> [return: bb1, unwind continue];
}

View File

@ -89,7 +89,7 @@
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit));
+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
StorageDead(_4);
- _2 = Box::<[bool]>(copy _3, const std::alloc::Global);

View File

@ -93,7 +93,7 @@
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit));
+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
StorageDead(_4);
- _2 = Box::<[bool]>(copy _3, const std::alloc::Global);

View File

@ -89,7 +89,7 @@
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit));
+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
StorageDead(_4);
- _2 = Box::<[bool]>(copy _3, const std::alloc::Global);

View File

@ -93,7 +93,7 @@
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit));
+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
StorageDead(_4);
- _2 = Box::<[bool]>(copy _3, const std::alloc::Global);

View File

@ -32,7 +32,7 @@
_14 = const main::promoted[0];
_4 = copy _14;
_3 = copy _4;
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -32,7 +32,7 @@
_14 = const main::promoted[0];
_4 = copy _14;
_3 = copy _4;
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -32,7 +32,7 @@
_14 = const main::promoted[0];
_4 = copy _14;
_3 = copy _4;
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -32,7 +32,7 @@
_14 = const main::promoted[0];
_4 = copy _14;
_3 = copy _4;
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
StorageDead(_3);
StorageLive(_6);
_6 = const 1_usize;

View File

@ -16,7 +16,7 @@
+ nop;
StorageLive(_3);
_3 = &(*_1);
_2 = move _3 as &[i32] (PointerCoercion(Unsize));
_2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
StorageLive(_4);
_4 = &raw const (*_2);

View File

@ -16,7 +16,7 @@
+ nop;
StorageLive(_3);
_3 = &(*_1);
_2 = move _3 as &[i32] (PointerCoercion(Unsize));
_2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
StorageLive(_4);
_4 = &raw const (*_2);

View File

@ -37,7 +37,7 @@
bb0: {
- StorageLive(_1);
+ nop;
_1 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer));
_1 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast));
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
@ -50,7 +50,7 @@
StorageDead(_2);
- StorageLive(_4);
+ nop;
_4 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer));
_4 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast));
StorageLive(_5);
StorageLive(_6);
_6 = copy _4;
@ -69,9 +69,9 @@
+ nop;
StorageLive(_9);
- _9 = copy _7;
- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
StorageDead(_9);
StorageLive(_10);
StorageLive(_11);
@ -87,9 +87,9 @@
+ nop;
StorageLive(_13);
- _13 = copy _7;
- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
StorageDead(_13);
StorageLive(_14);
StorageLive(_15);

View File

@ -37,7 +37,7 @@
bb0: {
- StorageLive(_1);
+ nop;
_1 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer));
_1 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast));
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
@ -50,7 +50,7 @@
StorageDead(_2);
- StorageLive(_4);
+ nop;
_4 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer));
_4 = identity::<u8> as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast));
StorageLive(_5);
StorageLive(_6);
_6 = copy _4;
@ -69,9 +69,9 @@
+ nop;
StorageLive(_9);
- _9 = copy _7;
- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
StorageDead(_9);
StorageLive(_10);
StorageLive(_11);
@ -87,9 +87,9 @@
+ nop;
StorageLive(_13);
- _13 = copy _7;
- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
StorageDead(_13);
StorageLive(_14);
StorageLive(_15);

View File

@ -64,10 +64,10 @@
_44 = const wide_ptr_provenance::promoted[1];
_5 = &(*_44);
_4 = &(*_5);
_3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize));
_3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_4);
_2 = &raw const (*_3);
- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_2);
+ _1 = copy _2;
+ nop;
@ -82,10 +82,10 @@
_43 = const wide_ptr_provenance::promoted[0];
_11 = &(*_43);
_10 = &(*_11);
_9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize));
_9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_10);
_8 = &raw const (*_9);
- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_8);
+ _7 = copy _8;
+ nop;
@ -99,7 +99,7 @@
StorageLive(_16);
StorageLive(_17);
- _17 = copy _7;
- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _17 = copy _8;
+ _16 = copy _8;
StorageDead(_17);
@ -121,7 +121,7 @@
StorageLive(_21);
StorageLive(_22);
- _22 = copy _7;
- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _22 = copy _8;
+ _21 = copy _8;
StorageDead(_22);
@ -143,7 +143,7 @@
StorageLive(_26);
StorageLive(_27);
- _27 = copy _7;
- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _27 = copy _8;
+ _26 = copy _8;
StorageDead(_27);
@ -165,7 +165,7 @@
StorageLive(_31);
StorageLive(_32);
- _32 = copy _7;
- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _32 = copy _8;
+ _31 = copy _8;
StorageDead(_32);
@ -187,7 +187,7 @@
StorageLive(_36);
StorageLive(_37);
- _37 = copy _7;
- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _37 = copy _8;
+ _36 = copy _8;
StorageDead(_37);
@ -209,7 +209,7 @@
StorageLive(_41);
StorageLive(_42);
- _42 = copy _7;
- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _42 = copy _8;
+ _41 = copy _8;
StorageDead(_42);

View File

@ -64,10 +64,10 @@
_44 = const wide_ptr_provenance::promoted[1];
_5 = &(*_44);
_4 = &(*_5);
_3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize));
_3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_4);
_2 = &raw const (*_3);
- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_2);
+ _1 = copy _2;
+ nop;
@ -82,10 +82,10 @@
_43 = const wide_ptr_provenance::promoted[0];
_11 = &(*_43);
_10 = &(*_11);
_9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize));
_9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_10);
_8 = &raw const (*_9);
- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_8);
+ _7 = copy _8;
+ nop;
@ -99,7 +99,7 @@
StorageLive(_16);
StorageLive(_17);
- _17 = copy _7;
- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _17 = copy _8;
+ _16 = copy _8;
StorageDead(_17);
@ -121,7 +121,7 @@
StorageLive(_21);
StorageLive(_22);
- _22 = copy _7;
- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _22 = copy _8;
+ _21 = copy _8;
StorageDead(_22);
@ -143,7 +143,7 @@
StorageLive(_26);
StorageLive(_27);
- _27 = copy _7;
- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _27 = copy _8;
+ _26 = copy _8;
StorageDead(_27);
@ -165,7 +165,7 @@
StorageLive(_31);
StorageLive(_32);
- _32 = copy _7;
- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _32 = copy _8;
+ _31 = copy _8;
StorageDead(_32);
@ -187,7 +187,7 @@
StorageLive(_36);
StorageLive(_37);
- _37 = copy _7;
- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _37 = copy _8;
+ _36 = copy _8;
StorageDead(_37);
@ -209,7 +209,7 @@
StorageLive(_41);
StorageLive(_42);
- _42 = copy _7;
- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _42 = copy _8;
+ _41 = copy _8;
StorageDead(_42);

View File

@ -86,10 +86,10 @@
- _7 = &(*_1)[_8];
+ _7 = &(*_1)[0 of 1];
_6 = &(*_7);
_5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize));
_5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_6);
_4 = &raw const (*_5);
- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_4);
+ _3 = copy _4;
+ nop;
@ -115,10 +115,10 @@
- _15 = &(*_1)[_16];
+ _15 = &(*_1)[1 of 2];
_14 = &(*_15);
_13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize));
_13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_14);
_12 = &raw const (*_13);
- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_12);
+ _11 = copy _12;
+ nop;
@ -132,7 +132,7 @@
StorageLive(_22);
StorageLive(_23);
- _23 = copy _11;
- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _23 = copy _12;
+ _22 = copy _12;
StorageDead(_23);
@ -154,7 +154,7 @@
StorageLive(_27);
StorageLive(_28);
- _28 = copy _11;
- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _28 = copy _12;
+ _27 = copy _12;
StorageDead(_28);
@ -176,7 +176,7 @@
StorageLive(_32);
StorageLive(_33);
- _33 = copy _11;
- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _33 = copy _12;
+ _32 = copy _12;
StorageDead(_33);
@ -198,7 +198,7 @@
StorageLive(_37);
StorageLive(_38);
- _38 = copy _11;
- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _38 = copy _12;
+ _37 = copy _12;
StorageDead(_38);
@ -220,7 +220,7 @@
StorageLive(_42);
StorageLive(_43);
- _43 = copy _11;
- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _43 = copy _12;
+ _42 = copy _12;
StorageDead(_43);
@ -242,7 +242,7 @@
StorageLive(_47);
StorageLive(_48);
- _48 = copy _11;
- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _48 = copy _12;
+ _47 = copy _12;
StorageDead(_48);

View File

@ -86,10 +86,10 @@
- _7 = &(*_1)[_8];
+ _7 = &(*_1)[0 of 1];
_6 = &(*_7);
_5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize));
_5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_6);
_4 = &raw const (*_5);
- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_4);
+ _3 = copy _4;
+ nop;
@ -115,10 +115,10 @@
- _15 = &(*_1)[_16];
+ _15 = &(*_1)[1 of 2];
_14 = &(*_15);
_13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize));
_13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
StorageDead(_14);
_12 = &raw const (*_13);
- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
- StorageDead(_12);
+ _11 = copy _12;
+ nop;
@ -132,7 +132,7 @@
StorageLive(_22);
StorageLive(_23);
- _23 = copy _11;
- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _23 = copy _12;
+ _22 = copy _12;
StorageDead(_23);
@ -154,7 +154,7 @@
StorageLive(_27);
StorageLive(_28);
- _28 = copy _11;
- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _28 = copy _12;
+ _27 = copy _12;
StorageDead(_28);
@ -176,7 +176,7 @@
StorageLive(_32);
StorageLive(_33);
- _33 = copy _11;
- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _33 = copy _12;
+ _32 = copy _12;
StorageDead(_33);
@ -198,7 +198,7 @@
StorageLive(_37);
StorageLive(_38);
- _38 = copy _11;
- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _38 = copy _12;
+ _37 = copy _12;
StorageDead(_38);
@ -220,7 +220,7 @@
StorageLive(_42);
StorageLive(_43);
- _43 = copy _11;
- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _43 = copy _12;
+ _42 = copy _12;
StorageDead(_43);
@ -242,7 +242,7 @@
StorageLive(_47);
StorageLive(_48);
- _48 = copy _11;
- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize));
- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+ _48 = copy _12;
+ _47 = copy _12;
StorageDead(_48);

View File

@ -31,7 +31,7 @@
_4 = copy _2;
- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind unreachable];
+ StorageLive(_5);
+ _5 = copy _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize));
+ _5 = copy _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize, Implicit));
+ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _5) -> [return: bb2, unwind unreachable];
}

View File

@ -31,7 +31,7 @@
_4 = copy _2;
- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind continue];
+ StorageLive(_5);
+ _5 = copy _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize));
+ _5 = copy _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize, Implicit));
+ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _5) -> [return: bb2, unwind continue];
}

View File

@ -14,7 +14,7 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize));
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind unreachable];
+ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind unreachable];

View File

@ -14,7 +14,7 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize));
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind continue];
+ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind continue];

View File

@ -26,7 +26,7 @@
StorageLive(_4);
_4 = [copy _1, copy _1, copy _1];
_3 = &_4;
_2 = copy _3 as &[T] (PointerCoercion(Unsize));
_2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
nop;
nop;
goto -> bb2;

View File

@ -26,7 +26,7 @@
StorageLive(_4);
_4 = [copy _1, copy _1, copy _1];
_3 = &_4;
_2 = copy _3 as &[T] (PointerCoercion(Unsize));
_2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
nop;
nop;
goto -> bb2;

View File

@ -24,7 +24,7 @@
StorageLive(_6);
StorageLive(_7);
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
_6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_7);
- _5 = PtrMetadata(move _6);
+ _5 = const N;

View File

@ -24,7 +24,7 @@
StorageLive(_6);
StorageLive(_7);
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
_6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_7);
- _5 = PtrMetadata(move _6);
+ _5 = const N;

View File

@ -27,7 +27,7 @@
StorageLive(_6);
StorageLive(_7);
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
_6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_7);
- _5 = PtrMetadata(move _6);
+ _5 = const N;

View File

@ -27,7 +27,7 @@
StorageLive(_6);
StorageLive(_7);
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
_6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_7);
- _5 = PtrMetadata(move _6);
+ _5 = const N;

View File

@ -11,7 +11,7 @@
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_2 = move _3 as &[u8] (PointerCoercion(Unsize));
_2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
- _0 = PtrMetadata(move _2);
+ _0 = const N;

View File

@ -11,7 +11,7 @@
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_2 = move _3 as &[u8] (PointerCoercion(Unsize));
_2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
- _0 = PtrMetadata(move _2);
+ _0 = const N;

View File

@ -11,7 +11,7 @@
StorageLive(_2);
StorageLive(_3);
_3 = &_1;
_2 = move _3 as &[u8] (PointerCoercion(Unsize));
_2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
- _0 = PtrMetadata(move _2);
+ _0 = const N;

View File

@ -11,7 +11,7 @@
StorageLive(_2);
StorageLive(_3);
_3 = &_1;
_2 = move _3 as &[u8] (PointerCoercion(Unsize));
_2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
- _0 = PtrMetadata(move _2);
+ _0 = const N;

View File

@ -24,7 +24,7 @@
StorageLive(_4);
_4 = &_1;
_3 = &(*_4);
_2 = move _3 as &[u8] (PointerCoercion(Unsize));
_2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
StorageDead(_4);
StorageLive(_5);

View File

@ -24,7 +24,7 @@
StorageLive(_4);
_4 = &_1;
_3 = &(*_4);
_2 = move _3 as &[u8] (PointerCoercion(Unsize));
_2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
StorageDead(_4);
StorageLive(_5);

View File

@ -23,7 +23,7 @@
StorageLive(_4);
_4 = &mut _1;
_3 = &mut (*_4);
_2 = move _3 as &mut [u8] (PointerCoercion(Unsize));
_2 = move _3 as &mut [u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
StorageDead(_4);
StorageLive(_5);

View File

@ -23,7 +23,7 @@
StorageLive(_4);
_4 = &mut _1;
_3 = &mut (*_4);
_2 = move _3 as &mut [u8] (PointerCoercion(Unsize));
_2 = move _3 as &mut [u8] (PointerCoercion(Unsize, Implicit));
StorageDead(_3);
StorageDead(_4);
StorageLive(_5);

View File

@ -93,7 +93,7 @@
bb5: {
StorageLive(_15);
_16 = &_13;
_15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize));
_15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit));
_14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable;
}

View File

@ -93,7 +93,7 @@
bb5: {
StorageLive(_15);
_16 = &_13;
_15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize));
_15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit));
_14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable;
}

View File

@ -105,7 +105,7 @@ fn main() -> () {
StorageLive(_14);
_14 = {closure@main::{closure#0}};
Retag(_14);
_13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe)));
_13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe), Implicit));
StorageDead(_14);
StorageLive(_15);
StorageLive(_16);

View File

@ -105,7 +105,7 @@ fn main() -> () {
StorageLive(_14);
_14 = {closure@main::{closure#0}};
Retag(_14);
_13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe)));
_13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe), Implicit));
StorageDead(_14);
StorageLive(_15);
StorageLive(_16);

View File

@ -21,7 +21,7 @@
- StorageLive(_4);
- _4 = &_1;
- _3 = &(*_4);
- _2 = move _3 as &[u8] (PointerCoercion(Unsize));
- _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit));
- StorageDead(_3);
- StorageDead(_4);
- StorageDead(_2);

View File

@ -61,7 +61,7 @@
}
bb1: {
_3 = move _4 as std::boxed::Box<dyn std::fmt::Display> (PointerCoercion(Unsize));
_3 = move _4 as std::boxed::Box<dyn std::fmt::Display> (PointerCoercion(Unsize, Implicit));
StorageDead(_4);
_2 = Result::<Box<dyn std::fmt::Display>, <T as Err>::Err>::Ok(move _3);
StorageDead(_3);

View File

@ -7,7 +7,7 @@ LL | let refcell = RefCell::new(&mut foo);
| ^^^^^^^^ borrowed value does not live long enough
LL |
LL | let read = &refcell as &RefCell<dyn Read>;
| -------- coercion requires that `foo` is borrowed for `'static`
| ------------------------------ cast requires that `foo` is borrowed for `'static`
...
LL | }
| - `foo` dropped here while still borrowed
@ -19,7 +19,7 @@ LL | fn inner(mut foo: &[u8]) {
| - let's call the lifetime of this reference `'1`
...
LL | let read = &refcell as &RefCell<dyn Read>;
| ^^^^^^^^ coercion requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
error: aborting due to 2 previous errors

View File

@ -30,12 +30,11 @@ error[E0310]: the parameter type `U` may not live long enough
--> $DIR/regions-close-object-into-object-4.rs:9:5
|
LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `U` must be valid for the static lifetime...
| ...so that the type `U` will meet its required lifetime bounds
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider adding an explicit lifetime bound
|
LL | fn i<'a, T, U: 'static>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {

View File

@ -30,12 +30,11 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:5
|
LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider adding an explicit lifetime bound
|
LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {

View File

@ -2,7 +2,7 @@ error[E0310]: the parameter type `A` may not live long enough
--> $DIR/regions-close-over-type-parameter-1.rs:11:5
|
LL | Box::new(v) as Box<dyn SomeTrait + 'static>
| ^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `A` must be valid for the static lifetime...
| ...so that the type `A` will meet its required lifetime bounds
@ -18,7 +18,7 @@ error[E0309]: the parameter type `A` may not live long enough
LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
| -- the parameter type `A` must be valid for the lifetime `'b` as defined here...
LL | Box::new(v) as Box<dyn SomeTrait + 'b>
| ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|

View File

@ -4,7 +4,7 @@ error: lifetime may not live long enough
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
| - let's call the lifetime of this reference `'1`
LL | Box::new(value) as Box<dyn Any>
| ^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound
|