Skip to content

Commit

Permalink
rune: Enable more miri tests
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Nov 2, 2024
1 parent 1dce7f8 commit 8ff7a56
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 94 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,18 @@ jobs:
strategy:
fail-fast: false
matrix:
include:
- crate: rune
target: >
runtime:: hir::arena:: --skip runtime::vm:: --skip runtime::vm_execution::
- crate: rune-alloc
crate:
- rune
- rune-core
- rune-alloc
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: miri
- uses: Swatinem/rust-cache@v2
- run: cargo miri test -p ${{matrix.crate}} --all-features -- ${{matrix.target}}
- run: cargo miri test -p ${{matrix.crate}} --all-features --all-targets
- run: cargo miri test -p ${{matrix.crate}} --all-features --doc

test_lib:
runs-on: ubuntu-latest
Expand Down
18 changes: 10 additions & 8 deletions crates/rune/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl core::error::Error for BuildError {
/// Note: these must be built with the `emit` feature enabled (default) to give
/// access to `rune::termcolor`.
///
/// ```
/// ```no_run
/// use rune::termcolor::{ColorChoice, StandardStream};
/// use rune::{Context, Source, Vm};
/// use std::sync::Arc;
Expand All @@ -101,9 +101,9 @@ impl core::error::Error for BuildError {
///
/// let mut sources = rune::Sources::new();
///
/// sources.insert(Source::new("entry", r#"
/// sources.insert(Source::memory(r#"
/// pub fn main() {
/// println("Hello World");
/// println!("Hello World");
/// }
/// "#)?)?;
///
Expand Down Expand Up @@ -237,12 +237,14 @@ impl<'a> compile::CompileVisitor for CompileVisitorGroup<'a> {
}

impl<'a, S> Build<'a, S> {
/// Modify the current [Build] to use the given [Context] while building.
/// Modify the current [`Build`] to use the given [`Context`] while
/// building.
///
/// If unspecified the empty context constructed with [`Context::new`] will
/// be used. Since this counts as building without a context,
/// [`Vm::without_runtime`] can be used when running the produced [`Unit`].
///
/// If unspecified the empty context constructed with [Context::new] will be
/// used. Since this counts as building without a context,
/// [Vm::without_context][crate::runtime::Vm] can be used when running the
/// produced [Unit].
/// [`Vm::without_runtime`]: crate::Vm::without_runtime
#[inline]
pub fn with_context(mut self, context: &'a Context) -> Self {
self.context = Some(context);
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/compile/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ impl Context {
/// This is not a cheap operation, since it requires cloning things out of
/// the build-time [Context] which are necessary at runtime.
///
/// ```
/// ```no_run
/// use rune::{Context, Vm, Unit};
/// use std::sync::Arc;
///
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
//!
//! [`termcolor`]: https://docs.rs/termcolor
//!
//! ```rust
//! ```no_run
//! use rune::{Context, Diagnostics, Source, Sources, Vm};
//! use rune::termcolor::{ColorChoice, StandardStream};
//! use std::sync::Arc;
Expand Down
6 changes: 3 additions & 3 deletions crates/rune/src/modules/capture_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
//!
//! # Examples
//!
//! ```
//! use rune::{Context, ContextError};
//! ```no_run
//! use rune::Context;
//! use rune::modules::capture_io::{self, CaptureIo};
//!
//! let io = CaptureIo::new();
//!
//! let mut context = rune::Context::with_config(false)?;
//! context.install(capture_io::module(&io)?)?;
//! # Ok::<_, ContextError>(())
//! # Ok::<_, rune::ContextError>(())
//! ```

use core::mem::take;
Expand Down
6 changes: 3 additions & 3 deletions crates/rune/src/modules/disable_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
//!
//! # Examples
//!
//! ```
//! use rune::{Context, ContextError};
//! ```no_run
//! use rune::Context;
//! use rune::modules::disable_io;
//!
//! let mut context = rune::Context::with_config(false)?;
//! context.install(disable_io::module()?)?;
//! # Ok::<_, ContextError>(())
//! # Ok::<_, rune::ContextError>(())
//! ```

use crate as rune;
Expand Down
4 changes: 1 addition & 3 deletions crates/rune/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,11 @@ pub(crate) use self::unit::UnitFn;
pub use self::unit::{Unit, UnitStorage};

mod value;
#[cfg(any(test, feature = "cli"))]
pub(crate) use self::value::OwnedRepr;
pub use self::value::{
Accessor, EmptyStruct, Inline, RawValueGuard, Rtti, Struct, TupleStruct, TypeValue, Value,
ValueMutGuard, ValueRefGuard, VariantRtti,
};
pub(crate) use self::value::{BorrowRefRepr, MutRepr, Mutable, RefRepr};
pub(crate) use self::value::{BorrowRefRepr, MutRepr, Mutable, OwnedRepr, RefRepr};

mod variant;
pub use self::variant::{Variant, VariantData};
Expand Down
37 changes: 36 additions & 1 deletion crates/rune/src/runtime/value/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate as rune;
use crate::alloc::prelude::*;
use crate::runtime::{OwnedTuple, TypeInfo};

use super::{Rtti, Value};
use super::{FromValue, Mutable, OwnedRepr, Rtti, RuntimeError, Value};

/// A empty with a well-defined type.
#[derive(TryClone)]
Expand All @@ -31,6 +31,17 @@ impl EmptyStruct {
}
}

impl FromValue for EmptyStruct {
fn from_value(value: Value) -> Result<Self, RuntimeError> {
match value.take_repr()? {
OwnedRepr::Inline(value) => Err(RuntimeError::expected_unit_struct(value.type_info())),
OwnedRepr::Mutable(Mutable::EmptyStruct(value)) => Ok(value),
OwnedRepr::Mutable(value) => Err(RuntimeError::expected_unit_struct(value.type_info())),
OwnedRepr::Any(value) => Err(RuntimeError::expected_unit_struct(value.type_info())),
}
}
}

impl fmt::Debug for EmptyStruct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.rtti.item)
Expand Down Expand Up @@ -78,6 +89,19 @@ impl TupleStruct {
}
}

impl FromValue for TupleStruct {
fn from_value(value: Value) -> Result<Self, RuntimeError> {
match value.take_repr()? {
OwnedRepr::Inline(value) => Err(RuntimeError::expected_tuple_struct(value.type_info())),
OwnedRepr::Mutable(Mutable::TupleStruct(value)) => Ok(value),
OwnedRepr::Mutable(value) => {
Err(RuntimeError::expected_tuple_struct(value.type_info()))
}
OwnedRepr::Any(value) => Err(RuntimeError::expected_tuple_struct(value.type_info())),
}
}
}

impl fmt::Debug for TupleStruct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}{:?}", self.rtti.item, self.data)
Expand Down Expand Up @@ -133,6 +157,17 @@ impl Struct {
}
}

