@@ -6,6 +6,7 @@ use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
6
6
use crate :: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
7
7
use crate :: infer:: lexical_region_resolve:: RegionResolutionError ;
8
8
use crate :: infer:: SubregionOrigin ;
9
+ use crate :: infer:: TyCtxt ;
9
10
10
11
use rustc_errors:: { struct_span_err, Applicability , Diagnostic , ErrorGuaranteed } ;
11
12
use rustc_hir as hir;
@@ -145,84 +146,83 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
145
146
}
146
147
}
147
148
148
- self . suggest_adding_lifetime_params ( sub, ty_sup, ty_sub, & mut err) ;
149
+ if suggest_adding_lifetime_params ( self . tcx ( ) , sub, ty_sup, ty_sub, & mut err) {
150
+ err. note ( "each elided lifetime in input position becomes a distinct lifetime" ) ;
151
+ }
149
152
150
153
let reported = err. emit ( ) ;
151
154
Some ( reported)
152
155
}
156
+ }
153
157
154
- fn suggest_adding_lifetime_params (
155
- & self ,
156
- sub : Region < ' tcx > ,
157
- ty_sup : & Ty < ' _ > ,
158
- ty_sub : & Ty < ' _ > ,
159
- err : & mut Diagnostic ,
160
- ) {
161
- if let (
162
- hir:: Ty { kind : hir:: TyKind :: Rptr ( lifetime_sub, _) , .. } ,
163
- hir:: Ty { kind : hir:: TyKind :: Rptr ( lifetime_sup, _) , .. } ,
164
- ) = ( ty_sub, ty_sup)
165
- {
166
- if lifetime_sub. name . is_elided ( ) && lifetime_sup. name . is_elided ( ) {
167
- if let Some ( anon_reg) = self . tcx ( ) . is_suitable_region ( sub) {
168
- let hir_id = self . tcx ( ) . hir ( ) . local_def_id_to_hir_id ( anon_reg. def_id ) ;
169
-
170
- let node = self . tcx ( ) . hir ( ) . get ( hir_id) ;
171
- let is_impl = matches ! ( & node, hir:: Node :: ImplItem ( _) ) ;
172
- let generics = match node {
173
- hir:: Node :: Item ( & hir:: Item {
174
- kind : hir:: ItemKind :: Fn ( _, ref generics, ..) ,
175
- ..
176
- } )
177
- | hir:: Node :: TraitItem ( & hir:: TraitItem { ref generics, .. } )
178
- | hir:: Node :: ImplItem ( & hir:: ImplItem { ref generics, .. } ) => generics,
179
- _ => return ,
180
- } ;
181
-
182
- let ( suggestion_param_name, introduce_new) = generics
183
- . params
184
- . iter ( )
185
- . find ( |p| matches ! ( p. kind, GenericParamKind :: Lifetime { .. } ) )
186
- . and_then ( |p| self . tcx ( ) . sess . source_map ( ) . span_to_snippet ( p. span ) . ok ( ) )
187
- . map ( |name| ( name, false ) )
188
- . unwrap_or_else ( || ( "'a" . to_string ( ) , true ) ) ;
189
-
190
- let mut suggestions = vec ! [
191
- if let hir:: LifetimeName :: Underscore = lifetime_sub. name {
192
- ( lifetime_sub. span, suggestion_param_name. clone( ) )
193
- } else {
194
- ( lifetime_sub. span. shrink_to_hi( ) , suggestion_param_name. clone( ) + " " )
195
- } ,
196
- if let hir:: LifetimeName :: Underscore = lifetime_sup. name {
197
- ( lifetime_sup. span, suggestion_param_name. clone( ) )
198
- } else {
199
- ( lifetime_sup. span. shrink_to_hi( ) , suggestion_param_name. clone( ) + " " )
200
- } ,
201
- ] ;
202
-
203
- if introduce_new {
204
- let new_param_suggestion = match & generics. params {
205
- [ ] => ( generics. span , format ! ( "<{}>" , suggestion_param_name) ) ,
206
- [ first, ..] => {
207
- ( first. span . shrink_to_lo ( ) , format ! ( "{}, " , suggestion_param_name) )
208
- }
209
- } ;
210
-
211
- suggestions. push ( new_param_suggestion) ;
212
- }
213
-
214
- let mut sugg = String :: from ( "consider introducing a named lifetime parameter" ) ;
215
- if is_impl {
216
- sugg. push_str ( " and update trait if needed" ) ;
217
- }
218
- err. multipart_suggestion (
219
- sugg. as_str ( ) ,
220
- suggestions,
221
- Applicability :: MaybeIncorrect ,
222
- ) ;
223
- err. note ( "each elided lifetime in input position becomes a distinct lifetime" ) ;
224
- }
225
- }
226
- }
158
+ pub fn suggest_adding_lifetime_params < ' tcx > (
159
+ tcx : TyCtxt < ' tcx > ,
160
+ sub : Region < ' tcx > ,
161
+ ty_sup : & Ty < ' _ > ,
162
+ ty_sub : & Ty < ' _ > ,
163
+ err : & mut Diagnostic ,
164
+ ) -> bool {
165
+ let (
166
+ hir:: Ty { kind : hir:: TyKind :: Rptr ( lifetime_sub, _) , .. } ,
167
+ hir:: Ty { kind : hir:: TyKind :: Rptr ( lifetime_sup, _) , .. } ,
168
+ ) = ( ty_sub, ty_sup) else {
169
+ return false ;
170
+ } ;
171
+
172
+ if !lifetime_sub. name . is_elided ( ) || !lifetime_sup. name . is_elided ( ) {
173
+ return false ;
174
+ } ;
175
+
176
+ let Some ( anon_reg) = tcx. is_suitable_region ( sub) else {
177
+ return false ;
178
+ } ;
179
+
180
+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( anon_reg. def_id ) ;
181
+
182
+ let node = tcx. hir ( ) . get ( hir_id) ;
183
+ let is_impl = matches ! ( & node, hir:: Node :: ImplItem ( _) ) ;
184
+ let generics = match node {
185
+ hir:: Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: Fn ( _, ref generics, ..) , .. } )
186
+ | hir:: Node :: TraitItem ( & hir:: TraitItem { ref generics, .. } )
187
+ | hir:: Node :: ImplItem ( & hir:: ImplItem { ref generics, .. } ) => generics,
188
+ _ => return false ,
189
+ } ;
190
+
191
+ let ( suggestion_param_name, introduce_new) = generics
192
+ . params
193
+ . iter ( )
194
+ . find ( |p| matches ! ( p. kind, GenericParamKind :: Lifetime { .. } ) )
195
+ . and_then ( |p| tcx. sess . source_map ( ) . span_to_snippet ( p. span ) . ok ( ) )
196
+ . map ( |name| ( name, false ) )
197
+ . unwrap_or_else ( || ( "'a" . to_string ( ) , true ) ) ;
198
+
199
+ let mut suggestions = vec ! [
200
+ if let hir:: LifetimeName :: Underscore = lifetime_sub. name {
201
+ ( lifetime_sub. span, suggestion_param_name. clone( ) )
202
+ } else {
203
+ ( lifetime_sub. span. shrink_to_hi( ) , suggestion_param_name. clone( ) + " " )
204
+ } ,
205
+ if let hir:: LifetimeName :: Underscore = lifetime_sup. name {
206
+ ( lifetime_sup. span, suggestion_param_name. clone( ) )
207
+ } else {
208
+ ( lifetime_sup. span. shrink_to_hi( ) , suggestion_param_name. clone( ) + " " )
209
+ } ,
210
+ ] ;
211
+
212
+ if introduce_new {
213
+ let new_param_suggestion = match & generics. params {
214
+ [ ] => ( generics. span , format ! ( "<{}>" , suggestion_param_name) ) ,
215
+ [ first, ..] => ( first. span . shrink_to_lo ( ) , format ! ( "{}, " , suggestion_param_name) ) ,
216
+ } ;
217
+
218
+ suggestions. push ( new_param_suggestion) ;
227
219
}
220
+
221
+ let mut sugg = String :: from ( "consider introducing a named lifetime parameter" ) ;
222
+ if is_impl {
223
+ sugg. push_str ( " and update trait if needed" ) ;
224
+ }
225
+ err. multipart_suggestion ( sugg. as_str ( ) , suggestions, Applicability :: MaybeIncorrect ) ;
226
+
227
+ true
228
228
}
0 commit comments