@@ -222,7 +222,87 @@ pub trait Try: FromResidual {
222
222
/// Every `Try` type needs to be recreatable from its own associated
223
223
/// `Residual` type, but can also have additional `FromResidual` implementations
224
224
/// 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(
226
306
on(
227
307
all(
228
308
from_desugaring = "QuestionMark" ,
@@ -301,7 +381,7 @@ pub trait Try: FromResidual {
301
381
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`" ,
302
382
enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
303
383
) ,
304
- ) ]
384
+ ) ) ]
305
385
#[ rustc_diagnostic_item = "FromResidual" ]
306
386
#[ unstable( feature = "try_trait_v2" , issue = "84277" ) ]
307
387
pub trait FromResidual < R = <Self as Try >:: Residual > {
0 commit comments