@@ -113,6 +113,10 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
113113 | While ( ..)
114114 | ConstBlock ( _) => break Some ( expr) ,
115115
116+ Cast ( _, ty) => {
117+ break type_trailing_brace ( ty) . then_some ( expr) ;
118+ }
119+
116120 MacCall ( mac) => {
117121 break ( mac. args . delim == Delimiter :: Brace ) . then_some ( expr) ;
118122 }
@@ -131,7 +135,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
131135 | MethodCall ( _)
132136 | Tup ( _)
133137 | Lit ( _)
134- | Cast ( _, _)
135138 | Type ( _, _)
136139 | Await ( _, _)
137140 | Field ( _, _)
@@ -148,3 +151,71 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
148151 }
149152 }
150153}
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