@@ -113,6 +113,10 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
113
113
| While ( ..)
114
114
| ConstBlock ( _) => break Some ( expr) ,
115
115
116
+ Cast ( _, ty) => {
117
+ break type_trailing_brace ( ty) . then_some ( expr) ;
118
+ }
119
+
116
120
MacCall ( mac) => {
117
121
break ( mac. args . delim == Delimiter :: Brace ) . then_some ( expr) ;
118
122
}
@@ -131,7 +135,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
131
135
| MethodCall ( _)
132
136
| Tup ( _)
133
137
| Lit ( _)
134
- | Cast ( _, _)
135
138
| Type ( _, _)
136
139
| Await ( _, _)
137
140
| Field ( _, _)
@@ -148,3 +151,71 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
148
151
}
149
152
}
150
153
}
154
+
155
+ /// Whether the type's last token is `}`.
156
+ fn type_trailing_brace ( mut ty : & ast:: Ty ) -> bool {
157
+ loop {
158
+ match & ty. kind {
159
+ ast:: TyKind :: AnonStruct ( ..) | ast:: TyKind :: AnonUnion ( ..) => break true ,
160
+
161
+ ast:: TyKind :: MacCall ( mac) => break mac. args . delim == Delimiter :: Brace ,
162
+
163
+ ast:: TyKind :: Ptr ( mut_ty) | ast:: TyKind :: Ref ( _, mut_ty) => {
164
+ ty = & mut_ty. ty ;
165
+ }
166
+
167
+ ast:: TyKind :: BareFn ( fn_ty) => match & fn_ty. decl . output {
168
+ ast:: FnRetTy :: Default ( _) => break false ,
169
+ ast:: FnRetTy :: Ty ( ret) => ty = ret,
170
+ } ,
171
+
172
+ ast:: TyKind :: Path ( _, path) => match path_return_type ( path) {
173
+ Some ( trailing_ty) => ty = trailing_ty,
174
+ None => break false ,
175
+ } ,
176
+
177
+ ast:: TyKind :: TraitObject ( bounds, _) | ast:: TyKind :: ImplTrait ( _, bounds, _) => {
178
+ match bounds. last ( ) {
179
+ Some ( ast:: GenericBound :: Trait ( bound, _) ) => {
180
+ match path_return_type ( & bound. trait_ref . path ) {
181
+ Some ( trailing_ty) => ty = trailing_ty,
182
+ None => break false ,
183
+ }
184
+ }
185
+ Some ( ast:: GenericBound :: Outlives ( _) ) | None => break false ,
186
+ }
187
+ }
188
+
189
+ ast:: TyKind :: Slice ( ..)
190
+ | ast:: TyKind :: Array ( ..)
191
+ | ast:: TyKind :: Never
192
+ | ast:: TyKind :: Tup ( ..)
193
+ | ast:: TyKind :: Paren ( ..)
194
+ | ast:: TyKind :: Typeof ( ..)
195
+ | ast:: TyKind :: Infer
196
+ | ast:: TyKind :: ImplicitSelf
197
+ | ast:: TyKind :: CVarArgs
198
+ | ast:: TyKind :: Pat ( ..)
199
+ | ast:: TyKind :: Dummy
200
+ | ast:: TyKind :: Err ( ..) => break false ,
201
+ }
202
+ }
203
+ }
204
+
205
+ /// Returns the trailing return type in the given path, if it has one.
206
+ ///
207
+ /// ```ignore (illustrative)
208
+ /// ::std::ops::FnOnce(&str) -> fn() -> *const c_void
209
+ /// ^^^^^^^^^^^^^^^^^^^^^
210
+ /// ```
211
+ fn path_return_type ( path : & ast:: Path ) -> Option < & ast:: Ty > {
212
+ let last_segment = path. segments . last ( ) ?;
213
+ let args = last_segment. args . as_ref ( ) ?;
214
+ match & * * args {
215
+ ast:: GenericArgs :: Parenthesized ( args) => match & args. output {
216
+ ast:: FnRetTy :: Default ( _) => None ,
217
+ ast:: FnRetTy :: Ty ( ret) => Some ( ret) ,
218
+ } ,
219
+ ast:: GenericArgs :: AngleBracketed ( _) => None ,
220
+ }
221
+ }
0 commit comments