1
+ use rustc_errors:: DecorateLint ;
1
2
use rustc_hir as hir;
2
3
use 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
+ } ;
5
8
use rustc_span:: Span ;
6
9
use rustc_trait_selection:: traits;
7
10
use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
@@ -117,23 +120,29 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
117
120
) ) {
118
121
// If it's a trait bound and an opaque that doesn't satisfy it,
119
122
// then we can emit a suggestion to add the bound.
120
- let ( suggestion , suggest_span ) =
123
+ let sugg =
121
124
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 ,
127
130
} ;
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 (
129
137
OPAQUE_HIDDEN_INFERRED_BOUND ,
130
138
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
137
146
} ,
138
147
) ;
139
148
}
@@ -150,7 +159,17 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
150
159
proj_ty : Ty < ' tcx > ,
151
160
#[ label( lint:: specifically) ]
152
161
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 > ,
156
175
}
0 commit comments