Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit aad59a3

Browse files
authoredApr 19, 2025
Rollup merge of #139091 - mejrs:format, r=compiler-errors
Rewrite on_unimplemented format string parser. This PR rewrites the format string parser for `rustc_on_unimplemented` and `diagnostic::on_unimplemented`. I plan on moving this code (and more) into the new attribute parsing system soon and wanted to PR it separately. This PR introduces some minor differences though: - `rustc_on_unimplemented` on trait *implementations* is no longer checked/used - this is actually never used (outside of some tests) so I plan on removing it in the future. - for `rustc_on_unimplemented`, it introduces the `{This}` argument in favor of `{ThisTraitname}` (to be removed later). It'll be easier to parse. - for `rustc_on_unimplemented`, `Self` can now consistently be used as a filter, rather than just `_Self`. It used to not match correctly on for example `Self = "[{integer}]"` - Some error messages now have better spans. Fixes #130627
2 parents 237064a + 4a5369b commit aad59a3

25 files changed

+962
-685
lines changed
 

‎compiler/rustc_span/src/hygiene.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,25 @@ impl DesugaringKind {
12321232
DesugaringKind::PatTyRange => "pattern type",
12331233
}
12341234
}
1235+
1236+
/// For use with `rustc_unimplemented` to support conditions
1237+
/// like `from_desugaring = "QuestionMark"`
1238+
pub fn matches(&self, value: &str) -> bool {
1239+
match self {
1240+
DesugaringKind::CondTemporary => value == "CondTemporary",
1241+
DesugaringKind::Async => value == "Async",
1242+
DesugaringKind::Await => value == "Await",
1243+
DesugaringKind::QuestionMark => value == "QuestionMark",
1244+
DesugaringKind::TryBlock => value == "TryBlock",
1245+
DesugaringKind::YeetExpr => value == "YeetExpr",
1246+
DesugaringKind::OpaqueTy => value == "OpaqueTy",
1247+
DesugaringKind::ForLoop => value == "ForLoop",
1248+
DesugaringKind::WhileLoop => value == "WhileLoop",
1249+
DesugaringKind::BoundModifier => value == "BoundModifier",
1250+
DesugaringKind::Contract => value == "Contract",
1251+
DesugaringKind::PatTyRange => value == "PatTyRange",
1252+
}
1253+
}
12351254
}
12361255

12371256
#[derive(Default)]

