-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Suggest creating unary tuples when types don't match a trait #132583
Conversation
r? @nnethercote rustbot has assigned @nnethercote. Use |
LL | check(((),)); | ||
| + ++ |
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.
Is this suggestion okay? I'm not quite sure what #[do_not_recommend]
is supposed to (not) show. Its rfc only talks about not mentioning confusing traits.
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.
I think it's fine.
This comment has been minimized.
This comment has been minimized.
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.
Otherwise LGTM
self.infcx.enter_forall(trait_ref, |trait_ref| { | ||
if self | ||
.type_implements_trait(trait_ref.def_id, trait_ref.args, root_obligation.param_env) | ||
.must_apply_modulo_regions() | ||
{ | ||
err.multipart_suggestion_verbose( | ||
format!("use a unary tuple instead"), | ||
vec![(span.shrink_to_lo(), "(".into()), (span.shrink_to_hi(), ",)".into())], | ||
Applicability::MaybeIncorrect, | ||
); | ||
} | ||
}); | ||
} |
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.
this is kinda unnecessary. instead of using enter_forall
and calling type_implements_trait
, just use predicate_must_hold_modulo_regions
.
obligation: &PredicateObligation<'tcx>, | ||
span: Span, | ||
) { | ||
if !matches!(obligation.cause.code(), ObligationCauseCode::FunctionArg { .. }) { |
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.
I would turn this into an if let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = ...
.
Then use the span from arg_hir_id
via tcx.hir.span(arg_hir_id)
. It may seem roundabout, but there's always a chance that the obligation span has been messed with, and getting the span from the actual arg expression is strictly more right...
@rustbot ready |
@bors r+ rollup |
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#132355 (Fix compiler panic with a large number of threads) - rust-lang#132486 (No need to instantiate binder in `confirm_async_closure_candidate`) - rust-lang#132544 (Use backticks instead of single quotes for library feature names in diagnostics) - rust-lang#132559 (find the generic container rather than simply looking up for the assoc with const arg) - rust-lang#132579 (add rustc std workspace crate sources) - rust-lang#132583 (Suggest creating unary tuples when types don't match a trait) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#132583 - mejrs:tuples, r=compiler-errors Suggest creating unary tuples when types don't match a trait When you want to have a variadic function, a common workaround to implement this is to create a trait and then implement that trait for various tuples. For example in `pyo3` there exists ```rust /// Calls the object with only positional arguments. pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> { ... } ``` with various impls like ```rust impl<A: IntoPy<PyObject> IntoPy<Py<PyAny>> for (A,) impl<A: IntoPy<PyObject, B: IntoPy<PyObject> IntoPy<Py<PyAny>> for (A, B) ... etc ``` This means that if you want to call the method with a single item you have to create a unary tuple, like `(x,)`, rather than just `x`. This PR implements a suggestion to do that, if applicable.
When you want to have a variadic function, a common workaround to implement this is to create a trait and then implement that trait for various tuples. For example in
pyo3
there existswith various impls like
This means that if you want to call the method with a single item you have to create a unary tuple, like
(x,)
, rather than justx
.This PR implements a suggestion to do that, if applicable.