-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a pessimistic Backtrace type #88
Comments
I guess this would be accomplished with the derive macro. I have written a macro that can be used on a type and if the type implements a certain trait then it can do something with that trait. Here is all the code I wrote when testing out how this could work. It became quite a lot of code so here is a simplified version that includes as little unnecessary code as possible. Edit: Here is an even simpler version of the code. It's macro doesn't create a new scope via a module because of the limitations that I discuss in the Code explanationThe code works using "resolver" structs that has a method that takes an error and returns its backtrace. The structs contain a The code uses the The macro has the constraint that it requires that no conflicting traits are in scope. Conflicting traits are traits that are implemented for the resolver and that provides a method with the same name that is used for the method that gets the backtrace from an error. I can see two ways to work around that issue:
Creating a new scope with a moduleAfter some more consideration the first solution (using a module to get a new scope) seems to have some issues. It looks like if a struct is defined inside a function then it can't be referenced from anywhere else. If this is true then it is not possible to write a macro that works for every struct using the first method. Example code: fn module_scope() {
struct Test;
mod inner {
// Won't compile:
// fn take(_: super::Test) { }
// Won't compile:
// fn take(_: super::module_scope::Test) { }
// Won't compile:
// fn take(_: Test) { }
}
} Edit: Workaround that allows creating a new scope with a moduleAfter some more thought and experimentation it is possible to refer directly to the user provided type from inside a new module, this would make the macro work in all situations. This is some code that demonstrates how to safely reference a type inside the new module: fn module_scope() {
struct Test;
impl Test {
fn test(&self) -> usize {151}
}
impl inner::GetTarget for () {
type Target = Test;
}
mod inner {
pub(super) trait GetTarget {
type Target;
}
pub(super) fn take(x: <() as GetTarget>::Target) {
// User traits aren't in scope but its still possible to refer directly to the user provided type:
assert_eq!(x.test(), 151);
}
}
inner::take(Test);
} With this method its possible to make a macro that gets a backtrace if a type implements |
Wow, that's a lot of hard work (and code)! Maybe I was a bit optimistic that this would be an "easy" addition! I was thinking something along the lines of this. TL;DR, we do need some help from the derive macro to appropriately call What do you think? |
Your code assumes that the source error implements the One way to be able to always generate the source backtrace checking code is if specialization is used to allow a blanket implementation of My code is a hack for specialization that allows the code to work even if the source error doesn't implement Edit: After some more thought I understand what you really mean now. You want the user to specify the |
It's hard to tell if a foreign error type has a backtrace or not. If it does, we don't want to create our own, otherwise we do.
It could be interesting to try and have some type that checks if the underlying error has a backtrace. If so, it does nothing. Otherwise, it generates one at that point.
The text was updated successfully, but these errors were encountered: