@@ -26,8 +26,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
26
26
) ;
27
27
let anon_reg_sup = self . tcx ( ) . is_suitable_region ( sup_r) ?;
28
28
debug ! ( "try_report_static_impl_trait: anon_reg_sup={:?}" , anon_reg_sup) ;
29
- let fn_return = self . tcx ( ) . return_type_impl_or_dyn_trait ( anon_reg_sup. def_id ) ?;
30
- debug ! ( "try_report_static_impl_trait: fn_return={:?}" , fn_return) ;
29
+ let fn_returns = self . tcx ( ) . return_type_impl_or_dyn_traits ( anon_reg_sup. def_id ) ;
30
+ if fn_returns. is_empty ( ) {
31
+ return None ;
32
+ }
33
+ debug ! ( "try_report_static_impl_trait: fn_return={:?}" , fn_returns) ;
31
34
if * * sub_r == RegionKind :: ReStatic {
32
35
let sp = var_origin. span ( ) ;
33
36
let return_sp = sub_origin. span ( ) ;
@@ -98,25 +101,26 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
98
101
) ;
99
102
}
100
103
101
- // only apply this suggestion onto functions with
102
- // explicit non-desugar'able return.
103
- if fn_return. span . desugaring_kind ( ) . is_none ( ) {
104
- // FIXME: account for the need of parens in `&(dyn Trait + '_)`
105
-
106
- let consider = "consider changing the" ;
107
- let declare = "to declare that the" ;
108
- let arg = match param_info. param . pat . simple_ident ( ) {
109
- Some ( simple_ident) => format ! ( "argument `{}`" , simple_ident) ,
110
- None => "the argument" . to_string ( ) ,
111
- } ;
112
- let explicit =
113
- format ! ( "you can add an explicit `{}` lifetime bound" , lifetime_name) ;
114
- let explicit_static =
115
- format ! ( "explicit `'static` bound to the lifetime of {}" , arg) ;
116
- let captures = format ! ( "captures data from {}" , arg) ;
117
- let add_static_bound =
118
- "alternatively, add an explicit `'static` bound to this reference" ;
119
- let plus_lt = format ! ( " + {}" , lifetime_name) ;
104
+ // FIXME: account for the need of parens in `&(dyn Trait + '_)`
105
+ let consider = "consider changing the" ;
106
+ let declare = "to declare that the" ;
107
+ let arg = match param_info. param . pat . simple_ident ( ) {
108
+ Some ( simple_ident) => format ! ( "argument `{}`" , simple_ident) ,
109
+ None => "the argument" . to_string ( ) ,
110
+ } ;
111
+ let explicit =
112
+ format ! ( "you can add an explicit `{}` lifetime bound" , lifetime_name) ;
113
+ let explicit_static =
114
+ format ! ( "explicit `'static` bound to the lifetime of {}" , arg) ;
115
+ let captures = format ! ( "captures data from {}" , arg) ;
116
+ let add_static_bound =
117
+ "alternatively, add an explicit `'static` bound to this reference" ;
118
+ let plus_lt = format ! ( " + {}" , lifetime_name) ;
119
+ for fn_return in fn_returns {
120
+ if fn_return. span . desugaring_kind ( ) . is_some ( ) {
121
+ // Skip `async` desugaring `impl Future`.
122
+ continue ;
123
+ }
120
124
match fn_return. kind {
121
125
TyKind :: OpaqueDef ( item_id, _) => {
122
126
let item = self . tcx ( ) . hir ( ) . item ( item_id. id ) ;
@@ -143,7 +147,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
143
147
err. span_suggestion_verbose (
144
148
span,
145
149
& format ! ( "{} `impl Trait`'s {}" , consider, explicit_static) ,
146
- lifetime_name,
150
+ lifetime_name. clone ( ) ,
147
151
Applicability :: MaybeIncorrect ,
148
152
) ;
149
153
err. span_suggestion_verbose (
@@ -152,6 +156,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
152
156
param_info. param_ty . to_string ( ) ,
153
157
Applicability :: MaybeIncorrect ,
154
158
) ;
159
+ } else if let Some ( _) = opaque
160
+ . bounds
161
+ . iter ( )
162
+ . filter_map ( |arg| match arg {
163
+ GenericBound :: Outlives ( Lifetime { name, span, .. } )
164
+ if name. ident ( ) . to_string ( ) == lifetime_name =>
165
+ {
166
+ Some ( * span)
167
+ }
168
+ _ => None ,
169
+ } )
170
+ . next ( )
171
+ {
155
172
} else {
156
173
err. span_suggestion_verbose (
157
174
fn_return. span . shrink_to_hi ( ) ,
@@ -161,10 +178,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
161
178
captures = captures,
162
179
explicit = explicit,
163
180
) ,
164
- plus_lt,
181
+ plus_lt. clone ( ) ,
165
182
Applicability :: MaybeIncorrect ,
166
183
) ;
167
- } ;
184
+ }
168
185
}
169
186
TyKind :: TraitObject ( _, lt) => match lt. name {
170
187
LifetimeName :: ImplicitObjectLifetimeDefault => {
@@ -176,15 +193,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
176
193
captures = captures,
177
194
explicit = explicit,
178
195
) ,
179
- plus_lt,
196
+ plus_lt. clone ( ) ,
180
197
Applicability :: MaybeIncorrect ,
181
198
) ;
182
199
}
183
- _ => {
200
+ name if name. ident ( ) . to_string ( ) != lifetime_name => {
201
+ // With this check we avoid suggesting redundant bounds. This
202
+ // would happen if there are nested impl/dyn traits and only
203
+ // one of them has the bound we'd suggest already there, like
204
+ // in `impl Foo<X = dyn Bar> + '_`.
184
205
err. span_suggestion_verbose (
185
206
lt. span ,
186
207
& format ! ( "{} trait object's {}" , consider, explicit_static) ,
187
- lifetime_name,
208
+ lifetime_name. clone ( ) ,
188
209
Applicability :: MaybeIncorrect ,
189
210
) ;
190
211
err. span_suggestion_verbose (
@@ -194,6 +215,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
194
215
Applicability :: MaybeIncorrect ,
195
216
) ;
196
217
}
218
+ _ => { }
197
219
} ,
198
220
_ => { }
199
221
}
0 commit comments