‎compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ symbols! {
372372
SyncUnsafeCell,
373373
T,
374374
Target,
375+
This,
375376
ToOwned,
376377
ToString,
377378
TokenStream,

‎compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ pub mod ambiguity;
22
pub mod call_kind;
33
mod fulfillment_errors;
44
pub mod on_unimplemented;
5+
pub mod on_unimplemented_condition;
6+
pub mod on_unimplemented_format;
57
mod overflow;
68
pub mod suggestions;
79

‎compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs

Lines changed: 253 additions & 368 deletions
Large diffs are not rendered by default.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use rustc_ast::MetaItemInner;
2+
use rustc_attr_parsing as attr;
3+
use rustc_middle::ty::{self, TyCtxt};
4+
use rustc_parse_format::{ParseMode, Parser, Piece, Position};
5+
use rustc_span::{DesugaringKind, Span, Symbol, kw, sym};
6+
7+
/// A predicate in an attribute using on, all, any,
8+
/// similar to a cfg predicate.
9+
#[derive(Debug)]
10+
pub struct Condition {
11+
pub inner: MetaItemInner,
12+
}
13+
14+
impl Condition {
15+
pub fn span(&self) -> Span {
16+
self.inner.span()
17+
}
18+
19+
pub fn matches_predicate<'tcx>(&self, tcx: TyCtxt<'tcx>, options: &ConditionOptions) -> bool {
20+
attr::eval_condition(&self.inner, tcx.sess, Some(tcx.features()), &mut |cfg| {
21+
let value = cfg.value.map(|v| {
22+
// `with_no_visible_paths` is also used when generating the options,
23+
// so we need to match it here.
24+
ty::print::with_no_visible_paths!({
25+
Parser::new(v.as_str(), None, None, false, ParseMode::Format)
26+
.map(|p| match p {
27+
Piece::Lit(s) => s.to_owned(),
28+
Piece::NextArgument(a) => match a.position {
29+
Position::ArgumentNamed(arg) => {
30+
let s = Symbol::intern(arg);
31+
match options.generic_args.iter().find(|(k, _)| *k == s) {
32+
Some((_, val)) => val.to_string(),
33+
None => format!("{{{arg}}}"),
34+
}
35+
}
36+
Position::ArgumentImplicitlyIs(_) => String::from("{}"),
37+
Position::ArgumentIs(idx) => format!("{{{idx}}}"),
38+
},
39+
})
40+
.collect()
41+
})
42+
});
43+
44+
options.contains(cfg.name, &value)
45+
})
46+
}
47+
}
48+
49+
/// Used with `Condition::matches_predicate` to test whether the condition applies
50+
///
51+
/// For example, given a
52+
/// ```rust,ignore (just an example)
53+
/// #[rustc_on_unimplemented(
54+
/// on(all(from_desugaring = "QuestionMark"),
55+
/// message = "the `?` operator can only be used in {ItemContext} \
56+
/// that returns `Result` or `Option` \
57+
/// (or another type that implements `{FromResidual}`)",
58+
/// label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
59+
/// parent_label = "this function should return `Result` or `Option` to accept `?`"
60+
/// ),
61+
/// )]
62+
/// pub trait FromResidual<R = <Self as Try>::Residual> {
63+
/// ...
64+
/// }
65+
///
66+
/// async fn an_async_function() -> u32 {
67+
/// let x: Option<u32> = None;
68+
/// x?; //~ ERROR the `?` operator
69+
/// 22
70+
/// }
71+
/// ```
72+
/// it will look like this:
73+
///
74+
/// ```rust,ignore (just an example)
75+
/// ConditionOptions {
76+
/// self_types: ["u32", "{integral}"],
77+
/// from_desugaring: Some("QuestionMark"),
78+
/// cause: None,
79+
/// crate_local: false,
80+
/// direct: true,
81+
/// generic_args: [("Self","u32"),
82+
/// ("R", "core::option::Option<core::convert::Infallible>"),
83+
/// ("R", "core::option::Option<T>" ),
84+
/// ],
85+
/// }
86+
/// ```
87+
#[derive(Debug)]
88+
pub struct ConditionOptions {
89+
/// All the self types that may apply.
90+
/// for example
91+
pub self_types: Vec<String>,
92+
// The kind of compiler desugaring.
93+
pub from_desugaring: Option<DesugaringKind>,
94+
/// Match on a variant of [rustc_infer::traits::ObligationCauseCode]
95+
pub cause: Option<String>,
96+
pub crate_local: bool,
97+
/// Is the obligation "directly" user-specified, rather than derived?
98+
pub direct: bool,
99+
// A list of the generic arguments and their reified types
100+
pub generic_args: Vec<(Symbol, String)>,
101+
}
102+
103+
impl ConditionOptions {
104+
pub fn contains(&self, key: Symbol, value: &Option<String>) -> bool {
105+
match (key, value) {
106+
(sym::_Self | kw::SelfUpper, Some(value)) => self.self_types.contains(&value),
107+
// from_desugaring as a flag
108+
(sym::from_desugaring, None) => self.from_desugaring.is_some(),
109+
// from_desugaring as key == value
110+
(sym::from_desugaring, Some(v)) if let Some(ds) = self.from_desugaring => ds.matches(v),
111+
(sym::cause, Some(value)) => self.cause.as_deref() == Some(value),
112+
(sym::crate_local, None) => self.crate_local,
113+
(sym::direct, None) => self.direct,
114+
(other, Some(value)) => {
115+
self.generic_args.iter().any(|(k, v)| *k == other && v == value)
116+
}
117+
_ => false,
118+
}
119+
}
120+
}

‎compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs

Lines changed: 414 additions & 0 deletions
Large diffs are not rendered by default.

‎src/tools/tidy/src/issues.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3138,7 +3138,6 @@ ui/nll/user-annotations/issue-55241.rs
31383138
ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs
31393139
ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs
31403140
ui/numbers-arithmetic/issue-8460.rs
3141-
ui/on-unimplemented/issue-104140.rs
31423141
ui/or-patterns/issue-64879-trailing-before-guard.rs
31433142
ui/or-patterns/issue-67514-irrefutable-param.rs
31443143
ui/or-patterns/issue-68785-irrefutable-param-with-at.rs

‎tests/crashes/130627.rs

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// used to ICE, see <https://github.com/rust-lang/rust/issues/130627>
2+
// Instead it should just ignore the diagnostic attribute
3+
#![feature(trait_alias)]
4+
5+
trait Test {}
6+
7+
#[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
8+
//~^ WARN `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
9+
trait Alias = Test;
10+
11+
// Use trait alias as bound on type parameter.
12+
fn foo<T: Alias>(v: &T) {}
13+
14+
pub fn main() {
15+
foo(&1);
16+
//~^ ERROR the trait bound `{integer}: Alias` is not satisfied
17+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
2+
--> $DIR/on_impl_trait.rs:7:1
3+
|
4+
LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
8+
9+
error[E0277]: the trait bound `{integer}: Alias` is not satisfied
10+
--> $DIR/on_impl_trait.rs:15:9
11+
|
12+
LL | foo(&1);
13+
| --- ^^ the trait `Test` is not implemented for `{integer}`
14+
| |
15+
| required by a bound introduced by this call
16+
|
17+
help: this trait has no implementations, consider adding one
18+
--> $DIR/on_impl_trait.rs:5:1
19+
|
20+
LL | trait Test {}
21+
| ^^^^^^^^^^
22+
= note: required for `{integer}` to implement `Alias`
23+
note: required by a bound in `foo`
24+
--> $DIR/on_impl_trait.rs:12:11
25+
|
26+
LL | fn foo<T: Alias>(v: &T) {}
27+
| ^^^^^ required by this bound in `foo`
28+
29+
error: aborting due to 1 previous error; 1 warning emitted
30+
31+
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
11
warning: unmatched `}` found
2-
--> $DIR/broken_format.rs:2:32
2+
--> $DIR/broken_format.rs:2:42
33
|
44
LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^
66
|
77
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
88

99
warning: positional format arguments are not allowed here
10-
--> $DIR/broken_format.rs:7:32
10+
--> $DIR/broken_format.rs:7:49
1111
|
1212
LL | #[diagnostic::on_unimplemented(message = "Test {}")]
13-
| ^^^^^^^^^^^^^^^^^^^
13+
| ^
1414
|
1515
= help: only named format arguments with the name of one of the generic types are allowed in this context
1616

1717
warning: positional format arguments are not allowed here
18-
--> $DIR/broken_format.rs:12:32
18+
--> $DIR/broken_format.rs:12:49
1919
|
2020
LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
21-
| ^^^^^^^^^^^^^^^^^^^^^
21+
| ^
2222
|
2323
= help: only named format arguments with the name of one of the generic types are allowed in this context
2424

2525
warning: invalid format specifier
26-
--> $DIR/broken_format.rs:17:32
26+
--> $DIR/broken_format.rs:17:42
2727
|
2828
LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
29+
| ^^^^^^^^^^^^^^^^^
3030
|
3131
= help: no format specifier are supported in this position
3232

3333
warning: expected `}`, found `!`
34-
--> $DIR/broken_format.rs:22:32
34+
--> $DIR/broken_format.rs:22:42
3535
|
3636
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
37+
| ^^^^^^^^^^^^^^^
3838

3939
warning: unmatched `}` found
40-
--> $DIR/broken_format.rs:22:32
40+
--> $DIR/broken_format.rs:22:42
4141
|
4242
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
43-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
43+
| ^^^^^^^^^^^^^^^
4444

4545
warning: unmatched `}` found
46-
--> $DIR/broken_format.rs:2:32
46+
--> $DIR/broken_format.rs:2:42
4747
|
4848
LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
49+
| ^^^^^^^^^^^^^^^^
5050
|
5151
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
5252

@@ -70,10 +70,10 @@ LL | fn check_1(_: impl ImportantTrait1) {}
7070
| ^^^^^^^^^^^^^^^ required by this bound in `check_1`
7171

7272
warning: positional format arguments are not allowed here
73-
--> $DIR/broken_format.rs:7:32
73+
--> $DIR/broken_format.rs:7:49
7474
|
7575
LL | #[diagnostic::on_unimplemented(message = "Test {}")]
76-
| ^^^^^^^^^^^^^^^^^^^
76+
| ^
7777
|
7878
= help: only named format arguments with the name of one of the generic types are allowed in this context
7979
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
@@ -98,10 +98,10 @@ LL | fn check_2(_: impl ImportantTrait2) {}
9898
| ^^^^^^^^^^^^^^^ required by this bound in `check_2`
9999

100100
warning: positional format arguments are not allowed here
101-
--> $DIR/broken_format.rs:12:32
101+
--> $DIR/broken_format.rs:12:49
102102
|
103103
LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
104-
| ^^^^^^^^^^^^^^^^^^^^^
104+
| ^
105105
|
106106
= help: only named format arguments with the name of one of the generic types are allowed in this context
107107
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
@@ -126,10 +126,10 @@ LL | fn check_3(_: impl ImportantTrait3) {}
126126
| ^^^^^^^^^^^^^^^ required by this bound in `check_3`
127127

128128
warning: invalid format specifier
129-
--> $DIR/broken_format.rs:17:32
129+
--> $DIR/broken_format.rs:17:42
130130
|
131131
LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
132-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
132+
| ^^^^^^^^^^^^^^^^^
133133
|
134134
= help: no format specifier are supported in this position
135135
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
@@ -154,18 +154,18 @@ LL | fn check_4(_: impl ImportantTrait4) {}
154154
| ^^^^^^^^^^^^^^^ required by this bound in `check_4`
155155

156156
warning: expected `}`, found `!`
157-
--> $DIR/broken_format.rs:22:32
157+
--> $DIR/broken_format.rs:22:42
158158
|
159159
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
160-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
160+
| ^^^^^^^^^^^^^^^
161161
|
162162
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
163163

164164
warning: unmatched `}` found
165-
--> $DIR/broken_format.rs:22:32
165+
--> $DIR/broken_format.rs:22:42
166166
|
167167
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
168-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
168+
| ^^^^^^^^^^^^^^^
169169
|
170170
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
171171

‎tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,82 +39,82 @@ LL | #[diagnostic::on_unimplemented = "Message"]
3939
= help: only `message`, `note` and `label` are allowed as options
4040

4141
warning: there is no parameter `from_desugaring` on trait `Baz`
42-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
42+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:17
4343
|
4444
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
45-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
45+
| ^^^^^^^^^^^^^^^
4646
|
4747
= help: expect either a generic argument name or `{Self}` as format argument
4848

4949
warning: there is no parameter `direct` on trait `Baz`
50-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
50+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:34
5151
|
5252
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
| ^^^^^^
5454
|
5555
= help: expect either a generic argument name or `{Self}` as format argument
5656

5757
warning: there is no parameter `cause` on trait `Baz`
58-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
58+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:42
5959
|
6060
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
61+
| ^^^^^
6262
|
6363
= help: expect either a generic argument name or `{Self}` as format argument
6464

6565
warning: there is no parameter `integral` on trait `Baz`
66-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
66+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:49
6767
|
6868
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
69-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
69+
| ^^^^^^^^
7070
|
7171
= help: expect either a generic argument name or `{Self}` as format argument
7272

7373
warning: there is no parameter `integer` on trait `Baz`
74-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
74+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:59
7575
|
7676
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77+
| ^^^^^^^
7878
|
7979
= help: expect either a generic argument name or `{Self}` as format argument
8080

8181
warning: there is no parameter `float` on trait `Baz`
82-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
82+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:15
8383
|
8484
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
85-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
85+
| ^^^^^
8686
|
8787
= help: expect either a generic argument name or `{Self}` as format argument
8888

8989
warning: there is no parameter `_Self` on trait `Baz`
90-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
90+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:22
9191
|
9292
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
93-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
93+
| ^^^^^
9494
|
9595
= help: expect either a generic argument name or `{Self}` as format argument
9696

9797
warning: there is no parameter `crate_local` on trait `Baz`
98-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
98+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:29
9999
|
100100
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
101-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
101+
| ^^^^^^^^^^^
102102
|
103103
= help: expect either a generic argument name or `{Self}` as format argument
104104

105105
warning: there is no parameter `Trait` on trait `Baz`
106-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
106+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:42
107107
|
108108
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
109-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
109+
| ^^^^^
110110
|
111111
= help: expect either a generic argument name or `{Self}` as format argument
112112

113113
warning: there is no parameter `ItemContext` on trait `Baz`
114-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
114+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:49
115115
|
116116
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
117-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
117+
| ^^^^^^^^^^^
118118
|
119119
= help: expect either a generic argument name or `{Self}` as format argument
120120

@@ -191,91 +191,91 @@ LL | fn takes_bar(_: impl Bar) {}
191191
| ^^^ required by this bound in `takes_bar`
192192

193193
warning: there is no parameter `from_desugaring` on trait `Baz`
194-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
194+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:17
195195
|
196196
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
197-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
197+
| ^^^^^^^^^^^^^^^
198198
|
199199
= help: expect either a generic argument name or `{Self}` as format argument
200200
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
201201

202202
warning: there is no parameter `direct` on trait `Baz`
203-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
203+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:34
204204
|
205205
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
206-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
206+
| ^^^^^^
207207
|
208208
= help: expect either a generic argument name or `{Self}` as format argument
209209
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
210210

211211
warning: there is no parameter `cause` on trait `Baz`
212-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
212+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:42
213213
|
214214
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
215-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
215+
| ^^^^^
216216
|
217217
= help: expect either a generic argument name or `{Self}` as format argument
218218
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
219219

220220
warning: there is no parameter `integral` on trait `Baz`
221-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
221+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:49
222222
|
223223
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
224-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
224+
| ^^^^^^^^
225225
|
226226
= help: expect either a generic argument name or `{Self}` as format argument
227227
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
228228

229229
warning: there is no parameter `integer` on trait `Baz`
230-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
230+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:59
231231
|
232232
LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
233-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
233+
| ^^^^^^^
234234
|
235235
= help: expect either a generic argument name or `{Self}` as format argument
236236
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
237237

238238
warning: there is no parameter `float` on trait `Baz`
239-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
239+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:15
240240
|
241241
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
242-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
242+
| ^^^^^
243243
|
244244
= help: expect either a generic argument name or `{Self}` as format argument
245245
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
246246

247247
warning: there is no parameter `_Self` on trait `Baz`
248-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
248+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:22
249249
|
250250
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
251-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
251+
| ^^^^^
252252
|
253253
= help: expect either a generic argument name or `{Self}` as format argument
254254
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
255255

256256
warning: there is no parameter `crate_local` on trait `Baz`
257-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
257+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:29
258258
|
259259
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
260-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
260+
| ^^^^^^^^^^^
261261
|
262262
= help: expect either a generic argument name or `{Self}` as format argument
263263
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
264264

265265
warning: there is no parameter `Trait` on trait `Baz`
266-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
266+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:42
267267
|
268268
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
269-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
269+
| ^^^^^
270270
|
271271
= help: expect either a generic argument name or `{Self}` as format argument
272272
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
273273

274274
warning: there is no parameter `ItemContext` on trait `Baz`
275-
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
275+
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:49
276276
|
277277
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
278-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
278+
| ^^^^^^^^^^^
279279
|
280280
= help: expect either a generic argument name or `{Self}` as format argument
281281
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

‎tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ LL | #[diagnostic::on_unimplemented]
4747
= help: at least one of the `message`, `note` and `label` options are expected
4848

4949
warning: there is no parameter `DoesNotExist` on trait `Test`
50-
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:32
50+
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:44
5151
|
5252
LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
| ^^^^^^^^^^^^
5454
|
5555
= help: expect either a generic argument name or `{Self}` as format argument
5656

@@ -167,10 +167,10 @@ LL | fn take_whatever(_: impl Whatever) {}
167167
| ^^^^^^^^ required by this bound in `take_whatever`
168168

169169
warning: there is no parameter `DoesNotExist` on trait `Test`
170-
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:32
170+
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:44
171171
|
172172
LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
173-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
173+
| ^^^^^^^^^^^^
174174
|
175175
= help: expect either a generic argument name or `{Self}` as format argument
176176
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

‎tests/ui/on-unimplemented/bad-annotation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ trait BadAnnotation1
2020
{}
2121

2222
#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
23-
//~^ ERROR there is no parameter `C` on trait `BadAnnotation2`
23+
//~^ ERROR cannot find parameter C on this trait
2424
trait BadAnnotation2<A,B>
2525
{}
2626

2727
#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
28-
//~^ ERROR only named generic parameters are allowed
28+
//~^ ERROR positional format arguments are not allowed here
2929
trait BadAnnotation3<A,B>
3030
{}
3131

‎tests/ui/on-unimplemented/bad-annotation.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ LL | #[rustc_on_unimplemented = "message"]
1111
LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]
1212
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1313

