Skip to content

Commit edba0c9

Browse files
Address nits, rename enclosing_scope => parent_label
1 parent c23fe81 commit edba0c9

File tree

7 files changed

+141
-65
lines changed

7 files changed

+141
-65
lines changed

Diff for: compiler/rustc_span/src/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@ symbols! {
661661
emit_struct,
662662
emit_struct_field,
663663
enable,
664-
enclosing_scope,
665664
encode,
666665
end,
667666
env,
@@ -1063,6 +1062,7 @@ symbols! {
10631062
panic_unwind,
10641063
panicking,
10651064
param_attrs,
1065+
parent_label,
10661066
partial_cmp,
10671067
partial_ord,
10681068
passes,

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
349349
message,
350350
label,
351351
note,
352-
enclosing_scope,
352+
parent_label,
353353
append_const_msg,
354354
} = self.on_unimplemented_note(trait_ref, &obligation);
355355
let have_alt_message = message.is_some() || label.is_some();
@@ -515,7 +515,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
515515
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
516516
err.note(s.as_str());
517517
}
518-
if let Some(ref s) = enclosing_scope {
518+
if let Some(ref s) = parent_label {
519519
let body = tcx
520520
.hir()
521521
.opt_local_def_id(obligation.cause.body_id)
@@ -524,11 +524,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
524524
hir_id: obligation.cause.body_id,
525525
})
526526
});
527-
528-
let enclosing_scope_span =
529-
tcx.hir().span(tcx.hir().local_def_id_to_hir_id(body));
530-
531-
err.span_label(enclosing_scope_span, s);
527+
err.span_label(tcx.def_span(body), s);
532528
}
533529

534530
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);

Diff for: compiler/rustc_trait_selection/src/traits/on_unimplemented.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct OnUnimplementedDirective {
2222
pub message: Option<OnUnimplementedFormatString>,
2323
pub label: Option<OnUnimplementedFormatString>,
2424
pub note: Option<OnUnimplementedFormatString>,
25-
pub enclosing_scope: Option<OnUnimplementedFormatString>,
25+
pub parent_label: Option<OnUnimplementedFormatString>,
2626
pub append_const_msg: Option<Option<Symbol>>,
2727
}
2828

@@ -31,7 +31,7 @@ pub struct OnUnimplementedNote {
3131
pub message: Option<String>,
3232
pub label: Option<String>,
3333
pub note: Option<String>,
34-
pub enclosing_scope: Option<String>,
34+
pub parent_label: Option<String>,
3535
/// Append a message for `~const Trait` errors. `None` means not requested and
3636
/// should fallback to a generic message, `Some(None)` suggests using the default
3737
/// appended message, `Some(Some(s))` suggests use the `s` message instead of the
@@ -74,7 +74,7 @@ impl<'tcx> OnUnimplementedDirective {
7474
let mut message = None;
7575
let mut label = None;
7676
let mut note = None;
77-
let mut enclosing_scope = None;
77+
let mut parent_label = None;
7878
let mut subcommands = vec![];
7979
let mut append_const_msg = None;
8080

@@ -94,9 +94,9 @@ impl<'tcx> OnUnimplementedDirective {
9494
note = parse_value(note_)?;
9595
continue;
9696
}
97-
} else if item.has_name(sym::enclosing_scope) && enclosing_scope.is_none() {
98-
if let Some(enclosing_scope_) = item.value_str() {
99-
enclosing_scope = parse_value(enclosing_scope_)?;
97+
} else if item.has_name(sym::parent_label) && parent_label.is_none() {
98+
if let Some(parent_label_) = item.value_str() {
99+
parent_label = parse_value(parent_label_)?;
100100
continue;
101101
}
102102
} else if item.has_name(sym::on)
@@ -135,7 +135,7 @@ impl<'tcx> OnUnimplementedDirective {
135135
message,
136136
label,
137137
note,
138-
enclosing_scope,
138+
parent_label,
139139
append_const_msg,
140140
})
141141
}
@@ -160,7 +160,7 @@ impl<'tcx> OnUnimplementedDirective {
160160
attr.span,
161161
)?),
162162
note: None,
163-
enclosing_scope: None,
163+
parent_label: None,
164164
append_const_msg: None,
165165
}))
166166
} else {
@@ -181,7 +181,7 @@ impl<'tcx> OnUnimplementedDirective {
181181
let mut message = None;
182182
let mut label = None;
183183
let mut note = None;
184-
let mut enclosing_scope = None;
184+
let mut parent_label = None;
185185
let mut append_const_msg = None;
186186
info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
187187

@@ -217,8 +217,8 @@ impl<'tcx> OnUnimplementedDirective {
217217
note = Some(note_.clone());
218218
}
219219

