From 11e35a77a671b3d85ea161e1799ef3f6d98201f1 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Tue, 12 Dec 2023 20:47:31 -0800 Subject: [PATCH] refactor(tvix/eval): let OpCoerceToString select the CoercionKind Change-Id: I92d58ef216d7e0766af70f019b3dcd445284a95d Reviewed-on: https://cl.tvl.fyi/c/depot/+/10344 Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/eval/src/compiler/mod.rs | 9 ++++++++- tvix/eval/src/opcode.rs | 6 ++---- tvix/eval/src/value/mod.rs | 2 +- tvix/eval/src/vm/mod.rs | 11 ++--------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index f54dc8ba4..5e0c1899c 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -34,6 +34,7 @@ use crate::spans::LightSpan; use crate::spans::ToSpan; use crate::value::{Closure, Formals, Lambda, NixAttrs, Thunk, Value}; use crate::warnings::{EvalWarning, WarningKind}; +use crate::CoercionKind; use crate::SourceCode; use self::scope::{LocalIdx, LocalPosition, Scope, Upvalue, UpvalueKind}; @@ -444,7 +445,13 @@ impl Compiler<'_> { ast::InterpolPart::Interpolation(ipol) => { self.compile(slot, ipol.expr().unwrap()); // implicitly forces as well - self.push_op(OpCode::OpCoerceToString, ipol); + self.push_op( + OpCode::OpCoerceToString(CoercionKind { + strong: false, + import_paths: true, + }), + ipol, + ); } ast::InterpolPart::Literal(lit) => { diff --git a/tvix/eval/src/opcode.rs b/tvix/eval/src/opcode.rs index b57a79a3b..f89c1c12e 100644 --- a/tvix/eval/src/opcode.rs +++ b/tvix/eval/src/opcode.rs @@ -201,10 +201,8 @@ pub enum OpCode { /// Interpolate the given number of string fragments into a single string. OpInterpolate(Count), - /// Force the Value on the stack and coerce it to a string, always using - /// `CoercionKind::Weak { import_paths: true }`. This is the behavior - /// necessary for path interpolation. - OpCoerceToString, + /// Force the Value on the stack and coerce it to a string + OpCoerceToString(crate::CoercionKind), // Paths /// Attempt to resolve the Value on the stack using the configured [`NixSearchPath`][] diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index 567a2f3df..eb54f6ae5 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -161,7 +161,7 @@ macro_rules! gen_is { } /// Describes what input types are allowed when coercing a `Value` to a string -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct CoercionKind { /// If false only coerce already "stringly" types like strings and paths, but /// also coerce sets that have a `__toString` attribute. In Tvix, this is diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs index c3c0b259b..6c11997db 100644 --- a/tvix/eval/src/vm/mod.rs +++ b/tvix/eval/src/vm/mod.rs @@ -777,20 +777,13 @@ impl<'o> VM<'o> { _ => panic!("attempted to finalise a non-thunk"), }, - OpCode::OpCoerceToString => { + OpCode::OpCoerceToString(kind) => { let value = self.stack_pop(); let gen_span = frame.current_light_span(); self.push_call_frame(span, frame); self.enqueue_generator("coerce_to_string", gen_span.clone(), |co| { - value.coerce_to_string( - co, - CoercionKind { - strong: false, - import_paths: true, - }, - gen_span, - ) + value.coerce_to_string(co, kind, gen_span) }); return Ok(false);