@@ -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