@@ -102,43 +102,89 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
102
102
None => String :: new ( ) ,
103
103
} ;
104
104
105
- let ( span_1, span_2, main_label, span_label) = match ( sup_is_ret_type, sub_is_ret_type) {
106
- ( None , None ) => {
107
- let ( main_label_1, span_label_1) = if ty_sup. hir_id == ty_sub. hir_id {
105
+ let ( span_1, span_2, main_label, span_label, future_return_type) =
106
+ match ( sup_is_ret_type, sub_is_ret_type) {
107
+ ( None , None ) => {
108
+ let ( main_label_1, span_label_1) = if ty_sup. hir_id == ty_sub. hir_id {
109
+ (
110
+ "this type is declared with multiple lifetimes..." . to_owned ( ) ,
111
+ "...but data with one lifetime flows into the other here" . to_owned ( ) ,
112
+ )
113
+ } else {
114
+ (
115
+ "these two types are declared with different lifetimes..." . to_owned ( ) ,
116
+ format ! ( "...but data{} flows{} here" , span_label_var1, span_label_var2) ,
117
+ )
118
+ } ;
119
+ ( ty_sup. span , ty_sub. span , main_label_1, span_label_1, None )
120
+ }
121
+
122
+ ( Some ( ret_span) , _) => {
123
+ let sup_future = self . future_return_type ( scope_def_id_sup) ;
124
+ let ( return_type, action) = if let Some ( _) = sup_future {
125
+ ( "returned future" , "held across an await point" )
126
+ } else {
127
+ ( "return type" , "returned" )
128
+ } ;
129
+
108
130
(
109
- "this type is declared with multiple lifetimes..." . to_owned ( ) ,
110
- "...but data with one lifetime flows into the other here" . to_owned ( ) ,
131
+ ty_sub. span ,
132
+ ret_span,
133
+ format ! (
134
+ "this parameter and the {} are declared with different lifetimes..." ,
135
+ return_type
136
+ ) ,
137
+ format ! ( "...but data{} is {} here" , span_label_var1, action) ,
138
+ sup_future,
111
139
)
112
- } else {
140
+ }
141
+ ( _, Some ( ret_span) ) => {
142
+ let sub_future = self . future_return_type ( scope_def_id_sub) ;
143
+ let ( return_type, action) = if let Some ( _) = sub_future {
144
+ ( "returned future" , "held across an await point" )
145
+ } else {
146
+ ( "return type" , "returned" )
147
+ } ;
148
+
113
149
(
114
- "these two types are declared with different lifetimes..." . to_owned ( ) ,
115
- format ! ( "...but data{} flows{} here" , span_label_var1, span_label_var2) ,
150
+ ty_sup. span ,
151
+ ret_span,
152
+ format ! (
153
+ "this parameter and the {} are declared with different lifetimes..." ,
154
+ return_type
155
+ ) ,
156
+ format ! ( "...but data{} is {} here" , span_label_var1, action) ,
157
+ sub_future,
116
158
)
117
- } ;
118
- ( ty_sup. span , ty_sub. span , main_label_1, span_label_1)
119
- }
120
-
121
- ( Some ( ret_span) , _) => (
122
- ty_sub. span ,
123
- ret_span,
124
- "this parameter and the return type are declared with different lifetimes..."
125
- . to_owned ( ) ,
126
- format ! ( "...but data{} is returned here" , span_label_var1) ,
127
- ) ,
128
- ( _, Some ( ret_span) ) => (
129
- ty_sup. span ,
130
- ret_span,
131
- "this parameter and the return type are declared with different lifetimes..."
132
- . to_owned ( ) ,
133
- format ! ( "...but data{} is returned here" , span_label_var1) ,
134
- ) ,
135
- } ;
136
-
137
- struct_span_err ! ( self . tcx( ) . sess, span, E0623 , "lifetime mismatch" )
138
- . span_label ( span_1, main_label)
139
- . span_label ( span_2, String :: new ( ) )
140
- . span_label ( span, span_label)
141
- . emit ( ) ;
159
+ }
160
+ } ;
161
+
162
+ let mut e = struct_span_err ! ( self . tcx( ) . sess, span, E0623 , "lifetime mismatch" ) ;
163
+
164
+ e. span_label ( span_1, main_label) ;
165
+ e. span_label ( span_2, String :: new ( ) ) ;
166
+ e. span_label ( span, span_label) ;
167
+
168
+ if let Some ( t) = future_return_type {
169
+ let snip = self
170
+ . tcx ( )
171
+ . sess
172
+ . source_map ( )
173
+ . span_to_snippet ( t. span )
174
+ . ok ( )
175
+ . and_then ( |s| match ( & t. kind , s. as_str ( ) ) {
176
+ ( rustc_hir:: TyKind :: Tup ( & [ ] ) , "" ) => Some ( "()" . to_string ( ) ) ,
177
+ ( _, "" ) => None ,
178
+ _ => Some ( s) ,
179
+ } )
180
+ . unwrap_or ( "{unnamed_type}" . to_string ( ) ) ;
181
+
182
+ e. span_label (
183
+ t. span ,
184
+ & format ! ( "this `async fn` implicitly returns an `impl Future<Output = {}>`" , snip) ,
185
+ ) ;
186
+ }
187
+ e. emit ( ) ;
142
188
Some ( ErrorReported )
143
189
}
144
190
}
0 commit comments