@@ -205,6 +205,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
205
205
self . note_obligation_cause_code (
206
206
& mut err,
207
207
& obligation. predicate ,
208
+ obligation. param_env ,
208
209
obligation. cause . code ( ) ,
209
210
& mut vec ! [ ] ,
210
211
& mut Default :: default ( ) ,
@@ -288,7 +289,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
288
289
match bound_predicate. skip_binder ( ) {
289
290
ty:: PredicateKind :: Trait ( trait_predicate) => {
290
291
let trait_predicate = bound_predicate. rebind ( trait_predicate) ;
291
- let trait_predicate = self . resolve_vars_if_possible ( trait_predicate) ;
292
+ let mut trait_predicate = self . resolve_vars_if_possible ( trait_predicate) ;
293
+
294
+ trait_predicate. remap_constness_diag ( obligation. param_env ) ;
295
+ let predicate_is_const = ty:: BoundConstness :: ConstIfConst
296
+ == trait_predicate. skip_binder ( ) . constness ;
292
297
293
298
if self . tcx . sess . has_errors ( ) && trait_predicate. references_error ( ) {
294
299
return ;
@@ -305,13 +310,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
305
310
} )
306
311
. unwrap_or_default ( ) ;
307
312
308
- let OnUnimplementedNote { message, label, note, enclosing_scope } =
309
- self . on_unimplemented_note ( trait_ref, & obligation) ;
313
+ let OnUnimplementedNote {
314
+ message,
315
+ label,
316
+ note,
317
+ enclosing_scope,
318
+ append_const_msg,
319
+ } = self . on_unimplemented_note ( trait_ref, & obligation) ;
310
320
let have_alt_message = message. is_some ( ) || label. is_some ( ) ;
311
321
let is_try_conversion = self . is_try_conversion ( span, trait_ref. def_id ( ) ) ;
312
322
let is_unsize =
313
323
{ Some ( trait_ref. def_id ( ) ) == self . tcx . lang_items ( ) . unsize_trait ( ) } ;
314
- let ( message, note) = if is_try_conversion {
324
+ let ( message, note, append_const_msg ) = if is_try_conversion {
315
325
(
316
326
Some ( format ! (
317
327
"`?` couldn't convert the error to `{}`" ,
@@ -322,21 +332,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
322
332
conversion on the error value using the `From` trait"
323
333
. to_owned ( ) ,
324
334
) ,
335
+ Some ( None ) ,
325
336
)
326
337
} else {
327
- ( message, note)
338
+ ( message, note, append_const_msg )
328
339
} ;
329
340
330
341
let mut err = struct_span_err ! (
331
342
self . tcx. sess,
332
343
span,
333
344
E0277 ,
334
345
"{}" ,
335
- message. unwrap_or_else( || format!(
336
- "the trait bound `{}` is not satisfied{}" ,
337
- trait_ref. without_const( ) . to_predicate( tcx) ,
338
- post_message,
339
- ) )
346
+ message
347
+ . and_then( |cannot_do_this| {
348
+ match ( predicate_is_const, append_const_msg) {
349
+ // do nothing if predicate is not const
350
+ ( false , _) => Some ( cannot_do_this) ,
351
+ // suggested using default post message
352
+ ( true , Some ( None ) ) => {
353
+ Some ( format!( "{cannot_do_this} in const contexts" ) )
354
+ }
355
+ // overriden post message
356
+ ( true , Some ( Some ( post_message) ) ) => {
357
+ Some ( format!( "{cannot_do_this}{post_message}" ) )
358
+ }
359
+ // fallback to generic message
360
+ ( true , None ) => None ,
361
+ }
362
+ } )
363
+ . unwrap_or_else( || format!(
364
+ "the trait bound `{}` is not satisfied{}" ,
365
+ trait_predicate, post_message,
366
+ ) )
340
367
) ;
341
368
342
369
if is_try_conversion {
@@ -384,15 +411,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
384
411
format ! (
385
412
"{}the trait `{}` is not implemented for `{}`" ,
386
413
pre_message,
387
- trait_ref . print_only_trait_path ( ) ,
414
+ trait_predicate . print_modifiers_and_trait_path ( ) ,
388
415
trait_ref. skip_binder( ) . self_ty( ) ,
389
416
)
390
417
} ;
391
418
392
419
if self . suggest_add_reference_to_arg (
393
420
& obligation,
394
421
& mut err,
395
- & trait_ref ,
422
+ trait_predicate ,
396
423
have_alt_message,
397
424
) {
398
425
self . note_obligation_cause ( & mut err, & obligation) ;
@@ -435,18 +462,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
435
462
err. span_label ( enclosing_scope_span, s. as_str ( ) ) ;
436
463
}
437
464
438
- self . suggest_dereferences ( & obligation, & mut err, trait_ref) ;
439
- self . suggest_fn_call ( & obligation, & mut err, trait_ref) ;
440
- self . suggest_remove_reference ( & obligation, & mut err, trait_ref) ;
441
- self . suggest_semicolon_removal ( & obligation, & mut err, span, trait_ref) ;
465
+ self . suggest_dereferences ( & obligation, & mut err, trait_predicate) ;
466
+ self . suggest_fn_call ( & obligation, & mut err, trait_predicate) ;
467
+ self . suggest_remove_reference ( & obligation, & mut err, trait_predicate) ;
468
+ self . suggest_semicolon_removal (
469
+ & obligation,
470
+ & mut err,
471
+ span,
472
+ trait_predicate,
473
+ ) ;
442
474
self . note_version_mismatch ( & mut err, & trait_ref) ;
443
475
self . suggest_remove_await ( & obligation, & mut err) ;
444
476
445
477
if Some ( trait_ref. def_id ( ) ) == tcx. lang_items ( ) . try_trait ( ) {
446
- self . suggest_await_before_try ( & mut err, & obligation, trait_ref, span) ;
478
+ self . suggest_await_before_try (
479
+ & mut err,
480
+ & obligation,
481
+ trait_predicate,
482
+ span,
483
+ ) ;
447
484
}
448
485
449
- if self . suggest_impl_trait ( & mut err, span, & obligation, trait_ref ) {
486
+ if self . suggest_impl_trait ( & mut err, span, & obligation, trait_predicate ) {
450
487
err. emit ( ) ;
451
488
return ;
452
489
}
@@ -494,7 +531,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
494
531
// which is somewhat confusing.
495
532
self . suggest_restricting_param_bound (
496
533
& mut err,
497
- trait_ref ,
534
+ trait_predicate ,
498
535
obligation. cause . body_id ,
499
536
) ;
500
537
} else if !have_alt_message {
@@ -506,7 +543,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
506
543
// Changing mutability doesn't make a difference to whether we have
507
544
// an `Unsize` impl (Fixes ICE in #71036)
508
545
if !is_unsize {
509
- self . suggest_change_mut ( & obligation, & mut err, trait_ref ) ;
546
+ self . suggest_change_mut ( & obligation, & mut err, trait_predicate ) ;
510
547
}
511
548
512
549
// If this error is due to `!: Trait` not implemented but `(): Trait` is
@@ -1121,7 +1158,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
1121
1158
fn mk_trait_obligation_with_new_self_ty (
1122
1159
& self ,
1123
1160
param_env : ty:: ParamEnv < ' tcx > ,
1124
- trait_ref : ty:: PolyTraitRef < ' tcx > ,
1161
+ trait_ref : ty:: PolyTraitPredicate < ' tcx > ,
1125
1162
new_self_ty : Ty < ' tcx > ,
1126
1163
) -> PredicateObligation < ' tcx > ;
1127
1164
@@ -1541,7 +1578,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1541
1578
) -> Option < ( String , Option < Span > ) > {
1542
1579
match code {
1543
1580
ObligationCauseCode :: BuiltinDerivedObligation ( data) => {
1544
- let parent_trait_ref = self . resolve_vars_if_possible ( data. parent_trait_ref ) ;
1581
+ let parent_trait_ref = self . resolve_vars_if_possible ( data. parent_trait_pred ) ;
1545
1582
match self . get_parent_trait_ref ( & data. parent_code ) {
1546
1583
Some ( t) => Some ( t) ,
1547
1584
None => {
@@ -1594,21 +1631,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1594
1631
fn mk_trait_obligation_with_new_self_ty (
1595
1632
& self ,
1596
1633
param_env : ty:: ParamEnv < ' tcx > ,
1597
- trait_ref : ty:: PolyTraitRef < ' tcx > ,
1634
+ trait_ref : ty:: PolyTraitPredicate < ' tcx > ,
1598
1635
new_self_ty : Ty < ' tcx > ,
1599
1636
) -> PredicateObligation < ' tcx > {
1600
1637
assert ! ( !new_self_ty. has_escaping_bound_vars( ) ) ;
1601
1638
1602
- let trait_ref = trait_ref. map_bound_ref ( |tr| ty:: TraitRef {
1603
- substs : self . tcx . mk_substs_trait ( new_self_ty, & tr. substs [ 1 ..] ) ,
1639
+ let trait_pred = trait_ref. map_bound_ref ( |tr| ty:: TraitPredicate {
1640
+ trait_ref : ty:: TraitRef {
1641
+ substs : self . tcx . mk_substs_trait ( new_self_ty, & tr. trait_ref . substs [ 1 ..] ) ,
1642
+ ..tr. trait_ref
1643
+ } ,
1604
1644
..* tr
1605
1645
} ) ;
1606
1646
1607
- Obligation :: new (
1608
- ObligationCause :: dummy ( ) ,
1609
- param_env,
1610
- trait_ref. without_const ( ) . to_predicate ( self . tcx ) ,
1611
- )
1647
+ Obligation :: new ( ObligationCause :: dummy ( ) , param_env, trait_pred. to_predicate ( self . tcx ) )
1612
1648
}
1613
1649
1614
1650
#[ instrument( skip( self ) , level = "debug" ) ]
@@ -2009,6 +2045,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
2009
2045
self . note_obligation_cause_code (
2010
2046
err,
2011
2047
& obligation. predicate ,
2048
+ obligation. param_env ,
2012
2049
obligation. cause . code ( ) ,
2013
2050
& mut vec ! [ ] ,
2014
2051
& mut Default :: default ( ) ,
@@ -2156,7 +2193,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
2156
2193
cause_code : & ObligationCauseCode < ' tcx > ,
2157
2194
) -> bool {
2158
2195
if let ObligationCauseCode :: BuiltinDerivedObligation ( ref data) = cause_code {
2159
- let parent_trait_ref = self . resolve_vars_if_possible ( data. parent_trait_ref ) ;
2196
+ let parent_trait_ref = self . resolve_vars_if_possible ( data. parent_trait_pred ) ;
2160
2197
let self_ty = parent_trait_ref. skip_binder ( ) . self_ty ( ) ;
2161
2198
if obligated_types. iter ( ) . any ( |ot| ot == & self_ty) {
2162
2199
return true ;
0 commit comments