mirror of https://github.com/rust-lang/rust.git
Rollup merge of #130234 - lukas-code:ptr-cast-errors, r=WaffleLapkin
improve compile errors for invalid ptr-to-ptr casts with trait objects This is a follow-up to https://github.com/rust-lang/rust/pull/120248 to improve some of its error messages. 1. Make the borrowcheck error for "type annotation requires that x must outlive y" actually point at the type annotation, i.e. the type `T` in a `x as T` cast. This makes the error more consistent with other errors caused by type annotation in other places, such as ```text error: lifetime may not live long enough --> src/lib.rs:4:12 | 3 | fn bar(a: &i32) { | - let's call the lifetime of this reference `'1` 4 | let b: &'static i32 = a; | ^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` ``` 2. Don't say "cast" when we actually mean "coercion" and give borrowcheck errors from actual casts (which is currently just the check added in https://github.com/rust-lang/rust/pull/120248) a higher priority than ones from coercions. This can improve the errors for ptr-to-ptr cast between trait objects because they are are lowered as an upcast "unsizing" coercion if possible (which may be the identity upcast) followed by the actual cast. 3. Bring back the old "casting X as Y is invalid" message for type mismatch in the principals and reword the "vtable kinds may not match" message to more accurately describe the pointer metadata and not refer to "vtables" if the metadata is unknown. fixes https://github.com/rust-lang/rust/issues/130030 r? `@WaffleLapkin` but feel free to reassign
This commit is contained in:
commit
75296fc721
|
@ -333,7 +333,11 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
if let ConstraintCategory::Cast { 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);
|
||||
}
|
||||
self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
|
||||
|
@ -740,7 +744,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
|||
// 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,
|
||||
) => {
|
||||
|
|
|
@ -47,7 +47,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
|
|||
ConstraintCategory::Yield => "yielding this value ",
|
||||
ConstraintCategory::UseAsConst => "using this value as a constant ",
|
||||
ConstraintCategory::UseAsStatic => "using this value as a static ",
|
||||
ConstraintCategory::Cast { .. } => "cast ",
|
||||
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 ",
|
||||
|
|
|
@ -1975,8 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
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 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
self.prove_predicate(
|
||||
ty::ClauseKind::WellFormed(src_ty.into()),
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
);
|
||||
|
||||
let src_ty = self.normalize(src_ty, location);
|
||||
|
@ -2015,7 +2016,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
src_ty,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
@ -2036,7 +2037,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
self.prove_predicate(
|
||||
ty::ClauseKind::WellFormed(src_ty.into()),
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { 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 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
src_ty,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
@ -2062,19 +2063,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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 { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
@ -2087,7 +2092,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
|
||||
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 { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
@ -2116,7 +2125,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize, coercion_source) => {
|
||||
let &ty = ty;
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
|
@ -2124,22 +2133,21 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
[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 {
|
||||
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::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
|
||||
|
@ -2150,12 +2158,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
|
||||
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 { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
);
|
||||
|
||||
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
|
||||
|
@ -2166,11 +2175,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
self.prove_predicate(
|
||||
outlives_predicate,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { 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,);
|
||||
|
@ -2180,11 +2192,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
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 { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
@ -2197,7 +2210,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -2242,11 +2255,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
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 { unsize_to: None },
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
@ -2427,7 +2441,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -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 codegen_stmt<'tcx>(
|
|||
}
|
||||
}
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
|
||||
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _),
|
||||
ref operand,
|
||||
_to_ty,
|
||||
) => {
|
||||
|
@ -763,14 +764,18 @@ fn codegen_stmt<'tcx>(
|
|||
}
|
||||
}
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize),
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize, _),
|
||||
ref operand,
|
||||
_to_ty,
|
||||
) => {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
crate::unsize::coerce_unsized_into(fx, operand, lval);
|
||||
}
|
||||
Rvalue::Cast(CastKind::DynStar, ref operand, _) => {
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(PointerCoercion::DynStar, _),
|
||||
ref operand,
|
||||
_,
|
||||
) => {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
crate::unsize::coerce_dyn_star(fx, operand, lval);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
|
||||
mir::Rvalue::Cast(
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _),
|
||||
ref source,
|
||||
_,
|
||||
) => {
|
||||
|
@ -465,7 +465,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
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 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
_ => 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 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
_ => 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 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
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 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
bug!("unexpected non-pair operand");
|
||||
}
|
||||
}
|
||||
mir::CastKind::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);
|
||||
|
|
|
@ -440,6 +440,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
| PointerCoercion::UnsafeFnPointer
|
||||
| PointerCoercion::ClosureFnPointer(_)
|
||||
| PointerCoercion::ReifyFnPointer,
|
||||
_,
|
||||
),
|
||||
_,
|
||||
_,
|
||||
|
@ -447,8 +448,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
// These are all okay; they only change the type, not the data.
|
||||
}
|
||||
|
||||
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => {
|
||||
// Unsizing is implemented for CTFE.
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar, _),
|
||||
_,
|
||||
_,
|
||||
) => {
|
||||
// Unsizing and `dyn*` coercions are implemented for CTFE.
|
||||
}
|
||||
|
||||
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
|
||||
|
@ -458,10 +463,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
// Since no pointer can ever get exposed (rejected above), this is easy to support.
|
||||
}
|
||||
|
||||
Rvalue::Cast(CastKind::DynStar, _, _) => {
|
||||
// `dyn*` coercion is implemented for CTFE.
|
||||
}
|
||||
|
||||
Rvalue::Cast(_, _, _) => {}
|
||||
|
||||
Rvalue::NullaryOp(
|
||||
|
|
|
@ -32,7 +32,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
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 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
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 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
|
||||
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
|
||||
let src = self.read_immediate(src)?;
|
||||
match cast_ty.kind() {
|
||||
ty::FnPtr(..) => {
|
||||
|
@ -105,7 +106,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
CastKind::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)?;
|
||||
|
|
|
@ -32,13 +32,14 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
|
||||
use rustc_hir::{self as hir, ExprKind};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::Mutability;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::cast::{CastKind, CastTy};
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -152,12 +153,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum CastError {
|
||||
enum CastError<'tcx> {
|
||||
ErrorGuaranteed(ErrorGuaranteed),
|
||||
|
||||
CastToBool,
|
||||
CastToChar,
|
||||
DifferingKinds,
|
||||
DifferingKinds {
|
||||
src_kind: PointerKind<'tcx>,
|
||||
dst_kind: PointerKind<'tcx>,
|
||||
},
|
||||
/// Cast of thin to fat raw ptr (e.g., `*const () as *const [u8]`).
|
||||
SizedUnsizedCast,
|
||||
IllegalCast,
|
||||
|
@ -177,7 +181,7 @@ pub enum CastError {
|
|||
ForeignNonExhaustiveAdt,
|
||||
}
|
||||
|
||||
impl From<ErrorGuaranteed> for CastError {
|
||||
impl From<ErrorGuaranteed> for CastError<'_> {
|
||||
fn from(err: ErrorGuaranteed) -> Self {
|
||||
CastError::ErrorGuaranteed(err)
|
||||
}
|
||||
|
@ -251,7 +255,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) {
|
||||
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError<'tcx>) {
|
||||
match e {
|
||||
CastError::ErrorGuaranteed(_) => {
|
||||
// an error has already been reported
|
||||
|
@ -303,10 +307,52 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
CastError::IllegalCast => {
|
||||
make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx).emit();
|
||||
}
|
||||
CastError::DifferingKinds => {
|
||||
make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx)
|
||||
.with_note("vtable kinds may not match")
|
||||
.emit();
|
||||
CastError::DifferingKinds { src_kind, dst_kind } => {
|
||||
let mut err =
|
||||
make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx);
|
||||
|
||||
match (src_kind, dst_kind) {
|
||||
(PointerKind::VTable(_), PointerKind::VTable(_)) => {
|
||||
err.note("the trait objects may have different vtables");
|
||||
}
|
||||
(
|
||||
PointerKind::OfParam(_) | PointerKind::OfAlias(_),
|
||||
PointerKind::OfParam(_)
|
||||
| PointerKind::OfAlias(_)
|
||||
| PointerKind::VTable(_)
|
||||
| PointerKind::Length,
|
||||
)
|
||||
| (
|
||||
PointerKind::VTable(_) | PointerKind::Length,
|
||||
PointerKind::OfParam(_) | PointerKind::OfAlias(_),
|
||||
) => {
|
||||
err.note("the pointers may have different metadata");
|
||||
}
|
||||
(PointerKind::VTable(_), PointerKind::Length)
|
||||
| (PointerKind::Length, PointerKind::VTable(_)) => {
|
||||
err.note("the pointers have different metadata");
|
||||
}
|
||||
(
|
||||
PointerKind::Thin,
|
||||
PointerKind::Thin
|
||||
| PointerKind::VTable(_)
|
||||
| PointerKind::Length
|
||||
| PointerKind::OfParam(_)
|
||||
| PointerKind::OfAlias(_),
|
||||
)
|
||||
| (
|
||||
PointerKind::VTable(_)
|
||||
| PointerKind::Length
|
||||
| PointerKind::OfParam(_)
|
||||
| PointerKind::OfAlias(_),
|
||||
PointerKind::Thin,
|
||||
)
|
||||
| (PointerKind::Length, PointerKind::Length) => {
|
||||
span_bug!(self.span, "unexpected cast error: {e:?}")
|
||||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
CastError::CastToBool => {
|
||||
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
|
||||
|
@ -670,10 +716,20 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
/// Checks a cast, and report an error if one exists. In some cases, this
|
||||
/// can return Ok and create type errors in the fcx rather than returning
|
||||
/// directly. coercion-cast is handled in check instead of here.
|
||||
fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
|
||||
fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError<'tcx>> {
|
||||
use rustc_middle::ty::cast::CastTy::*;
|
||||
use rustc_middle::ty::cast::IntTy::*;
|
||||
|
||||
if self.cast_ty.is_dyn_star() {
|
||||
if fcx.tcx.features().dyn_star {
|
||||
span_bug!(self.span, "should be handled by `coerce`");
|
||||
} else {
|
||||
// Report "casting is invalid" rather than "non-primitive cast"
|
||||
// if the feature is not enabled.
|
||||
return Err(CastError::IllegalCast);
|
||||
}
|
||||
}
|
||||
|
||||
let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
|
||||
{
|
||||
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
|
||||
|
@ -780,16 +836,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
|
||||
|
||||
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
|
||||
|
||||
(_, DynStar) => {
|
||||
if fcx.tcx.features().dyn_star {
|
||||
bug!("should be handled by `coerce`")
|
||||
} else {
|
||||
Err(CastError::IllegalCast)
|
||||
}
|
||||
}
|
||||
|
||||
(DynStar, _) => Err(CastError::IllegalCast),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,27 +844,34 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
m_src: ty::TypeAndMut<'tcx>,
|
||||
m_dst: ty::TypeAndMut<'tcx>,
|
||||
) -> Result<CastKind, CastError> {
|
||||
) -> Result<CastKind, CastError<'tcx>> {
|
||||
debug!("check_ptr_ptr_cast m_src={m_src:?} m_dst={m_dst:?}");
|
||||
// ptr-ptr cast. vtables must match.
|
||||
// ptr-ptr cast. metadata must match.
|
||||
|
||||
let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?);
|
||||
let dst_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_dst.ty, self.span)?);
|
||||
|
||||
// We can't cast if target pointer kind is unknown
|
||||
let Some(dst_kind) = dst_kind else {
|
||||
return Err(CastError::UnknownCastPtrKind);
|
||||
};
|
||||
|
||||
// Cast to thin pointer is OK
|
||||
if dst_kind == PointerKind::Thin {
|
||||
return Ok(CastKind::PtrPtrCast);
|
||||
}
|
||||
|
||||
// We can't cast to fat pointer if source pointer kind is unknown
|
||||
let Some(src_kind) = src_kind else {
|
||||
return Err(CastError::UnknownCastPtrKind);
|
||||
};
|
||||
|
||||
match (src_kind, dst_kind) {
|
||||
// We can't cast if target pointer kind is unknown
|
||||
(_, None) => Err(CastError::UnknownCastPtrKind),
|
||||
// Cast to thin pointer is OK
|
||||
(_, Some(PointerKind::Thin)) => Ok(CastKind::PtrPtrCast),
|
||||
|
||||
// We can't cast to fat pointer if source pointer kind is unknown
|
||||
(None, _) => Err(CastError::UnknownExprPtrKind),
|
||||
|
||||
// thin -> fat? report invalid cast (don't complain about vtable kinds)
|
||||
(Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast),
|
||||
(PointerKind::Thin, _) => Err(CastError::SizedUnsizedCast),
|
||||
|
||||
// trait object -> trait object? need to do additional checks
|
||||
(Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => {
|
||||
(PointerKind::VTable(src_tty), PointerKind::VTable(dst_tty)) => {
|
||||
match (src_tty.principal(), dst_tty.principal()) {
|
||||
// A<dyn Src<...> + SrcAuto> -> B<dyn Dst<...> + DstAuto>. need to make sure
|
||||
// - `Src` and `Dst` traits are the same
|
||||
|
@ -834,7 +887,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
// Note that trait upcasting goes through a different mechanism (`coerce_unsized`)
|
||||
// and is unaffected by this check.
|
||||
if src_principal.def_id() != dst_principal.def_id() {
|
||||
return Err(CastError::DifferingKinds);
|
||||
return Err(CastError::DifferingKinds { src_kind, dst_kind });
|
||||
}
|
||||
|
||||
// We need to reconstruct trait object types.
|
||||
|
@ -860,7 +913,16 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
));
|
||||
|
||||
// `dyn Src = dyn Dst`, this checks for matching traits/generics
|
||||
fcx.demand_eqtype(self.span, src_obj, dst_obj);
|
||||
// This is `demand_eqtype`, but inlined to give a better error.
|
||||
let cause = fcx.misc(self.span);
|
||||
if fcx
|
||||
.at(&cause, fcx.param_env)
|
||||
.eq(DefineOpaqueTypes::Yes, src_obj, dst_obj)
|
||||
.map(|infer_ok| fcx.register_infer_ok_obligations(infer_ok))
|
||||
.is_err()
|
||||
{
|
||||
return Err(CastError::DifferingKinds { src_kind, dst_kind });
|
||||
}
|
||||
|
||||
// Check that `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto`.
|
||||
// Emit an FCW otherwise.
|
||||
|
@ -905,17 +967,17 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
// dyn Trait -> dyn Auto? should be ok, but we used to not allow it.
|
||||
// FIXME: allow this
|
||||
(Some(_), None) => Err(CastError::DifferingKinds),
|
||||
(Some(_), None) => Err(CastError::DifferingKinds { src_kind, dst_kind }),
|
||||
|
||||
// dyn Auto -> dyn Trait? not ok.
|
||||
(None, Some(_)) => Err(CastError::DifferingKinds),
|
||||
(None, Some(_)) => Err(CastError::DifferingKinds { src_kind, dst_kind }),
|
||||
}
|
||||
}
|
||||
|
||||
// fat -> fat? metadata kinds must match
|
||||
(Some(src_kind), Some(dst_kind)) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast),
|
||||
(src_kind, dst_kind) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast),
|
||||
|
||||
(_, _) => Err(CastError::DifferingKinds),
|
||||
(_, _) => Err(CastError::DifferingKinds { src_kind, dst_kind }),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -923,7 +985,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
&self,
|
||||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
m_cast: ty::TypeAndMut<'tcx>,
|
||||
) -> Result<CastKind, CastError> {
|
||||
) -> Result<CastKind, CastError<'tcx>> {
|
||||
// fptr-ptr cast. must be to thin ptr
|
||||
|
||||
match fcx.pointer_kind(m_cast.ty, self.span)? {
|
||||
|
@ -937,7 +999,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
&self,
|
||||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
m_expr: ty::TypeAndMut<'tcx>,
|
||||
) -> Result<CastKind, CastError> {
|
||||
) -> Result<CastKind, CastError<'tcx>> {
|
||||
// ptr-addr cast. must be from thin ptr
|
||||
|
||||
match fcx.pointer_kind(m_expr.ty, self.span)? {
|
||||
|
@ -952,7 +1014,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
m_expr: ty::TypeAndMut<'tcx>,
|
||||
m_cast: ty::TypeAndMut<'tcx>,
|
||||
) -> Result<CastKind, CastError> {
|
||||
) -> Result<CastKind, CastError<'tcx>> {
|
||||
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
|
||||
if m_expr.mutbl >= m_cast.mutbl {
|
||||
if let ty::Array(ety, _) = m_expr.ty.kind() {
|
||||
|
@ -987,7 +1049,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
&self,
|
||||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
m_cast: TypeAndMut<'tcx>,
|
||||
) -> Result<CastKind, CastError> {
|
||||
) -> Result<CastKind, CastError<'tcx>> {
|
||||
// ptr-addr cast. pointer must be thin.
|
||||
match fcx.pointer_kind(m_cast.ty, self.span)? {
|
||||
None => Err(CastError::UnknownCastPtrKind),
|
||||
|
|
|
@ -769,7 +769,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
));
|
||||
|
||||
Ok(InferOk {
|
||||
value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),
|
||||
value: (
|
||||
vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }],
|
||||
b,
|
||||
),
|
||||
obligations,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -759,9 +759,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||
for adjustment in adjustments {
|
||||
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
|
||||
match adjustment.kind {
|
||||
adjustment::Adjust::NeverToAny
|
||||
| adjustment::Adjust::Pointer(_)
|
||||
| adjustment::Adjust::DynStar => {
|
||||
adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => {
|
||||
// Creating a closure/fn-pointer or unsizing consumes
|
||||
// the input and stores it into the resulting rvalue.
|
||||
self.consume_or_copy(&place_with_id, place_with_id.hir_id);
|
||||
|
@ -1296,8 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||
adjustment::Adjust::NeverToAny
|
||||
| adjustment::Adjust::Pointer(_)
|
||||
| adjustment::Adjust::Borrow(_)
|
||||
| adjustment::Adjust::ReborrowPin(..)
|
||||
| adjustment::Adjust::DynStar => {
|
||||
| adjustment::Adjust::ReborrowPin(..) => {
|
||||
// Result is an rvalue.
|
||||
Ok(self.cat_rvalue(expr.hir_id, target))
|
||||
}
|
||||
|
|
|
@ -234,7 +234,9 @@ pub enum ConstraintCategory<'tcx> {
|
|||
UseAsStatic,
|
||||
TypeAnnotation,
|
||||
Cast {
|
||||
/// Whether this is an unsizing cast and if yes, this contains the target type.
|
||||
/// 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)]
|
||||
unsize_to: Option<Ty<'tcx>>,
|
||||
|
|
|
@ -432,9 +432,8 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
| CastKind::IntToFloat
|
||||
| CastKind::FnPtrToPtr
|
||||
| CastKind::PtrToPtr
|
||||
| CastKind::PointerCoercion(_)
|
||||
| CastKind::PointerCoercion(_, _)
|
||||
| CastKind::PointerWithExposedProvenance
|
||||
| CastKind::DynStar
|
||||
| CastKind::Transmute,
|
||||
_,
|
||||
_,
|
||||
|
|
|
@ -579,7 +579,8 @@ 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 only for diagnostics.
|
||||
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub enum CallSource {
|
||||
|
@ -1403,9 +1404,7 @@ pub enum CastKind {
|
|||
/// * [`PointerCoercion::MutToConstPointer`]
|
||||
///
|
||||
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
|
||||
PointerCoercion(PointerCoercion),
|
||||
/// Cast into a dyn* object.
|
||||
DynStar,
|
||||
PointerCoercion(PointerCoercion, CoercionSource),
|
||||
IntToInt,
|
||||
FloatToInt,
|
||||
FloatToFloat,
|
||||
|
@ -1421,6 +1420,16 @@ pub enum CastKind {
|
|||
Transmute,
|
||||
}
|
||||
|
||||
/// Represents how a [`CastKind::PointerCoercion`] was constructed.
|
||||
/// Used only 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> {
|
||||
|
|
|
@ -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 {
|
||||
|
@ -453,12 +455,14 @@ pub enum ExprKind<'tcx> {
|
|||
source: ExprId,
|
||||
/// Type that the user gave to this expression
|
||||
user_ty: UserTy<'tcx>,
|
||||
user_ty_span: Span,
|
||||
},
|
||||
/// A type ascription on a value, e.g. `42: i32`.
|
||||
/// A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`.
|
||||
ValueTypeAscription {
|
||||
source: ExprId,
|
||||
/// Type that the user gave to this expression
|
||||
user_ty: UserTy<'tcx>,
|
||||
user_ty_span: Span,
|
||||
},
|
||||
/// A closure definition.
|
||||
Closure(Box<ClosureExpr<'tcx>>),
|
||||
|
|
|
@ -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);
|
||||
|
@ -129,7 +131,8 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
|
|||
visitor.visit_expr(&visitor.thir()[base.base]);
|
||||
}
|
||||
}
|
||||
PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
|
||||
PlaceTypeAscription { source, user_ty: _, user_ty_span: _ }
|
||||
| ValueTypeAscription { source, user_ty: _, user_ty_span: _ } => {
|
||||
visitor.visit_expr(&visitor.thir()[source])
|
||||
}
|
||||
Closure(box ClosureExpr {
|
||||
|
|
|
@ -35,6 +35,9 @@ pub enum PointerCoercion {
|
|||
/// type. Codegen backends and miri figure out what has to be done
|
||||
/// based on the precise source/target type at hand.
|
||||
Unsize,
|
||||
|
||||
/// Go from a pointer-like type to a `dyn*` object.
|
||||
DynStar,
|
||||
}
|
||||
|
||||
/// Represents coercing a value to a different type of value.
|
||||
|
@ -102,9 +105,6 @@ pub enum Adjust<'tcx> {
|
|||
|
||||
Pointer(PointerCoercion),
|
||||
|
||||
/// Cast into a dyn* object.
|
||||
DynStar,
|
||||
|
||||
/// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
|
||||
ReborrowPin(ty::Region<'tcx>, hir::Mutability),
|
||||
}
|
||||
|
|
|
@ -34,15 +34,12 @@ pub enum CastTy<'tcx> {
|
|||
FnPtr,
|
||||
/// Raw pointers.
|
||||
Ptr(ty::TypeAndMut<'tcx>),
|
||||
/// Casting into a `dyn*` value.
|
||||
DynStar,
|
||||
}
|
||||
|
||||
/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html)
|
||||
/// (or rustc_hir_analysis/check/cast.rs).
|
||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub enum CastKind {
|
||||
CoercionCast,
|
||||
PtrPtrCast,
|
||||
PtrAddrCast,
|
||||
AddrPtrCast,
|
||||
|
@ -53,7 +50,6 @@ pub enum CastKind {
|
|||
ArrayPtrCast,
|
||||
FnPtrPtrCast,
|
||||
FnPtrAddrCast,
|
||||
DynStarCast,
|
||||
}
|
||||
|
||||
impl<'tcx> CastTy<'tcx> {
|
||||
|
@ -71,7 +67,6 @@ impl<'tcx> CastTy<'tcx> {
|
|||
ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
|
||||
ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })),
|
||||
ty::FnPtr(..) => Some(CastTy::FnPtr),
|
||||
ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +81,6 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin
|
|||
mir::CastKind::PointerExposeProvenance
|
||||
}
|
||||
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
|
||||
(_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,
|
||||
(Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt,
|
||||
(Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr,
|
||||
|
||||
|
|
|
@ -470,21 +470,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block.and(place_builder)
|
||||
}
|
||||
|
||||
ExprKind::PlaceTypeAscription { source, ref user_ty } => {
|
||||
ExprKind::PlaceTypeAscription { source, ref user_ty, user_ty_span } => {
|
||||
let place_builder = unpack!(
|
||||
block = this.expr_as_place(block, source, mutability, fake_borrow_temps,)
|
||||
);
|
||||
if let Some(user_ty) = user_ty {
|
||||
let ty_source_info = this.source_info(user_ty_span);
|
||||
let annotation_index =
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
span: user_ty_span,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
|
||||
let place = place_builder.to_place(this);
|
||||
this.cfg.push(block, Statement {
|
||||
source_info,
|
||||
source_info: ty_source_info,
|
||||
kind: StatementKind::AscribeUserType(
|
||||
Box::new((place, UserTypeProjection {
|
||||
base: annotation_index,
|
||||
|
@ -496,20 +497,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
block.and(place_builder)
|
||||
}
|
||||
ExprKind::ValueTypeAscription { source, ref user_ty } => {
|
||||
ExprKind::ValueTypeAscription { source, ref user_ty, user_ty_span } => {
|
||||
let source_expr = &this.thir[source];
|
||||
let temp = unpack!(
|
||||
block = this.as_temp(block, source_expr.temp_lifetime, source, mutability)
|
||||
);
|
||||
if let Some(user_ty) = user_ty {
|
||||
let ty_source_info = this.source_info(user_ty_span);
|
||||
let annotation_index =
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
span: user_ty_span,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
this.cfg.push(block, Statement {
|
||||
source_info,
|
||||
source_info: ty_source_info,
|
||||
kind: StatementKind::AscribeUserType(
|
||||
Box::new((Place::from(temp), UserTypeProjection {
|
||||
base: annotation_index,
|
||||
|
|
|
@ -292,7 +292,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
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
|
||||
|
|
|
@ -407,7 +407,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
source_info,
|
||||
temp,
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize),
|
||||
CastKind::PointerCoercion(
|
||||
PointerCoercion::Unsize,
|
||||
CoercionSource::Implicit,
|
||||
),
|
||||
Operand::Copy(val),
|
||||
ty,
|
||||
),
|
||||
|
@ -421,7 +424,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
source_info,
|
||||
slice,
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize),
|
||||
CastKind::PointerCoercion(
|
||||
PointerCoercion::Unsize,
|
||||
CoercionSource::Implicit,
|
||||
),
|
||||
expect,
|
||||
ty,
|
||||
),
|
||||
|
|
|
@ -104,15 +104,28 @@ impl<'tcx> Cx<'tcx> {
|
|||
};
|
||||
|
||||
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) },
|
||||
|
@ -146,7 +159,6 @@ impl<'tcx> Cx<'tcx> {
|
|||
Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
|
||||
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
|
||||
}
|
||||
Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
|
||||
Adjust::ReborrowPin(region, mutbl) => {
|
||||
debug!("apply ReborrowPin adjustment");
|
||||
// Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
|
||||
|
@ -236,6 +248,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
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)
|
||||
|
@ -841,6 +854,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
ExprKind::ValueTypeAscription {
|
||||
source: cast_expr,
|
||||
user_ty: Some(Box::new(*user_ty)),
|
||||
user_ty_span: cast_ty.span,
|
||||
}
|
||||
} else {
|
||||
cast
|
||||
|
@ -852,9 +866,17 @@ impl<'tcx> Cx<'tcx> {
|
|||
debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
|
||||
let mirrored = self.mirror_expr(source);
|
||||
if source.is_syntactic_place_expr() {
|
||||
ExprKind::PlaceTypeAscription { source: mirrored, user_ty }
|
||||
ExprKind::PlaceTypeAscription {
|
||||
source: mirrored,
|
||||
user_ty,
|
||||
user_ty_span: ty.span,
|
||||
}
|
||||
} else {
|
||||
ExprKind::ValueTypeAscription { source: mirrored, user_ty }
|
||||
ExprKind::ValueTypeAscription {
|
||||
source: mirrored,
|
||||
user_ty,
|
||||
user_ty_span: ty.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
|
||||
|
|
|
@ -292,9 +292,14 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||
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);
|
||||
|
@ -454,16 +459,18 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||
self.print_adt_expr(&**adt_expr, depth_lvl + 1);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
PlaceTypeAscription { source, user_ty } => {
|
||||
PlaceTypeAscription { source, user_ty, user_ty_span } => {
|
||||
print_indented!(self, "PlaceTypeAscription {", depth_lvl);
|
||||
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
|
||||
print_indented!(self, format!("user_ty_span: {:?}", user_ty_span), depth_lvl + 1);
|
||||
print_indented!(self, "source:", depth_lvl + 1);
|
||||
self.print_expr(*source, depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
ValueTypeAscription { source, user_ty } => {
|
||||
ValueTypeAscription { source, user_ty, user_ty_span } => {
|
||||
print_indented!(self, "ValueTypeAscription {", depth_lvl);
|
||||
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
|
||||
print_indented!(self, format!("user_ty_span: {:?}", user_ty_span), depth_lvl + 1);
|
||||
print_indented!(self, "source:", depth_lvl + 1);
|
||||
self.print_expr(*source, depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
|
|
|
@ -42,6 +42,7 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
|
|||
ref mut cast_kind @ CastKind::PointerCoercion(
|
||||
PointerCoercion::ArrayToPointer
|
||||
| PointerCoercion::MutToConstPointer,
|
||||
_,
|
||||
),
|
||||
..,
|
||||
),
|
||||
|
|
|
@ -189,7 +189,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize),
|
||||
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _),
|
||||
operand,
|
||||
_,
|
||||
) => {
|
||||
|
|
|
@ -576,7 +576,7 @@ impl<'body, 'tcx> VnState<'body, '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 @@ impl<'body, 'tcx> VnState<'body, '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 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
(
|
||||
UnOp::PtrMetadata,
|
||||
Value::Cast {
|
||||
kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize),
|
||||
kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _),
|
||||
from,
|
||||
to,
|
||||
..
|
||||
|
@ -1342,7 +1342,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
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 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
|
||||
// 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)
|
||||
|
|
|
@ -70,11 +70,11 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
|
|||
match *rvalue {
|
||||
// We need to detect unsizing casts that required vtables.
|
||||
mir::Rvalue::Cast(
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _)
|
||||
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _),
|
||||
ref operand,
|
||||
target_ty,
|
||||
)
|
||||
| mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
|
||||
) => {
|
||||
// This isn't monomorphized yet so we can't tell what the actual types are -- just
|
||||
// add everything that may involve a vtable.
|
||||
let source_ty = operand.ty(self.body, self.tcx);
|
||||
|
@ -96,7 +96,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
|
|||
}
|
||||
// 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 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
|
|||
}
|
||||
// And finally, function pointer reification casts.
|
||||
mir::Rvalue::Cast(
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _),
|
||||
ref operand,
|
||||
_,
|
||||
) => {
|
||||
|
|
|
@ -7,9 +7,10 @@ use rustc_hir::def_id::DefId;
|
|||
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 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
|||
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,
|
||||
))
|
||||
|
|
|
@ -1128,12 +1128,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
Rvalue::Cast(kind, operand, target_type) => {
|
||||
let op_ty = operand.ty(self.body, self.tcx);
|
||||
match kind {
|
||||
CastKind::DynStar => {
|
||||
// FIXME(dyn-star): make sure nothing needs to be done here.
|
||||
}
|
||||
// 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,
|
||||
|
@ -1146,7 +1143,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
ty::FnPtr(..)
|
||||
);
|
||||
}
|
||||
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
|
||||
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
|
||||
// FIXME: check safety and signature compatibility.
|
||||
check_kinds!(
|
||||
op_ty,
|
||||
|
@ -1159,7 +1156,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
ty::FnPtr(..)
|
||||
);
|
||||
}
|
||||
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => {
|
||||
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..), _) => {
|
||||
// FIXME: check safety, captures, and signature compatibility.
|
||||
check_kinds!(
|
||||
op_ty,
|
||||
|
@ -1172,7 +1169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
ty::FnPtr(..)
|
||||
);
|
||||
}
|
||||
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
|
||||
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer, _) => {
|
||||
// FIXME: check same pointee?
|
||||
check_kinds!(
|
||||
op_ty,
|
||||
|
@ -1188,7 +1185,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
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,
|
||||
|
@ -1204,10 +1201,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
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, _) => {
|
||||
// FIXME(dyn-star): make sure nothing needs to be done here.
|
||||
}
|
||||
CastKind::IntToInt | CastKind::IntToFloat => {
|
||||
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
|
||||
let target_valid = target_type.is_numeric() || target_type.is_char();
|
||||
|
|
|
@ -665,11 +665,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
|||
// 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::Unsize, _)
|
||||
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _),
|
||||
ref operand,
|
||||
target_ty,
|
||||
)
|
||||
| mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
|
||||
) => {
|
||||
let source_ty = operand.ty(self.body, self.tcx);
|
||||
// *Before* monomorphizing, record that we already handled this mention.
|
||||
self.used_mentioned_items
|
||||
|
@ -694,7 +694,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
mir::Rvalue::Cast(
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
|
||||
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _),
|
||||
ref operand,
|
||||
_,
|
||||
) => {
|
||||
|
@ -705,7 +705,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
|||
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,
|
||||
_,
|
||||
) => {
|
||||
|
|
|
@ -282,11 +282,12 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
|
|||
type T = stable_mir::mir::CastKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
use rustc_middle::mir::CastKind::*;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
match self {
|
||||
PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
|
||||
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
|
||||
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
|
||||
DynStar => stable_mir::mir::CastKind::DynStar,
|
||||
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,
|
||||
|
|
|
@ -119,6 +119,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
|
|||
}
|
||||
PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
|
||||
PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
|
||||
PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -960,6 +960,7 @@ pub enum CastKind {
|
|||
PointerExposeAddress,
|
||||
PointerWithExposedProvenance,
|
||||
PointerCoercion(PointerCoercion),
|
||||
// FIXME(smir-rename): change this to PointerCoercion(DynStar)
|
||||
DynStar,
|
||||
IntToInt,
|
||||
FloatToInt,
|
||||
|
|
|
@ -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::DynStar, _, _) => {
|
||||
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar, _), _, _) => {
|
||||
// FIXME(dyn-star)
|
||||
unimplemented!()
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// MIR for `address_of_reborrow` after SimplifyCfg-initial
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:8:5: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:10:5: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
|
@ -11,8 +11,8 @@
|
|||
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:19:5: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:21:5: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
|
@ -21,8 +21,8 @@
|
|||
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:29:5: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:31:5: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
|
@ -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: [] });
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -75,7 +75,7 @@ LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut)));
|
|||
| ^^^^^^^^^^^^^^^^^^-----------------------------------------^
|
||||
| | | |
|
||||
| | | immutable borrow occurs here
|
||||
| | cast requires that `reg.sess_mut` is borrowed for `'a`
|
||||
| | coercion requires that `reg.sess_mut` is borrowed for `'a`
|
||||
| mutable borrow occurs here
|
||||
|
|
||||
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
||||
|
@ -119,7 +119,7 @@ LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
|||
| ^^^^^^^^^^^^^^^^^^-------------------------------------------------^
|
||||
| | | |
|
||||
| | | first mutable borrow occurs here
|
||||
| | cast requires that `reg.sess_mut` is borrowed for `'a`
|
||||
| | coercion requires that `reg.sess_mut` is borrowed for `'a`
|
||||
| second mutable borrow occurs here
|
||||
|
|
||||
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` i
|
|||
LL | b_raw = f_raw as *mut _;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: vtable kinds may not match
|
||||
= note: the pointers may have different metadata
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -18,14 +18,14 @@ fn main() {
|
|||
let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid
|
||||
|
||||
let x: *const dyn Trait<X> = &();
|
||||
let y: *const dyn Trait<Y> = x as _; //~ error: mismatched types
|
||||
let y: *const dyn Trait<Y> = x as _; //~ error: casting `*const dyn Trait<X>` as `*const dyn Trait<Y>` is invalid
|
||||
|
||||
_ = (b, y);
|
||||
}
|
||||
|
||||
fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) {
|
||||
let _: *const dyn Trait<T> = x as _; //~ error: mismatched types
|
||||
let _: *const dyn Trait<X> = t as _; //~ error: mismatched types
|
||||
let _: *const dyn Trait<T> = x as _; //~ error: casting `*const (dyn Trait<X> + 'static)` as `*const dyn Trait<T>` is invalid
|
||||
let _: *const dyn Trait<X> = t as _; //~ error: casting `*const (dyn Trait<T> + 'static)` as `*const dyn Trait<X>` is invalid
|
||||
}
|
||||
|
||||
trait Assocked {
|
||||
|
@ -33,5 +33,5 @@ trait Assocked {
|
|||
}
|
||||
|
||||
fn change_assoc(x: *mut dyn Assocked<Assoc = u8>) -> *mut dyn Assocked<Assoc = u32> {
|
||||
x as _ //~ error: mismatched types
|
||||
x as _ //~ error: casting `*mut (dyn Assocked<Assoc = u8> + 'static)` as `*mut (dyn Assocked<Assoc = u32> + 'static)` is invalid
|
||||
}
|
||||
|
|
|
@ -4,53 +4,40 @@ error[E0606]: casting `*const dyn A` as `*const dyn B` is invalid
|
|||
LL | let b: *const dyn B = a as _;
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: vtable kinds may not match
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error[E0606]: casting `*const dyn Trait<X>` as `*const dyn Trait<Y>` is invalid
|
||||
--> $DIR/ptr-to-trait-obj-different-args.rs:21:34
|
||||
|
|
||||
LL | let y: *const dyn Trait<Y> = x as _;
|
||||
| ^^^^^^ expected `X`, found `Y`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: expected trait object `dyn Trait<X>`
|
||||
found trait object `dyn Trait<Y>`
|
||||
= help: `dyn Trait<Y>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error[E0606]: casting `*const (dyn Trait<X> + 'static)` as `*const dyn Trait<T>` is invalid
|
||||
--> $DIR/ptr-to-trait-obj-different-args.rs:27:34
|
||||
|
|
||||
LL | fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) {
|
||||
| - found this type parameter
|
||||
LL | let _: *const dyn Trait<T> = x as _;
|
||||
| ^^^^^^ expected `X`, found type parameter `T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: expected trait object `dyn Trait<X>`
|
||||
found trait object `dyn Trait<T>`
|
||||
= help: `dyn Trait<T>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error[E0606]: casting `*const (dyn Trait<T> + 'static)` as `*const dyn Trait<X>` is invalid
|
||||
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
|
||||
|
|
||||
LL | fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) {
|
||||
| - expected this type parameter
|
||||
LL | let _: *const dyn Trait<T> = x as _;
|
||||
LL | let _: *const dyn Trait<X> = t as _;
|
||||
| ^^^^^^ expected type parameter `T`, found `X`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: expected trait object `dyn Trait<T>`
|
||||
found trait object `dyn Trait<X>`
|
||||
= help: `dyn Trait<X>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error[E0308]: mismatched types
|
||||
error[E0606]: casting `*mut (dyn Assocked<Assoc = u8> + 'static)` as `*mut (dyn Assocked<Assoc = u32> + 'static)` is invalid
|
||||
--> $DIR/ptr-to-trait-obj-different-args.rs:36:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^ expected `u8`, found `u32`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: expected trait object `dyn Assocked<Assoc = u8>`
|
||||
found trait object `dyn Assocked<Assoc = u32>`
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0606.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0606`.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:27
|
||||
|
|
||||
LL | fn m<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let unsend: *const dyn Cat<'a> = &();
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of the type `S<dyn Cat<'_>>`, which makes the generic argument `dyn Cat<'_>` invariant
|
||||
= note: the struct `S<T>` is invariant over the parameter `T`
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:27
|
||||
|
|
||||
LL | fn m<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let unsend: *const dyn Cat<'a> = &();
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of the type `S<dyn Cat<'_>>`, which makes the generic argument `dyn Cat<'_>` invariant
|
||||
= note: the struct `S<T>` is invariant over the parameter `T`
|
||||
|
|
|
@ -33,5 +33,10 @@ fn change_assoc_1<'a, 'b>(
|
|||
//~| error: lifetime may not live long enough
|
||||
}
|
||||
|
||||
// This tests the default borrow check error, without the special casing for return values.
|
||||
fn require_static(_: *const dyn Trait<'static>) {}
|
||||
fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
||||
require_static(ptr as _) //~ error: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue