11use rustc_hir as hir;
22use rustc_infer:: infer:: TyCtxtInferExt ;
3- use rustc_macros:: LintDiagnostic ;
4- use rustc_middle:: ty:: { self , fold:: BottomUpFolder , Ty , TypeFoldable } ;
3+ use rustc_macros:: { LintDiagnostic , Subdiagnostic } ;
4+ use rustc_middle:: ty:: {
5+ self , fold:: BottomUpFolder , print:: TraitPredPrintModifiersAndPath , Ty , TypeFoldable ,
6+ } ;
57use rustc_span:: Span ;
68use rustc_trait_selection:: traits;
79use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
@@ -117,13 +119,13 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
117119 ) ) {
118120 // If it's a trait bound and an opaque that doesn't satisfy it,
119121 // then we can emit a suggestion to add the bound.
120- let ( suggestion , suggest_span ) =
122+ let add_bound =
121123 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 ) ,
124+ ( ty:: Opaque ( def_id, _) , ty:: PredicateKind :: Trait ( trait_pred) ) => Some ( AddBound {
125+ suggest_span : cx . tcx . def_span ( * def_id ) . shrink_to_hi ( ) ,
126+ trait_ref : trait_pred . print_modifiers_and_trait_path ( ) ,
127+ } ) ,
128+ _ => None ,
127129 } ;
128130 cx. emit_spanned_lint (
129131 OPAQUE_HIDDEN_INFERRED_BOUND ,
@@ -132,8 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
132134 ty : cx. tcx . mk_opaque ( def_id, ty:: InternalSubsts :: identity_for_item ( cx. tcx , def_id) ) ,
133135 proj_ty : proj_term,
134136 assoc_pred_span,
135- suggestion,
136- suggest_span,
137+ add_bound,
137138 } ,
138139 ) ;
139140 }
@@ -150,7 +151,19 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
150151 proj_ty : Ty < ' tcx > ,
151152 #[ label( lint:: specifically) ]
152153 assoc_pred_span : Span ,
153- #[ suggestion_verbose( applicability = "machine-applicable" , code = "{suggestion}" ) ]
154- suggest_span : Option < Span > ,
155- suggestion : String ,
154+ #[ subdiagnostic]
155+ add_bound : Option < AddBound < ' tcx > > ,
156+ }
157+
158+ #[ derive( Subdiagnostic ) ]
159+ #[ suggestion_verbose(
160+ lint:: opaque_hidden_inferred_bound_sugg,
161+ applicability = "machine-applicable" ,
162+ code = " + {trait_ref}"
163+ ) ]
164+ struct AddBound < ' tcx > {
165+ #[ primary_span]
166+ suggest_span : Span ,
167+ #[ skip_arg]
168+ trait_ref : TraitPredPrintModifiersAndPath < ' tcx > ,
156169}
0 commit comments