-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Suggest method syntax x.max(y)
for unresolved max(x, y)
calls
#147102
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
base: master
Are you sure you want to change the base?
Conversation
personally I find the method usage of |
it more looks like a typo from people who came from other languages like python and do not know about method way which is more idiomatic in rust imo, so, I guess, such suggestion woudln't harm on top i can say it produce such suggestion between incomparable types, which may be missleading? im not sure if there an easy way to check if both types are implementing fn main() {
struct A;
let a = A;
max(a, 2);
}
|
let arg0 = self.r.tcx.sess.source_map().span_to_snippet(args[0].span).unwrap(); | ||
let arg1 = self.r.tcx.sess.source_map().span_to_snippet(args[1].span).unwrap(); |
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.
As a rule of thumb, please never unwrap span_to_snippet
, it can indeed fail.
Under your PR we likely crash under a scenario like (not tested):
// file `a.rs`
#[macro_export]
macro_rules! mk { () => { max(0, 0) } }
// file `b.rs`
fn main() {
a::mk!();
}
Then compile a.rs
and delete or move a.rs
and compile b.rs
with --extern a
.
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.
Instead of using span_to_snippet
, construct a multi-part suggestion that maps the span of min(
or max(
to empty and the span of ,
to .min(
or .max(
respectively. These subspans can be obtained via Span::{to,between,until}
etc. However, you'd probably still want to guard against differing expansion levels via eq_ctxt
(heavy hammer) or find_*_ancestor_*
(brittle).
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.
Independently, you gonna want to account for more complex expressions that need to be wrapped in parentheses. E.g: max(1 + 1, 0)
→ (1 + 1).max(0)
not 1 + 1.max(0)
.
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.
Hm, do you have idea how can I protect myself from more complex expressions like this, always wrap left part in parentheses? or there is something better I can do about it
Also about multi-part suggestion I'm not sure if I can use it here because as far I as remember it's something with vec of strings and the final type of variable that using here is like this Option<(&Span, &str, String)>
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.
Hm, do you have idea how can I protect myself from more complex expressions like this, always wrap left part in parentheses? or there is something better I can do about it
Yes, you can :) since we're trying to construct a method call, if first_arg.precedence() < ExprPrecedence::Unambiguous
it needs parentheses, otherwise it doesn't. That's a good approximation that's also used by rustc_ast_pretty
essentially.
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.
Also about multi-part suggestion I'm not sure if I can use it here
Arf, that's annoying; in that case only suggest something if both span_to_snippet
s are Ok(_)
.
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.
Yep, I guess I can even add this inside let chains, right after a some zulip poll if we decide on necessity of this diagnostics
I disagree, I prefer the function form over the method form (because of the mentioned asymmetry) |
Before proceeding, we should agree on whether this diagnostic adds value. Since I've only spent about 15 minutes on it so far, I'm fine with closing it if we decide it's not needed So would be nice if we could collect some more opinions |
The change adds a suggestion for an alternative (and in the diagnostic, encouraged) way to use method syntax for min/max when someone tried to use the min/max functions. So really it's a question of style. I prefer the free functions, but I'd suggest making a poll in general on Zulip to gather some other opinions if you think the method style is better or at least has some merit. |
Fixes #76386
r? compiler