@@ -172,6 +172,18 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) {
172172 _ => None
173173 } ;
174174 check_associated_item ( tcx, trait_item. hir_id , trait_item. span , method_sig) ;
175+
176+ // Prohibits applying `#[track_caller]` to trait decls
177+ for attr in & trait_item. attrs {
178+ if attr. check_name ( sym:: track_caller) {
179+ struct_span_err ! (
180+ tcx. sess,
181+ attr. span,
182+ E0738 ,
183+ "`#[track_caller]` is not supported in trait declarations."
184+ ) . emit ( ) ;
185+ }
186+ }
175187}
176188
177189pub fn check_impl_item ( tcx : TyCtxt < ' _ > , def_id : DefId ) {
@@ -182,6 +194,30 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) {
182194 hir:: ImplItemKind :: Method ( ref sig, _) => Some ( sig) ,
183195 _ => None
184196 } ;
197+
198+ // Prohibits applying `#[track_caller]` to trait impls
199+ if method_sig. is_some ( ) {
200+ let track_caller_attr = impl_item. attrs . iter ( )
201+ . find ( |a| a. check_name ( sym:: track_caller) ) ;
202+ if let Some ( tc_attr) = track_caller_attr {
203+ let parent_hir_id = tcx. hir ( ) . get_parent_item ( hir_id) ;
204+ let containing_item = tcx. hir ( ) . expect_item ( parent_hir_id) ;
205+ let containing_impl_is_for_trait = match & containing_item. kind {
206+ hir:: ItemKind :: Impl ( _, _, _, _, tr, _, _) => tr. is_some ( ) ,
207+ _ => bug ! ( "parent of an ImplItem must be an Impl" ) ,
208+ } ;
209+
210+ if containing_impl_is_for_trait {
211+ struct_span_err ! (
212+ tcx. sess,
213+ tc_attr. span,
214+ E0738 ,
215+ "`#[track_caller]` is not supported in traits yet."
216+ ) . emit ( ) ;
217+ }
218+ }
219+ }
220+
185221 check_associated_item ( tcx, impl_item. hir_id , impl_item. span , method_sig) ;
186222}
187223
0 commit comments