1
Fork 0

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

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

View file

@ -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

View file

@ -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,
),

View file

@ -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) },
@ -235,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)

View file

@ -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);