From 08c98b75877ad85446c5939b5e8c5e4087af08d6 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 18 Feb 2025 17:52:25 +0100 Subject: [PATCH 1/3] Fix formatting --- frontend/exporter/src/constant_utils.rs | 44 ++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/frontend/exporter/src/constant_utils.rs b/frontend/exporter/src/constant_utils.rs index e35b3e986..c5b7ba685 100644 --- a/frontend/exporter/src/constant_utils.rs +++ b/frontend/exporter/src/constant_utils.rs @@ -562,27 +562,32 @@ mod rustc { (_, ty::Ref(_, inner_ty, _)) => { ConstantExprKind::Borrow(valtree_to_constant_expr(s, valtree, *inner_ty, span)) } - (ty::ValTree::Branch(valtrees), ty::Str) => ConstantExprKind::Literal( - ConstantLiteral::byte_str(valtrees.iter().map(|x| match x { - ty::ValTree::Leaf(leaf) => leaf.to_u8(), - _ => fatal!(s[span], "Expected a flat list of leaves while translating a str literal, got a arbitrary valtree.") - }).collect(), StrStyle::Cooked)) - , + (ty::ValTree::Branch(valtrees), ty::Str) => { + let bytes = valtrees + .iter() + .map(|x| match x { + ty::ValTree::Leaf(leaf) => leaf.to_u8(), + _ => fatal!( + s[span], + "Expected a flat list of leaves while translating \ + a str literal, got a arbitrary valtree." + ), + }) + .collect(); + ConstantExprKind::Literal(ConstantLiteral::byte_str(bytes, StrStyle::Cooked)) + } (ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => { let contents: rustc_middle::ty::DestructuredConst = s - .base().tcx + .base() + .tcx .destructure_const(ty::Const::new_value(s.base().tcx, valtree, ty)); let fields = contents.fields.iter().copied(); match ty.kind() { ty::Array(_, _) => ConstantExprKind::Array { - fields: fields - .map(|field| field.sinto(s)) - .collect(), + fields: fields.map(|field| field.sinto(s)).collect(), }, ty::Tuple(_) => ConstantExprKind::Tuple { - fields: fields - .map(|field| field.sinto(s)) - .collect(), + fields: fields.map(|field| field.sinto(s)).collect(), }, ty::Adt(def, _) => { let variant_idx = contents @@ -590,9 +595,10 @@ mod rustc { .s_expect(s, "destructed const of adt without variant idx"); let variant_def = &def.variant(variant_idx); - ConstantExprKind::Adt{ + ConstantExprKind::Adt { info: get_variant_information(def, variant_idx, s), - fields: fields.into_iter() + fields: fields + .into_iter() .zip(&variant_def.fields) .map(|(value, field)| ConstantFieldExpr { field: field.did.sinto(s), @@ -611,12 +617,12 @@ mod rustc { let usize_ty = rustc_middle::ty::Ty::new_usize(s.base().tcx).sinto(s); let lit = ConstantLiteral::Int(ConstantInt::Uint(raw_address, uint_ty)); ConstantExprKind::Cast { - source: ConstantExprKind::Literal(lit).decorate(usize_ty, span.sinto(s)) + source: ConstantExprKind::Literal(lit).decorate(usize_ty, span.sinto(s)), } } - (ty::ValTree::Leaf(x), _) => ConstantExprKind::Literal ( - scalar_int_to_constant_literal(s, x, ty) - ), + (ty::ValTree::Leaf(x), _) => { + ConstantExprKind::Literal(scalar_int_to_constant_literal(s, x, ty)) + } _ => supposely_unreachable_fatal!( s[span], "valtree_to_expr"; {valtree, ty} From 0923906a99528867caf9c5ef483122da417f59b3 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 18 Feb 2025 17:52:35 +0100 Subject: [PATCH 2/3] Not all evaluated MIR constants are byte strings --- engine/lib/import_thir.ml | 5 ++-- frontend/exporter/src/constant_utils.rs | 32 +++++++++++++++++-------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/engine/lib/import_thir.ml b/engine/lib/import_thir.ml index f24594f74..397d51eea 100644 --- a/engine/lib/import_thir.ml +++ b/engine/lib/import_thir.ml @@ -852,9 +852,10 @@ end) : EXPR = struct | Borrow arg -> Borrow { arg = constant_expr_to_expr arg; borrow_kind = Thir.Shared } | ConstRef { id } -> ConstRef { id } - | Cast _ | RawBorrow _ | TraitConst _ | FnPtr _ -> + | Cast _ | RawBorrow _ | TraitConst _ | FnPtr _ | Memory _ -> assertion_failure [ span ] - "constant_lit_to_lit: TraitConst | FnPtr | MutPtr" + "constant_lit_to_lit: TraitConst | FnPtr | RawBorrow | Cast | \ + Memory" | Todo _ -> assertion_failure [ span ] "ConstantExpr::Todo" and constant_lit_to_lit (l : Thir.constant_literal) _span : Thir.lit_kind * bool = diff --git a/frontend/exporter/src/constant_utils.rs b/frontend/exporter/src/constant_utils.rs index c5b7ba685..23891d31d 100644 --- a/frontend/exporter/src/constant_utils.rs +++ b/frontend/exporter/src/constant_utils.rs @@ -104,6 +104,10 @@ pub enum ConstantExprKind { /// is an implementation of `Foo` method_impl: Option, }, + /// A blob of memory containing the byte representation of the value. This can occur when + /// evaluating MIR constants. Interpreting this back to a structured value is left as an + /// exercice to the consumer. + Memory(Vec), Todo(String), } @@ -213,9 +217,9 @@ mod rustc { Cast { source } => ExprKind::Cast { source: source.into(), }, - kind @ (FnPtr { .. } | TraitConst { .. }) => { + kind @ (FnPtr { .. } | TraitConst { .. } | Memory { .. }) => { // SH: I see the `Closure` kind, but it's not the same as function pointer? - ExprKind::Todo(format!("FnPtr or TraitConst. kind={:#?}", kind)) + ExprKind::Todo(format!("FnPtr or TraitConst or Memory. kind={:#?}", kind)) } Todo(msg) => ExprKind::Todo(msg), }; @@ -327,16 +331,24 @@ mod rustc { variant_information: None, }, GlobalAlloc::Memory(alloc) => { - let values = alloc.inner().get_bytes_unchecked( - rustc_middle::mir::interpret::AllocRange { + let bytes = alloc + .inner() + .get_bytes_unchecked(rustc_middle::mir::interpret::AllocRange { start: rustc_abi::Size::ZERO, size: alloc.inner().size(), - }, - ); - ConstantExprKind::Literal(ConstantLiteral::ByteStr( - values.to_vec(), - StrStyle::Cooked, - )) + }) + .to_vec(); + match inner_ty.kind() { + ty::Slice(slice_ty) | ty::Array(slice_ty, _) + if matches!(slice_ty.kind(), ty::Uint(ty::UintTy::U8)) => + { + ConstantExprKind::Literal(ConstantLiteral::ByteStr( + bytes, + StrStyle::Cooked, + )) + } + _ => ConstantExprKind::Memory(bytes), + } } provenance => fatal!( s[span], From 2046c22438a88600bb30ff8a489686800e14cbc5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 19 Feb 2025 21:43:13 +0100 Subject: [PATCH 3/3] The style of string literals is semantically irrelevant --- engine/lib/import_thir.ml | 4 ++-- frontend/exporter/src/constant_utils.rs | 28 ++++++++++--------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/engine/lib/import_thir.ml b/engine/lib/import_thir.ml index 397d51eea..8cd3791b4 100644 --- a/engine/lib/import_thir.ml +++ b/engine/lib/import_thir.ml @@ -871,8 +871,8 @@ end) : EXPR = struct match String.chop_prefix v ~prefix:"-" with | Some v -> (Float (v, Suffixed ty), true) | None -> (Float (v, Suffixed ty), false)) - | Str (v, style) -> (Str (v, style), false) - | ByteStr (v, style) -> (ByteStr (v, style), false) + | Str v -> (Str (v, Cooked), false) + | ByteStr v -> (ByteStr (v, Cooked), false) and constant_field_expr ({ field; value } : Thir.constant_field_expr) : Thir.field_expr = { field; value = constant_expr_to_expr value } diff --git a/frontend/exporter/src/constant_utils.rs b/frontend/exporter/src/constant_utils.rs index 23891d31d..a093e8544 100644 --- a/frontend/exporter/src/constant_utils.rs +++ b/frontend/exporter/src/constant_utils.rs @@ -24,8 +24,8 @@ pub enum ConstantLiteral { Char(char), Float(String, FloatTy), Int(ConstantInt), - Str(String, StrStyle), - ByteStr(Vec, StrStyle), + Str(String), + ByteStr(Vec), } /// The subset of [Expr] that corresponds to constants. @@ -147,10 +147,10 @@ mod rustc { /// Rustc always represents string constants as `&[u8]`, but this /// is not nice to consume. This associated function interpret /// bytes as an unicode string, and as a byte string otherwise. - fn byte_str(bytes: Vec, style: StrStyle) -> Self { + fn byte_str(bytes: Vec) -> Self { match String::from_utf8(bytes.clone()) { - Ok(s) => Self::Str(s, style), - Err(_) => Self::ByteStr(bytes, style), + Ok(s) => Self::Str(s), + Err(_) => Self::ByteStr(bytes), } } } @@ -176,8 +176,8 @@ mod rustc { } } Float(f, ty) => LitKind::Float(f, LitFloatType::Suffixed(ty)), - ByteStr(raw, str_style) => LitKind::ByteStr(raw, str_style), - Str(raw, str_style) => LitKind::Str(raw, str_style), + ByteStr(raw) => LitKind::ByteStr(raw, StrStyle::Cooked), + Str(raw) => LitKind::Str(raw, StrStyle::Cooked), }; let span = c.span.clone(); let lit = Spanned { span, node }; @@ -342,10 +342,7 @@ mod rustc { ty::Slice(slice_ty) | ty::Array(slice_ty, _) if matches!(slice_ty.kind(), ty::Uint(ty::UintTy::U8)) => { - ConstantExprKind::Literal(ConstantLiteral::ByteStr( - bytes, - StrStyle::Cooked, - )) + ConstantExprKind::Literal(ConstantLiteral::ByteStr(bytes)) } _ => ConstantExprKind::Memory(bytes), } @@ -586,7 +583,7 @@ mod rustc { ), }) .collect(); - ConstantExprKind::Literal(ConstantLiteral::byte_str(bytes, StrStyle::Cooked)) + ConstantExprKind::Literal(ConstantLiteral::byte_str(bytes)) } (ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => { let contents: rustc_middle::ty::DestructuredConst = s @@ -715,11 +712,8 @@ mod rustc { let slice: &[u8] = data .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..end); - ConstantExprKind::Literal(ConstantLiteral::byte_str( - slice.to_vec(), - StrStyle::Cooked, - )) - .decorate(ty.sinto(s), span.sinto(s)) + ConstantExprKind::Literal(ConstantLiteral::byte_str(slice.to_vec())) + .decorate(ty.sinto(s), span.sinto(s)) } ConstValue::ZeroSized { .. } => { // Should be unit