diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-11-04 18:12:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-04 18:12:48 +0100 |
| commit | a4f323ce9c00a1a51eae998c373103e23b622a7a (patch) | |
| tree | 0788c16493dc1a71ea5277855be55abb0eaf06af /tests/ui | |
| parent | 46ae1555e26d0bc39651cdb249b2ae740d46f3a3 (diff) | |
| parent | 5a48fe2c202a7aff935daf6b7cc56a12ad0ae72a (diff) | |
| download | rust-a4f323ce9c00a1a51eae998c373103e23b622a7a.tar.gz rust-a4f323ce9c00a1a51eae998c373103e23b622a7a.zip | |
Rollup merge of #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.
Diffstat (limited to 'tests/ui')
9 files changed, 116 insertions, 0 deletions
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr index e56af28f3fb..be17476524a 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr @@ -15,6 +15,10 @@ note: required by a bound in `check` | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` +help: use a unary tuple instead + | +LL | check(((),)); + | + ++ error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr index 629fc59361d..ca9a6ebc1c4 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr @@ -12,6 +12,10 @@ note: required by a bound in `check` | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` +help: use a unary tuple instead + | +LL | check(((),)); + | + ++ error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr index 629fc59361d..ca9a6ebc1c4 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr @@ -12,6 +12,10 @@ note: required by a bound in `check` | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` +help: use a unary tuple instead + | +LL | check(((),)); + | + ++ error: aborting due to 1 previous error diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr index cceaddf7803..206a6801065 100644 --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -71,6 +71,10 @@ LL | cachedcoso.call_once(1); | note: required by a bound in `call_once` --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: use a unary tuple instead + | +LL | cachedcoso.call_once((1,)); + | + ++ error: aborting due to 6 previous errors diff --git a/tests/ui/on-unimplemented/suggest_tuple_wrap.rs b/tests/ui/on-unimplemented/suggest_tuple_wrap.rs new file mode 100644 index 00000000000..010a47aef62 --- /dev/null +++ b/tests/ui/on-unimplemented/suggest_tuple_wrap.rs @@ -0,0 +1,19 @@ +pub trait Argument {} +impl Argument for u8 {} +impl Argument for i8 {} +impl Argument for String {} +impl Argument for &str {} + +pub trait TupleArgs {} +impl<A: Argument> TupleArgs for (A,) {} +impl<A: Argument, B: Argument> TupleArgs for (A, B) {} +impl<A: Argument, B: Argument, C: Argument> TupleArgs for (A, B, C) {} + +fn convert_into_tuple(_x: impl TupleArgs) {} + +fn main() { + convert_into_tuple(42_u8); + //~^ ERROR E0277 + //~| HELP the following other types implement trait `TupleArgs` + //~| HELP use a unary tuple instead +} diff --git a/tests/ui/on-unimplemented/suggest_tuple_wrap.stderr b/tests/ui/on-unimplemented/suggest_tuple_wrap.stderr new file mode 100644 index 00000000000..93dd43aafd9 --- /dev/null +++ b/tests/ui/on-unimplemented/suggest_tuple_wrap.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `u8: TupleArgs` is not satisfied + --> $DIR/suggest_tuple_wrap.rs:15:24 + | +LL | convert_into_tuple(42_u8); + | ------------------ ^^^^^ the trait `TupleArgs` is not implemented for `u8` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `TupleArgs`: + (A, B) + (A, B, C) + (A,) +note: required by a bound in `convert_into_tuple` + --> $DIR/suggest_tuple_wrap.rs:12:32 + | +LL | fn convert_into_tuple(_x: impl TupleArgs) {} + | ^^^^^^^^^ required by this bound in `convert_into_tuple` +help: use a unary tuple instead + | +LL | convert_into_tuple((42_u8,)); + | + ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs new file mode 100644 index 00000000000..e0036d30187 --- /dev/null +++ b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs @@ -0,0 +1,26 @@ +struct Tuple; + +impl From<(u8,)> for Tuple { + fn from(_: (u8,)) -> Self { + todo!() + } +} +impl From<(u8, u8)> for Tuple { + fn from(_: (u8, u8)) -> Self { + todo!() + } +} +impl From<(u8, u8, u8)> for Tuple { + fn from(_: (u8, u8, u8)) -> Self { + todo!() + } +} + +fn convert_into_tuple(_x: impl Into<Tuple>) {} + +fn main() { + convert_into_tuple(42_u8); + //~^ ERROR E0277 + //~| HELP use a unary tuple instead + //~| HELP the following other types implement trait `From<T>` +} diff --git a/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr new file mode 100644 index 00000000000..6ee08d2cd1b --- /dev/null +++ b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr @@ -0,0 +1,26 @@ +error[E0277]: the trait bound `Tuple: From<u8>` is not satisfied + --> $DIR/suggest_tuple_wrap_root_obligation.rs:22:24 + | +LL | convert_into_tuple(42_u8); + | ------------------ ^^^^^ the trait `From<u8>` is not implemented for `Tuple` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `From<T>`: + `Tuple` implements `From<(u8, u8)>` + `Tuple` implements `From<(u8, u8, u8)>` + `Tuple` implements `From<(u8,)>` + = note: required for `u8` to implement `Into<Tuple>` +note: required by a bound in `convert_into_tuple` + --> $DIR/suggest_tuple_wrap_root_obligation.rs:19:32 + | +LL | fn convert_into_tuple(_x: impl Into<Tuple>) {} + | ^^^^^^^^^^^ required by this bound in `convert_into_tuple` +help: use a unary tuple instead + | +LL | convert_into_tuple((42_u8,)); + | + ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.stderr b/tests/ui/overloaded/overloaded-calls-nontuple.stderr index 45a84fc4d7b..22598f3a390 100644 --- a/tests/ui/overloaded/overloaded-calls-nontuple.stderr +++ b/tests/ui/overloaded/overloaded-calls-nontuple.stderr @@ -38,6 +38,10 @@ LL | self.call_mut(z) | note: required by a bound in `call_mut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: use a unary tuple instead + | +LL | self.call_mut((z,)) + | + ++ error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit --> $DIR/overloaded-calls-nontuple.rs:29:10 |
