@@ -205,6 +205,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
205205        self . note_obligation_cause_code ( 
206206            & mut  err, 
207207            & obligation. predicate , 
208+             obligation. param_env , 
208209            obligation. cause . code ( ) , 
209210            & mut  vec ! [ ] , 
210211            & mut  Default :: default ( ) , 
@@ -288,7 +289,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
288289                match  bound_predicate. skip_binder ( )  { 
289290                    ty:: PredicateKind :: Trait ( trait_predicate)  => { 
290291                        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 ; 
292297
293298                        if  self . tcx . sess . has_errors ( )  && trait_predicate. references_error ( )  { 
294299                            return ; 
@@ -305,13 +310,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
305310                            } ) 
306311                            . unwrap_or_default ( ) ; 
307312
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) ; 
310320                        let  have_alt_message = message. is_some ( )  || label. is_some ( ) ; 
311321                        let  is_try_conversion = self . is_try_conversion ( span,  trait_ref. def_id ( ) ) ; 
312322                        let  is_unsize =
313323                            {  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 { 
315325                            ( 
316326                                Some ( format ! ( 
317327                                    "`?` couldn't convert the error to `{}`" , 
@@ -322,21 +332,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
322332                                         conversion on the error value using the `From` trait"
323333                                        . to_owned ( ) , 
324334                                ) , 
335+                                 Some ( None ) , 
325336                            ) 
326337                        }  else  { 
327-                             ( message,  note) 
338+                             ( message,  note,  append_const_msg ) 
328339                        } ; 
329340
330341                        let  mut  err = struct_span_err ! ( 
331342                            self . tcx. sess, 
332343                            span, 
333344                            E0277 , 
334345                            "{}" , 
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+                                 ) ) 
340367                        ) ; 
341368
342369                        if  is_try_conversion { 
@@ -384,15 +411,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
384411                            format ! ( 
385412                                "{}the trait `{}` is not implemented for `{}`" , 
386413                                pre_message, 
387-                                 trait_ref . print_only_trait_path ( ) , 
414+                                 trait_predicate . print_modifiers_and_trait_path ( ) , 
388415                                trait_ref. skip_binder( ) . self_ty( ) , 
389416                            ) 
390417                        } ; 
391418
392419                        if  self . suggest_add_reference_to_arg ( 
393420                            & obligation, 
394421                            & mut  err, 
395-                             & trait_ref , 
422+                             trait_predicate , 
396423                            have_alt_message, 
397424                        )  { 
398425                            self . note_obligation_cause ( & mut  err,  & obligation) ; 
@@ -435,18 +462,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
435462                            err. span_label ( enclosing_scope_span,  s. as_str ( ) ) ; 
436463                        } 
437464
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+                         ) ; 
442474                        self . note_version_mismatch ( & mut  err,  & trait_ref) ; 
443475                        self . suggest_remove_await ( & obligation,  & mut  err) ; 
444476
445477                        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+                             ) ; 
447484                        } 
448485
449-                         if  self . suggest_impl_trait ( & mut  err,  span,  & obligation,  trait_ref )  { 
486+                         if  self . suggest_impl_trait ( & mut  err,  span,  & obligation,  trait_predicate )  { 
450487                            err. emit ( ) ; 
451488                            return ; 
452489                        } 
@@ -494,7 +531,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
494531                            // which is somewhat confusing. 
495532                            self . suggest_restricting_param_bound ( 
496533                                & mut  err, 
497-                                 trait_ref , 
534+                                 trait_predicate , 
498535                                obligation. cause . body_id , 
499536                            ) ; 
500537                        }  else  if  !have_alt_message { 
@@ -506,7 +543,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
506543                        // Changing mutability doesn't make a difference to whether we have 
507544                        // an `Unsize` impl (Fixes ICE in #71036) 
508545                        if  !is_unsize { 
509-                             self . suggest_change_mut ( & obligation,  & mut  err,  trait_ref ) ; 
546+                             self . suggest_change_mut ( & obligation,  & mut  err,  trait_predicate ) ; 
510547                        } 
511548
512549                        // If this error is due to `!: Trait` not implemented but `(): Trait` is 
@@ -1121,7 +1158,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
11211158     fn  mk_trait_obligation_with_new_self_ty ( 
11221159        & self , 
11231160        param_env :  ty:: ParamEnv < ' tcx > , 
1124-         trait_ref :  ty:: PolyTraitRef < ' tcx > , 
1161+         trait_ref :  ty:: PolyTraitPredicate < ' tcx > , 
11251162        new_self_ty :  Ty < ' tcx > , 
11261163    )  -> PredicateObligation < ' tcx > ; 
11271164
@@ -1541,7 +1578,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
15411578    )  -> Option < ( String ,  Option < Span > ) >  { 
15421579        match  code { 
15431580            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 ) ; 
15451582                match  self . get_parent_trait_ref ( & data. parent_code )  { 
15461583                    Some ( t)  => Some ( t) , 
15471584                    None  => { 
@@ -1594,21 +1631,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
15941631    fn  mk_trait_obligation_with_new_self_ty ( 
15951632        & self , 
15961633        param_env :  ty:: ParamEnv < ' tcx > , 
1597-         trait_ref :  ty:: PolyTraitRef < ' tcx > , 
1634+         trait_ref :  ty:: PolyTraitPredicate < ' tcx > , 
15981635        new_self_ty :  Ty < ' tcx > , 
15991636    )  -> PredicateObligation < ' tcx >  { 
16001637        assert ! ( !new_self_ty. has_escaping_bound_vars( ) ) ; 
16011638
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+             } , 
16041644            ..* tr
16051645        } ) ; 
16061646
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 ) ) 
16121648    } 
16131649
16141650    #[ instrument( skip( self ) ,  level = "debug" ) ]  
@@ -2009,6 +2045,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
20092045            self . note_obligation_cause_code ( 
20102046                err, 
20112047                & obligation. predicate , 
2048+                 obligation. param_env , 
20122049                obligation. cause . code ( ) , 
20132050                & mut  vec ! [ ] , 
20142051                & mut  Default :: default ( ) , 
@@ -2156,7 +2193,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
21562193        cause_code :  & ObligationCauseCode < ' tcx > , 
21572194    )  -> bool  { 
21582195        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 ) ; 
21602197            let  self_ty = parent_trait_ref. skip_binder ( ) . self_ty ( ) ; 
21612198            if  obligated_types. iter ( ) . any ( |ot| ot == & self_ty)  { 
21622199                return  true ; 
0 commit comments