-
Notifications
You must be signed in to change notification settings - Fork 169
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
Changed return_ref
syntax to returns(as_ref)
and returns(cloned)
#772
base: master
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for salsa-rs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
CodSpeed Performance ReportMerging #772 will not alter performanceComparing Summary
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change itself looks good to me. However, I realised that it isn't entirely clear to me how we'd implement as_deref
because it would require knowing the return type (Option<Name>
where Name
has a Deref implementation to str
returns a &str
and this isn't something that salsa can easily infer).
That makes me think that it might be good to add as_deref
support as part of this PR, to ensure that the new syntax is flexible enough (I don't want to make this migration twice 😅)
A possible syntax could be returns(as_deref = &str)
I would have assumed it would work the same way Honestly, I didn't even consider Another option I considered is to instead implement something like |
Yes, it should work the same as Oh, I see, yes my example was incorrect. It should return Hmm, we might need to think a bit more about the desired API. It would be nice if we didn't have to special case |
Just to clarify on From my quick browsing of the std-lib, So we could special case it, or, like you suggested, use a custom trait. That may also be able to cover other custom mappings that a user might want to provide. pub trait AsDeref {
type Target<'a>;
fn as_deref(&self) -> T::Target<'a>;
} should in principle cover all allowed transformations (not just |
This would be a lot easier with spezialitation 😅 |
I think you both already agreed on it but I'll just put down my coarse view on it (partially rehashing what was already said)
Naming bikeshed: Should it be
This sounds generally nice to have and I think can also just be modeled with a simple trait that we can provide a derive for which would basically look the same trait SalsaReturnTransform<'db> {
type Transformed;
fn as_ref(&'db self) -> Transformed;
} (I think a GAT would be less flexible here than tying the database lifetime to the trait impl, not 100% sure though) |
Seems about right, yeah.
I would rather wrap the value using something like
I agree, it should be the latter, via a custom trait.
Regarding Also there still needs to be a decision on the default: I believe that |
I have now implemented Once we've decided on the default (I'm still undecided between |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. This looks good to me. I'd prefer if someone else good quickly glance over it to confirm that they agree with the overall approach.
Could you add a test that demonstrates thtat the following doesn't compile: returns(not_a_return_mode)
.
I'd be okay if we switch the default in a separate PR
/// | ||
/// Used when generating field getters. | ||
#[macro_export] | ||
macro_rules! return_mode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: maybe return_expression
and return_expression_ty
or result_ty
and result_expression
?
/// Generate either `field_ref_expr` or a clone of that expr. | ||
/// | ||
/// Used when generating field getters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation here needs updating
|
||
use std::ops::Deref; | ||
|
||
pub trait SalsaAsRef { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to have some more documentation for those public types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I try to avoid traits
modules because it suggests that all traits are in this module (they're not). Maybe return
, as
, return_mode
?
As discussed in #719 , I figured I'd give this a go.
It was about as straightforward as I expected, with about as much problems as I anticipated.
Basically, I replaced the
return_ref
syntax withreturns(as_ref)
. This allows other return modes to be specified as well, like the current default ofreturns(cloned)
.I used
returns
instead ofreturn
, because using#[return(ref)]
already fails pre-macro expansion, sincereturn
is a keyword. I usedas_ref
instead ofref
, because it required less rewrite of the macros. It's possible to useref
, but I didn't bother with it for now. I usedcloned
instead ofclone
, since it felt more analogous toas_ref
(compare withOption::as_ref
andOption::cloned
).Since this was my first time browsing this code base, I wasn't entirely sure how hacky is too hacky. I think it's not too bad, other than the reuse of
maybe_clone
(which I renamed toreturn_mode
), since I didn't want to duplicate the code.I don't necessarily expect this to be merged, but I wanted to share the results of my experiment.
I also didn't change the defaults away from clone yet, since updating all the tests seems like an annoying chore that I'd rather only do once it's decided on.