Skip to content

Commit 6b1bceb

Browse files
committed
Replace OwnedApp Deref with explicit 'borrowed' method
The Deref impl used a scary unsafe lifetype cast which was hard to reason about and unsound for use within the spin-app crate. Signed-off-by: Lann Martin <lann.martin@fermyon.com>
1 parent 2f60a5d commit 6b1bceb

File tree

2 files changed

+9
-13
lines changed

2 files changed

+9
-13
lines changed

crates/app/src/lib.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,9 @@ pub struct OwnedApp {
8787
app: App<'this>,
8888
}
8989

90-
impl std::ops::Deref for OwnedApp {
91-
type Target = App<'static>;
92-
93-
fn deref(&self) -> &Self::Target {
94-
unsafe {
95-
// We know that App's lifetime param is for AppLoader, which is owned by self here.
96-
std::mem::transmute::<&App, &App<'static>>(self.borrow_app())
97-
}
90+
impl OwnedApp {
91+
pub fn borrowed(&self) -> &App {
92+
self.borrow_app()
9893
}
9994
}
10095

crates/trigger/src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl<Executor: TriggerExecutor> TriggerExecutorBuilder<Executor> {
110110
};
111111

112112
let app = self.loader.load_owned_app(app_uri).await?;
113-
let app_name = app.require_metadata("name")?;
113+
let app_name = app.borrowed().require_metadata("name")?;
114114

115115
let log_dir = {
116116
let sanitized_app = sanitize_filename::sanitize(&app_name);
@@ -176,6 +176,7 @@ impl<Executor: TriggerExecutor> TriggerAppEngine<Executor> {
176176
<Executor as TriggerExecutor>::TriggerConfig: DeserializeOwned,
177177
{
178178
let trigger_configs = app
179+
.borrowed()
179180
.triggers_with_type(Executor::TRIGGER_TYPE)
180181
.map(|trigger| {
181182
trigger.typed_config().with_context(|| {
@@ -185,7 +186,7 @@ impl<Executor: TriggerExecutor> TriggerAppEngine<Executor> {
185186
.collect::<Result<_>>()?;
186187

187188
let mut component_instance_pres = HashMap::default();
188-
for component in app.components() {
189+
for component in app.borrowed().components() {
189190
let module = component.load_module(&engine).await?;
190191
let instance_pre = engine.instantiate_pre(&module)?;
191192
component_instance_pres.insert(component.id().to_string(), instance_pre);
@@ -204,12 +205,12 @@ impl<Executor: TriggerExecutor> TriggerAppEngine<Executor> {
204205

205206
/// Returns a reference to the App.
206207
pub fn app(&self) -> &App {
207-
&self.app
208+
self.app.borrowed()
208209
}
209210

210211
/// Returns AppTriggers and typed TriggerConfigs for this executor type.
211212
pub fn trigger_configs(&self) -> impl Iterator<Item = (AppTrigger, &Executor::TriggerConfig)> {
212-
self.app
213+
self.app()
213214
.triggers_with_type(Executor::TRIGGER_TYPE)
214215
.zip(&self.trigger_configs)
215216
}
@@ -257,7 +258,7 @@ impl<Executor: TriggerExecutor> TriggerAppEngine<Executor> {
257258
mut store_builder: StoreBuilder,
258259
) -> Result<(Instance, Store<Executor::RuntimeData>)> {
259260
// Look up AppComponent
260-
let component = self.app.get_component(component_id).with_context(|| {
261+
let component = self.app().get_component(component_id).with_context(|| {
261262
format!(
262263
"app {:?} has no component {:?}",
263264
self.app_name, component_id

0 commit comments

Comments
 (0)