1+ use rustc_errors:: DecorateLint ;
12use rustc_hir as hir;
23use rustc_infer:: infer:: TyCtxtInferExt ;
3- use rustc_macros:: LintDiagnostic ;
4- use rustc_middle:: ty:: { self , fold:: BottomUpFolder , Ty , TypeFoldable } ;
4+ use rustc_macros:: { LintDiagnostic , Subdiagnostic } ;
5+ use rustc_middle:: ty:: {
6+ self , fold:: BottomUpFolder , print:: TraitPredPrintModifiersAndPath , Ty , TypeFoldable ,
7+ } ;
58use rustc_span:: Span ;
69use rustc_trait_selection:: traits;
710use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
@@ -117,23 +120,29 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
117120 ) ) {
118121 // If it's a trait bound and an opaque that doesn't satisfy it,
119122 // then we can emit a suggestion to add the bound.
120- let ( suggestion , suggest_span ) =
123+ let sugg =
121124 match ( proj_term. kind ( ) , assoc_pred. kind ( ) . skip_binder ( ) ) {
122- ( ty:: Opaque ( def_id, _) , ty:: PredicateKind :: Trait ( trait_pred) ) => (
123- format ! ( " + {}" , trait_pred . print_modifiers_and_trait_path ( ) ) ,
124- Some ( cx . tcx . def_span ( def_id ) . shrink_to_hi ( ) ) ,
125- ) ,
126- _ => ( String :: new ( ) , None ) ,
125+ ( ty:: Opaque ( def_id, _) , ty:: PredicateKind :: Trait ( trait_pred) ) => Some ( AddBound {
126+ suggest_span : cx . tcx . def_span ( * def_id ) . shrink_to_hi ( ) ,
127+ trait_ref : trait_pred . print_modifiers_and_trait_path ( ) ,
128+ } ) ,
129+ _ => None ,
127130 } ;
128- cx. emit_spanned_lint (
131+ let lint = OpaqueHiddenInferredBoundLint {
132+ ty : cx. tcx . mk_opaque ( def_id, ty:: InternalSubsts :: identity_for_item ( cx. tcx , def_id) ) ,
133+ proj_ty : proj_term,
134+ assoc_pred_span,
135+ } ;
136+ cx. struct_span_lint (
129137 OPAQUE_HIDDEN_INFERRED_BOUND ,
130138 pred_span,
131- OpaqueHiddenInferredBoundLint {
132- ty : cx. tcx . mk_opaque ( def_id, ty:: InternalSubsts :: identity_for_item ( cx. tcx , def_id) ) ,
133- proj_ty : proj_term,
134- assoc_pred_span,
135- suggestion,
136- suggest_span,
139+ lint. msg ( ) ,
140+ |diag| {
141+ lint. decorate_lint ( diag) ;
142+ if let Some ( sugg) = sugg {
143+ diag. subdiagnostic ( sugg) ;
144+ }
145+ diag
137146 } ,
138147 ) ;
139148 }
@@ -150,7 +159,17 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
150159 proj_ty : Ty < ' tcx > ,
151160 #[ label( lint:: specifically) ]
152161 assoc_pred_span : Span ,
153- #[ suggestion_verbose( applicability = "machine-applicable" , code = "{suggestion}" ) ]
154- suggest_span : Option < Span > ,
155- suggestion : String ,
162+ }
163+
164+ #[ derive( Subdiagnostic ) ]
165+ #[ suggestion_verbose(
166+ lint:: opaque_hidden_inferred_bound_sugg,
167+ applicability = "machine-applicable" ,
168+ code = " + {trait_ref}"
169+ ) ]
170+ struct AddBound < ' tcx > {
171+ #[ primary_span]
172+ suggest_span : Span ,
173+ #[ skip_arg]
174+ trait_ref : TraitPredPrintModifiersAndPath < ' tcx > ,
156175}
0 commit comments