+
Skip to content
This repository was archived by the owner on Aug 31, 2023. It is now read-only.

Replace unsafe rome_diagnostics::Error implementation with double-Box #4240

Merged
merged 1 commit into from
Feb 27, 2023

Conversation

andersk
Copy link
Contributor

@andersk andersk commented Feb 25, 2023

Summary

The stated reason for this unsafe code was to avoid bloating the size of Result<T, Error>, since Box<dyn Diagnostic> would be a fat pointer. But Box<Box<dyn Diagnostic>>, a thin pointer to a fat pointer, acomplishes the same goal safely. We don’t have millions of Errors in the common case, so this seems like a better tradeoff than maintaining unsafe code here.

Test Plan

Ran the test suite. Two of the tests in rome_diagnostics::error::tests make assertions about the sizes of Error and Result<(), Error>, and continue to pass.

Documentation

  • The PR requires documentation
  • I will create a new PR to update the documentation

@netlify
Copy link

netlify bot commented Feb 25, 2023

Deploy Preview for docs-rometools canceled.

Built without sensitive environment variables

Name Link
🔨 Latest commit 109cdab
🔍 Latest deploy log https://app.netlify.com/sites/docs-rometools/deploys/63fa606beff0c8000867015e

The stated reason for this `unsafe` code was to avoid bloating the
size of `Result<T, Error>`, since `Box<dyn Diagnostic>` would be a fat
pointer.  But `Box<Box<dyn Diagnostic>>`, a thin pointer to a fat
pointer, acomplishes the same goal safely.  We don’t have millions of
`Error`s in the common case, so this seems like a better tradeoff than
maintaining `unsafe` code here.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
@ematipico
Copy link
Contributor

As pointed out in the comments of type, one thing we wanted to do later on was to implement Copy and/or Clone for Error. Something that it's possible to do with the previous implementation, although it requires more unsafe code.

How flexible/permissive is this proposed solution?

@andersk
Copy link
Contributor Author

andersk commented Feb 26, 2023

The std::io::Error wrapped in rome_diagnostics::adapters::IoError is not Clone, nor is the Box<dyn std::error::Error> wrapped in rome_diagnostics::adapters::StdError. So neither the current unsafe solution nor this Box<Box<dyn Diagnostic>> solution can be made Clone as written.

However, we could switch to Arc<Box<dyn Diagnostic>> or Box<Arc<dyn Diagnostic>> if we wanted to. Arc is Clone even if its contents aren’t.

@andersk
Copy link
Contributor Author

andersk commented Feb 26, 2023

Alternatively, if we wrap just std::io::Error and dyn std::error::Error in Arc to make IoError and StdError implement Clone, then we can implement Clone for Error just by adding this method to Diagnostic:

pub trait Diagnostic: Debug {fn to_owned_diagnostic<'a>(&self) -> Box<dyn Diagnostic + Send + Sync + 'a>
    where
        Self: Send + Sync + 'a;
}

Proof of concept: andersk@clone-error.

I’m not sure whether there’s an advantage to doing it this way; depends on what you want Clone for I guess. But it’s possible at least.

@ematipico
Copy link
Contributor

ematipico commented Feb 27, 2023

Great proof of concept @andersk ! Thank you very much for taking the time to look into it!

Having Clone for Error is not a high priority, but there have been cases where they would have been nice to have.

Inside the analyzer infrastructure, we have the concept of "signals". Signals are simply closures stored while analyzing some code, and eventually, we call these closures and use their result. Among these signals, we also have diagnostics, and there have been cases where a .clone() was nice to have, but I managed to make it work.

I think we can hold off on the Clone implementation for now, but it's good to know that we can implement it if needed!

@ematipico ematipico added this pull request to the merge queue Feb 27, 2023
Merged via the queue into rome:main with commit eb20b36 Feb 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载