220-
if let Some(ref enclosing_scope_) = command.enclosing_scope {
221-
enclosing_scope = Some(enclosing_scope_.clone());
220+
if let Some(ref parent_label_) = command.parent_label {
221+
parent_label = Some(parent_label_.clone());
222222
}
223223

224224
append_const_msg = command.append_const_msg;
@@ -228,7 +228,7 @@ impl<'tcx> OnUnimplementedDirective {
228228
label: label.map(|l| l.format(tcx, trait_ref, &options_map)),
229229
message: message.map(|m| m.format(tcx, trait_ref, &options_map)),
230230
note: note.map(|n| n.format(tcx, trait_ref, &options_map)),
231-
enclosing_scope: enclosing_scope.map(|e_s| e_s.format(tcx, trait_ref, &options_map)),
231+
parent_label: parent_label.map(|e_s| e_s.format(tcx, trait_ref, &options_map)),
232232
append_const_msg,
233233
}
234234
}

Diff for: library/core/src/ops/try_trait.rs

+82-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,87 @@ pub trait Try: FromResidual {
222222
/// Every `Try` type needs to be recreatable from its own associated
223223
/// `Residual` type, but can also have additional `FromResidual` implementations
224224
/// to support interconversion with other `Try` types.
225-
#[rustc_on_unimplemented(
225+
#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
226+
on(
227+
all(
228+
from_desugaring = "QuestionMark",
229+
_Self = "std::result::Result<T, E>",
230+
R = "std::option::Option<std::convert::Infallible>"
231+
),
232+
message = "the `?` operator can only be used on `Result`s, not `Option`s, \
233+
in {ItemContext} that returns `Result`",
234+
label = "use `.ok_or(...)?` to provide an error compatible with `{Self}`",
235+
parent_label = "this function returns a `Result`"
236+
),
237+
on(
238+
all(
239+
from_desugaring = "QuestionMark",
240+
_Self = "std::result::Result<T, E>",
241+
),
242+
// There's a special error message in the trait selection code for
243+
// `From` in `?`, so this is not shown for result-in-result errors,
244+
// and thus it can be phrased more strongly than `ControlFlow`'s.
245+
message = "the `?` operator can only be used on `Result`s \
246+
in {ItemContext} that returns `Result`",
247+
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
248+
parent_label = "this function returns a `Result`"
249+
),
250+
on(
251+
all(
252+
from_desugaring = "QuestionMark",
253+
_Self = "std::option::Option<T>",
254+
R = "std::result::Result<T, E>",
255+
),
256+
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
257+
in {ItemContext} that returns `Option`",
258+
label = "use `.ok()?` if you want to discard the `{R}` error information",
259+
parent_label = "this function returns an `Option`"
260+
),
261+
on(
262+
all(
263+
from_desugaring = "QuestionMark",
264+
_Self = "std::option::Option<T>",
265+
),
266+
// `Option`-in-`Option` always works, as there's only one possible
267+
// residual, so this can also be phrased strongly.
268+
message = "the `?` operator can only be used on `Option`s \
269+
in {ItemContext} that returns `Option`",
270+
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
271+
parent_label = "this function returns an `Option`"
272+
),
273+
on(
274+
all(
275+
from_desugaring = "QuestionMark",
276+
_Self = "std::ops::ControlFlow<B, C>",
277+
R = "std::ops::ControlFlow<B, C>",
278+
),
279+
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
280+
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
281+
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
282+
parent_label = "this function returns a `ControlFlow`",
283+
note = "unlike `Result`, there's no `From`-conversion performed for `ControlFlow`"
284+
),
285+
on(
286+
all(
287+
from_desugaring = "QuestionMark",
288+
_Self = "std::ops::ControlFlow<B, C>",
289+
// `R` is not a `ControlFlow`, as that case was matched previously
290+
),
291+
message = "the `?` operator can only be used on `ControlFlow`s \
292+
in {ItemContext} that returns `ControlFlow`",
293+
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
294+
parent_label = "this function returns a `ControlFlow`",
295+
),
296+
on(
297+
all(from_desugaring = "QuestionMark"),
298+
message = "the `?` operator can only be used in {ItemContext} \
299+
that returns `Result` or `Option` \
300+
(or another type that implements `{FromResidual}`)",
301+
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
302+
parent_label = "this function should return `Result` or `Option` to accept `?`"
303+
),
304+
))]
305+
#[cfg_attr(bootstrap, rustc_on_unimplemented(
226306
on(
227307
all(
228308
from_desugaring = "QuestionMark",
@@ -301,7 +381,7 @@ pub trait Try: FromResidual {
301381
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
302382
enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
303383
),
304-
)]
384+
))]
305385
#[rustc_diagnostic_item = "FromResidual"]
306386
#[unstable(feature = "try_trait_v2", issue = "84277")]
307387
pub trait FromResidual<R = <Self as Try>::Residual> {

Diff for: src/test/ui/on-unimplemented/enclosing-scope.rs

-27
This file was deleted.

Diff for: src/test/ui/on-unimplemented/parent-label.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Test scope annotations from `parent_label` parameter
2+
3+
#![feature(rustc_attrs)]
4+
5+
#[rustc_on_unimplemented(parent_label = "in this scope")]
6+
trait Trait {}
7+
8+
struct Foo;
9+
10+
fn f<T: Trait>(x: T) {}
11+
12+
fn main() {
13+
let x = || {
14+
f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
15+
let y = || {
16+
f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
17+
};
18+
};
19+
20+
{
21+
{
22+
f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
23+
}
24+
}
25+
26+
f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
27+
}

Diff for: src/test/ui/on-unimplemented/enclosing-scope.stderr renamed to src/test/ui/on-unimplemented/parent-label.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,65 @@
11
error[E0277]: the trait bound `Foo: Trait` is not satisfied
2-
--> $DIR/enclosing-scope.rs:14:11
2+
--> $DIR/parent-label.rs:14:11
33
|
44
LL | let x = || {
55
| -- in this scope
6-
LL | f(Foo{});
7-
| - ^^^^^ the trait `Trait` is not implemented for `Foo`
6+
LL | f(Foo {});
7+
| - ^^^^^^ the trait `Trait` is not implemented for `Foo`
88
| |
99
| required by a bound introduced by this call
1010
|
1111
note: required by a bound in `f`
12-
--> $DIR/enclosing-scope.rs:10:9
12+
--> $DIR/parent-label.rs:10:9
1313
|
1414
LL | fn f<T: Trait>(x: T) {}
1515
| ^^^^^ required by this bound in `f`
1616

1717
error[E0277]: the trait bound `Foo: Trait` is not satisfied
18-
--> $DIR/enclosing-scope.rs:16:15
18+
--> $DIR/parent-label.rs:16:15
1919
|
2020
LL | let y = || {
2121
| -- in this scope
22-
LL | f(Foo{});
23-
| - ^^^^^ the trait `Trait` is not implemented for `Foo`
22+
LL | f(Foo {});
23+
| - ^^^^^^ the trait `Trait` is not implemented for `Foo`
2424
| |
2525
| required by a bound introduced by this call
2626
|
2727
note: required by a bound in `f`
28-
--> $DIR/enclosing-scope.rs:10:9
28+
--> $DIR/parent-label.rs:10:9
2929
|
3030
LL | fn f<T: Trait>(x: T) {}
3131
| ^^^^^ required by this bound in `f`
3232

3333
error[E0277]: the trait bound `Foo: Trait` is not satisfied
34-
--> $DIR/enclosing-scope.rs:22:15
34+
--> $DIR/parent-label.rs:22:15
3535
|
3636
LL | fn main() {
3737
| --------- in this scope
3838
...
39-
LL | f(Foo{});
40-
| - ^^^^^ the trait `Trait` is not implemented for `Foo`
39+
LL | f(Foo {});
40+
| - ^^^^^^ the trait `Trait` is not implemented for `Foo`
4141
| |
4242
| required by a bound introduced by this call
4343
|
4444
note: required by a bound in `f`
45-
--> $DIR/enclosing-scope.rs:10:9
45+
--> $DIR/parent-label.rs:10:9
4646
|
4747
LL | fn f<T: Trait>(x: T) {}
4848
| ^^^^^ required by this bound in `f`
4949

5050
error[E0277]: the trait bound `Foo: Trait` is not satisfied
51-
--> $DIR/enclosing-scope.rs:26:7
51+
--> $DIR/parent-label.rs:26:7
5252
|
5353
LL | fn main() {
5454
| --------- in this scope
5555
...
56-
LL | f(Foo{});
57-
| - ^^^^^ the trait `Trait` is not implemented for `Foo`
56+
LL | f(Foo {});
57+
| - ^^^^^^ the trait `Trait` is not implemented for `Foo`
5858
| |
5959
| required by a bound introduced by this call
6060
|
6161
note: required by a bound in `f`
62-
--> $DIR/enclosing-scope.rs:10:9
62+
--> $DIR/parent-label.rs:10:9
6363
|
6464
LL | fn f<T: Trait>(x: T) {}
6565
| ^^^^^ required by this bound in `f`

0 commit comments

Comments
 (0)