Skip to content

Commit b73c5fe

Browse files
committed
Auto merge of #101296 - compiler-errors:head-span-for-enclosing-scope, r=oli-obk
Use head span for `rustc_on_unimplemented`'s `enclosing_scope` attr This may make #101281 slightly easier to understand
2 parents a634fb7 + 57d3ba4 commit b73c5fe

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

core/src/ops/try_trait.rs

Lines changed: 82 additions & 2 deletions
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> {

0 commit comments

Comments
 (0)