14-
error[E0230]: there is no parameter `C` on trait `BadAnnotation2`
15-
--> $DIR/bad-annotation.rs:22:1
14+
error[E0230]: cannot find parameter C on this trait
15+
--> $DIR/bad-annotation.rs:22:90
1616
|
1717
LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
18-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
| ^
1919

20-
error[E0231]: only named generic parameters are allowed
21-
--> $DIR/bad-annotation.rs:27:1
20+
error[E0231]: positional format arguments are not allowed here
21+
--> $DIR/bad-annotation.rs:27:90
2222
|
2323
LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
24-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
| ^
2525

2626
error[E0232]: this attribute must have a valid value
2727
--> $DIR/bad-annotation.rs:32:26

‎tests/ui/on-unimplemented/impl-substs.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.

‎tests/ui/on-unimplemented/impl-substs.stderr

Lines changed: 0 additions & 15 deletions
This file was deleted.

‎tests/ui/on-unimplemented/issue-104140.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

‎tests/ui/on-unimplemented/issue-104140.stderr

Lines changed: 0 additions & 15 deletions
This file was deleted.

‎tests/ui/on-unimplemented/multiple-impls.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.

‎tests/ui/on-unimplemented/multiple-impls.stderr

Lines changed: 0 additions & 75 deletions
This file was deleted.

‎tests/ui/on-unimplemented/on-impl.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

‎tests/ui/on-unimplemented/on-impl.stderr

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(rustc_attrs)]
2+
3+
#[rustc_on_unimplemented(on(
4+
all(A = "{integer}", any(Self = "[{integral}; _]",)),
5+
message = "an array of type `{Self}` cannot be built directly from an iterator",
6+
))]
7+
pub trait FromIterator<A>: Sized {
8+
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
9+
}
10+
fn main() {
11+
let iter = 0..42_8;
12+
let x: [u8; 8] = FromIterator::from_iter(iter);
13+
//~^ ERROR an array of type `[u8; 8]` cannot be built directly from an iterator
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: an array of type `[u8; 8]` cannot be built directly from an iterator
2+
--> $DIR/use_self_no_underscore.rs:12:22
3+
|
4+
LL | let x: [u8; 8] = FromIterator::from_iter(iter);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromIterator<{integer}>` is not implemented for `[u8; 8]`
6+
|
7+
help: this trait has no implementations, consider adding one
8+
--> $DIR/use_self_no_underscore.rs:7:1
9+
|
10+
LL | pub trait FromIterator<A>: Sized {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)
Please sign in to comment.