Skip to content

Commit c8642da

Browse files
committed
Auto merge of #44191 - arielb1:on-unimplemented-label, r=nikomatsakis
More general `on_unimplemented`, with uses in `Try` Allow `on_unimplemented` directives to specify both the label and the primary message of the trait error, and allow them to be controlled by flags - currently only to be desugaring-sensitive. e.g. ```Rust #[rustc_on_unimplemented( on(all(direct, from_desugaring="?"), message="the `?` operator can only be used in a \ function that returns `Result` \ (or another type that implements `{Try}`)", label="cannot use the `?` operator in a function that returns `{Self}`"), )] ``` r? @nikomatsakis
2 parents 2f2b8b3 + 291b4ed commit c8642da

File tree

15 files changed

+652
-275
lines changed

15 files changed

+652
-275
lines changed

src/libcore/ops/try.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,24 @@
1515
/// extracting those success or failure values from an existing instance and
1616
/// creating a new instance from a success or failure value.
1717
#[unstable(feature = "try_trait", issue = "42327")]
18-
#[rustc_on_unimplemented = "the `?` operator can only be used in a function that returns `Result` \
19-
(or another type that implements `{Try}`)"]
18+
#[cfg_attr(stage0,
19+
rustc_on_unimplemented = "the `?` operator can only be used in a \
20+
function that returns `Result` \
21+
(or another type that implements `{Try}`)")]
22+
#[cfg_attr(not(stage0),
23+
rustc_on_unimplemented(
24+
on(all(
25+
any(from_method="from_error", from_method="from_ok"),
26+
from_desugaring="?"),
27+
message="the `?` operator can only be used in a \
28+
function that returns `Result` \
29+
(or another type that implements `{Try}`)",
30+
label="cannot use the `?` operator in a function that returns `{Self}`"),
31+
on(all(from_method="into_result", from_desugaring="?"),
32+
message="the `?` operator can only be applied to values \
33+
that implement `{Try}`",
34+
label="the `?` operator cannot be applied to type `{Self}`")
35+
))]
2036
pub trait Try {
2137
/// The type of this value when viewed as successful.
2238
#[unstable(feature = "try_trait", issue = "42327")]

src/librustc/diagnostics.rs

+92-88
Original file line numberDiff line numberDiff line change
@@ -688,8 +688,8 @@ See also https://doc.rust-lang.org/book/first-edition/no-stdlib.html
688688
"##,
689689

690690
E0214: r##"
691-
A generic type was described using parentheses rather than angle brackets. For
692-
example:
691+
A generic type was described using parentheses rather than angle brackets.
692+
For example:
693693
694694
```compile_fail,E0214
695695
fn main() {
@@ -702,6 +702,93 @@ Parentheses are currently only used with generic types when defining parameters
702702
for `Fn`-family traits.
703703
"##,
704704

705+
E0230: r##"
706+
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
707+
message for when a particular trait isn't implemented on a type placed in a
708+
position that needs that trait. For example, when the following code is
709+
compiled:
710+
711+
```compile_fail
712+
#![feature(on_unimplemented)]
713+
714+
fn foo<T: Index<u8>>(x: T){}
715+
716+
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
717+
trait Index<Idx> { /* ... */ }
718+
719+
foo(true); // `bool` does not implement `Index<u8>`
720+
```
721+
722+
There will be an error about `bool` not implementing `Index<u8>`, followed by a
723+
note saying "the type `bool` cannot be indexed by `u8`".
724+
725+
As you can see, you can specify type parameters in curly braces for
726+
substitution with the actual types (using the regular format string syntax) in
727+
a given situation. Furthermore, `{Self}` will substitute to the type (in this
728+
case, `bool`) that we tried to use.
729+
730+
This error appears when the curly braces contain an identifier which doesn't
731+
match with any of the type parameters or the string `Self`. This might happen
732+
if you misspelled a type parameter, or if you intended to use literal curly
733+
braces. If it is the latter, escape the curly braces with a second curly brace
734+
of the same type; e.g. a literal `{` is `{{`.
735+
"##,
736+
737+
E0231: r##"
738+
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
739+
message for when a particular trait isn't implemented on a type placed in a
740+
position that needs that trait. For example, when the following code is
741+
compiled:
742+
743+
```compile_fail
744+
#![feature(on_unimplemented)]
745+
746+
fn foo<T: Index<u8>>(x: T){}
747+
748+
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
749+
trait Index<Idx> { /* ... */ }
750+
751+
foo(true); // `bool` does not implement `Index<u8>`
752+
```
753+
754+
there will be an error about `bool` not implementing `Index<u8>`, followed by a
755+
note saying "the type `bool` cannot be indexed by `u8`".
756+
757+
As you can see, you can specify type parameters in curly braces for
758+
substitution with the actual types (using the regular format string syntax) in
759+
a given situation. Furthermore, `{Self}` will substitute to the type (in this
760+
case, `bool`) that we tried to use.
761+
762+
This error appears when the curly braces do not contain an identifier. Please
763+
add one of the same name as a type parameter. If you intended to use literal
764+
braces, use `{{` and `}}` to escape them.
765+
"##,
766+
767+
E0232: r##"
768+
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
769+
message for when a particular trait isn't implemented on a type placed in a
770+
position that needs that trait. For example, when the following code is
771+
compiled:
772+
773+
```compile_fail
774+
#![feature(on_unimplemented)]
775+
776+
fn foo<T: Index<u8>>(x: T){}
777+
778+
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
779+
trait Index<Idx> { /* ... */ }
780+
781+
foo(true); // `bool` does not implement `Index<u8>`
782+
```
783+
784+
there will be an error about `bool` not implementing `Index<u8>`, followed by a
785+
note saying "the type `bool` cannot be indexed by `u8`".
786+
787+
For this to work, some note must be specified. An empty attribute will not do
788+
anything, please remove the attribute or add some helpful note for users of the
789+
trait.
790+
"##,
791+
705792
E0261: r##"
706793
When using a lifetime like `'a` in a type, it must be declared before being
707794
used.
@@ -917,92 +1004,6 @@ for v in &vs {
9171004
```
9181005
"##,
9191006

920-
E0272: r##"
921-
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
922-
message for when a particular trait isn't implemented on a type placed in a
923-
position that needs that trait. For example, when the following code is
924-
compiled:
925-
926-
```compile_fail
927-
#![feature(on_unimplemented)]
928-
929-
fn foo<T: Index<u8>>(x: T){}
930-
931-
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
932-
trait Index<Idx> { /* ... */ }
933-
934-
foo(true); // `bool` does not implement `Index<u8>`
935-
```
936-
937-
There will be an error about `bool` not implementing `Index<u8>`, followed by a
938-
note saying "the type `bool` cannot be indexed by `u8`".
939-
940-
As you can see, you can specify type parameters in curly braces for
941-
substitution with the actual types (using the regular format string syntax) in
942-
a given situation. Furthermore, `{Self}` will substitute to the type (in this
943-
case, `bool`) that we tried to use.
944-
945-
This error appears when the curly braces contain an identifier which doesn't
946-
match with any of the type parameters or the string `Self`. This might happen
947-
if you misspelled a type parameter, or if you intended to use literal curly
948-
braces. If it is the latter, escape the curly braces with a second curly brace
949-
of the same type; e.g. a literal `{` is `{{`.
950-
"##,
951-
952-
E0273: r##"
953-
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
954-
message for when a particular trait isn't implemented on a type placed in a
955-
position that needs that trait. For example, when the following code is
956-
compiled:
957-
958-
```compile_fail
959-
#![feature(on_unimplemented)]
960-
961-
fn foo<T: Index<u8>>(x: T){}
962-
963-
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
964-
trait Index<Idx> { /* ... */ }
965-
966-
foo(true); // `bool` does not implement `Index<u8>`
967-
```
968-
969-
there will be an error about `bool` not implementing `Index<u8>`, followed by a
970-
note saying "the type `bool` cannot be indexed by `u8`".
971-
972-
As you can see, you can specify type parameters in curly braces for
973-
substitution with the actual types (using the regular format string syntax) in
974-
a given situation. Furthermore, `{Self}` will substitute to the type (in this
975-
case, `bool`) that we tried to use.
976-
977-
This error appears when the curly braces do not contain an identifier. Please
978-
add one of the same name as a type parameter. If you intended to use literal
979-
braces, use `{{` and `}}` to escape them.
980-
"##,
981-
982-
E0274: r##"
983-
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
984-
message for when a particular trait isn't implemented on a type placed in a
985-
position that needs that trait. For example, when the following code is
986-
compiled:
987-
988-
```compile_fail
989-
#![feature(on_unimplemented)]
990-
991-
fn foo<T: Index<u8>>(x: T){}
992-
993-
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
994-
trait Index<Idx> { /* ... */ }
995-
996-
foo(true); // `bool` does not implement `Index<u8>`
997-
```
998-
999-
there will be an error about `bool` not implementing `Index<u8>`, followed by a
1000-
note saying "the type `bool` cannot be indexed by `u8`".
1001-
1002-
For this to work, some note must be specified. An empty attribute will not do
1003-
anything, please remove the attribute or add some helpful note for users of the
1004-
trait.
1005-
"##,
10061007

10071008
E0275: r##"
10081009
This error occurs when there was a recursive trait requirement that overflowed
@@ -2011,6 +2012,9 @@ register_diagnostics! {
20112012
// E0102, // replaced with E0282
20122013
// E0134,
20132014
// E0135,
2015+
// E0272, // on_unimplemented #0
2016+
// E0273, // on_unimplemented #1
2017+
// E0274, // on_unimplemented #2
20142018
E0278, // requirement is not satisfied
20152019
E0279, // requirement is not satisfied
20162020
E0280, // requirement is not satisfied

0 commit comments

Comments
 (0)