impl FromValue for Struct {
fn from_value(value: Value) -> Result<Self, RuntimeError> {
match value.take_repr()? {
OwnedRepr::Inline(value) => Err(RuntimeError::expected_struct(value.type_info())),
OwnedRepr::Mutable(Mutable::Struct(value)) => Ok(value),
OwnedRepr::Mutable(value) => Err(RuntimeError::expected_struct(value.type_info())),
OwnedRepr::Any(value) => Err(RuntimeError::expected_struct(value.type_info())),
}
}
}

impl fmt::Debug for Struct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {{", self.rtti.item)?;
Expand Down
26 changes: 24 additions & 2 deletions crates/rune/src/runtime/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use crate as rune;
use crate::alloc::clone::TryClone;
use crate::alloc::Box;

use super::{Accessor, OwnedTuple, ProtocolCaller, TypeInfo, Value, VariantRtti, Vec, VmResult};
use super::{
Accessor, FromValue, Mutable, OwnedRepr, OwnedTuple, ProtocolCaller, RuntimeError, Tuple,
TypeInfo, Value, VariantRtti, Vec, VmResult,
};

/// The variant of a type.
#[derive(TryClone)]
Expand All @@ -26,6 +29,14 @@ impl Variant {
}
}

/// Try to access variant data as a tuple.
pub fn as_tuple(&self) -> Option<&Tuple> {
match &self.data {
VariantData::Tuple(tuple) => Some(tuple),
_ => None,
}
}

/// Construct a unit variant.
pub(crate) fn unit(rtti: Arc<VariantRtti>) -> Self {
Self {
Expand Down Expand Up @@ -61,7 +72,7 @@ impl Variant {
}

/// Access the underlying variant data mutably.
pub fn data_mut(&mut self) -> &mut VariantData {
pub(crate) fn data_mut(&mut self) -> &mut VariantData {
&mut self.data
}

Expand Down Expand Up @@ -165,6 +176,17 @@ impl Variant {
}
}

impl FromValue for Variant {
fn from_value(value: Value) -> Result<Self, RuntimeError> {
match value.take_repr()? {
OwnedRepr::Inline(value) => Err(RuntimeError::expected_variant(value.type_info())),
OwnedRepr::Mutable(Mutable::Variant(value)) => Ok(value),
OwnedRepr::Mutable(value) => Err(RuntimeError::expected_variant(value.type_info())),
OwnedRepr::Any(value) => Err(RuntimeError::expected_variant(value.type_info())),
}
}
}

/// The data of the variant.
#[derive(TryClone)]
pub enum VariantData {
Expand Down
28 changes: 9 additions & 19 deletions crates/rune/src/runtime/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,11 @@ impl Vm {
///
/// # Examples
///
/// ```
/// ```no_run
/// use rune::{Context, Unit, Vm};
///
/// use std::sync::Arc;
///
/// let context = Context::with_default_modules()?;
/// let context = Arc::new(context.runtime()?);
///
/// let mut sources = rune::sources! {
/// entry => {
/// pub fn max(a, b) {
Expand All @@ -338,10 +335,13 @@ impl Vm {
/// }
/// };
///
/// let context = Context::with_default_modules()?;
/// let runtime = Arc::new(context.runtime()?);
///
/// let unit = rune::prepare(&mut sources).build()?;
/// let unit = Arc::new(unit);
///
/// let vm = Vm::new(context, unit);
/// let vm = Vm::new(runtime, unit);
///
/// // Looking up an item from the source.
/// let dynamic_max = vm.lookup_function(["max"])?;
Expand Down Expand Up @@ -394,18 +394,12 @@ impl Vm {
///
/// # Examples
///
/// ```,no_run
/// ```no_run
/// use rune::{Context, Unit};
/// use std::sync::Arc;
///
/// let context = Context::with_default_modules()?;
/// let context = Arc::new(context.runtime()?);
///
/// // Normally the unit would be created by compiling some source,
/// // and since this one is empty it won't do anything.
/// let unit = Arc::new(Unit::default());
///
/// let mut vm = rune::Vm::new(context, unit);
/// let mut vm = rune::Vm::without_runtime(unit);
///
/// let output = vm.execute(["main"], (33i64,))?.complete().into_result()?;
/// let output: i64 = rune::from_value(output)?;
Expand All @@ -417,18 +411,14 @@ impl Vm {
/// You can use a `Vec<Value>` to provide a variadic collection of
/// arguments.
///
/// ```,no_run
/// ```no_run
/// use rune::{Context, Unit};
/// use std::sync::Arc;
///
/// let context = Context::with_default_modules()?;
/// let context = Arc::new(context.runtime()?);
///
/// // Normally the unit would be created by compiling some source,
/// // and since this one is empty it won't do anything.
/// let unit = Arc::new(Unit::default());
///
/// let mut vm = rune::Vm::new(context, unit);
/// let mut vm = rune::Vm::without_runtime(unit);
///
/// let mut args = Vec::new();
/// args.push(rune::to_value(1u32)?);
Expand Down
43 changes: 38 additions & 5 deletions crates/rune/src/runtime/vm_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ impl VmError {
pub(crate) fn into_kind(self) -> VmErrorKind {
self.inner.error.kind
}

#[cfg(test)]
pub(crate) fn as_kind(&self) -> &VmErrorKind {
&self.inner.error.kind
}
}

impl fmt::Display for VmError {
Expand Down Expand Up @@ -446,6 +441,26 @@ impl RuntimeError {
})
}

/// Construct an expected error for a variant.
pub(crate) fn expected_variant(actual: TypeInfo) -> Self {
Self::new(VmErrorKind::ExpectedVariant { actual })
}

/// Construct an expected expecting a unit struct.
pub(crate) fn expected_unit_struct(actual: TypeInfo) -> Self {
Self::new(VmErrorKind::ExpectedUnitStruct { actual })
}

/// Construct an expected expecting a tuple struct.
pub(crate) fn expected_tuple_struct(actual: TypeInfo) -> Self {
Self::new(VmErrorKind::ExpectedTupleStruct { actual })
}

/// Construct an expected expecting a struct.
pub(crate) fn expected_struct(actual: TypeInfo) -> Self {
Self::new(VmErrorKind::ExpectedStruct { actual })
}

/// Construct an expected error from any.
pub(crate) fn expected_any<T>(actual: TypeInfo) -> Self
where
Expand Down Expand Up @@ -819,6 +834,15 @@ pub(crate) enum VmErrorKind {
ExpectedVariant {
actual: TypeInfo,
},
ExpectedUnitStruct {
actual: TypeInfo,
},
ExpectedTupleStruct {
actual: TypeInfo,
},
ExpectedStruct {
actual: TypeInfo,
},
UnsupportedObjectFieldGet {
target: TypeInfo,
},
Expand Down Expand Up @@ -1026,6 +1050,15 @@ impl fmt::Display for VmErrorKind {
VmErrorKind::ExpectedVariant { actual } => {
write!(f, "Expected an enum variant, but got `{actual}`")
}
VmErrorKind::ExpectedUnitStruct { actual } => {
write!(f, "Expected a unit struct, but got `{actual}`")
}
VmErrorKind::ExpectedTupleStruct { actual } => {
write!(f, "Expected a tuple struct, but got `{actual}`")
}
VmErrorKind::ExpectedStruct { actual } => {
write!(f, "Expected a struct, but got `{actual}`")
}
VmErrorKind::UnsupportedObjectFieldGet { target } => write!(
f,
"The object field get operation is not supported on `{target}`",
Expand Down
Loading

0 comments on commit 8ff7a56

Please sign in to comment.