@@ -11,7 +11,7 @@ use crate::ty::TyCtxt;
1111use crate :: ty:: query:: Providers ;
1212
1313use std:: fmt:: { self , Display } ;
14- use syntax:: symbol:: sym;
14+ use syntax:: { attr , symbol:: sym} ;
1515use syntax_pos:: Span ;
1616
1717#[ derive( Copy , Clone , PartialEq ) ]
@@ -103,6 +103,8 @@ impl CheckAttrVisitor<'tcx> {
103103 self . check_marker ( attr, item, target)
104104 } else if attr. check_name ( sym:: target_feature) {
105105 self . check_target_feature ( attr, item, target)
106+ } else if attr. check_name ( sym:: track_caller) {
107+ self . check_track_caller ( attr, & item, target)
106108 } else {
107109 true
108110 } ;
@@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
135137 }
136138 }
137139
140+ /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
141+ fn check_track_caller ( & self , attr : & hir:: Attribute , item : & hir:: Item , target : Target ) -> bool {
142+ if target != Target :: Fn {
143+ struct_span_err ! (
144+ self . tcx. sess,
145+ attr. span,
146+ E0735 ,
147+ "attribute should be applied to function"
148+ )
149+ . span_label ( item. span , "not a function" )
150+ . emit ( ) ;
151+ false
152+ } else if attr:: contains_name ( & item. attrs , sym:: naked) {
153+ struct_span_err ! (
154+ self . tcx. sess,
155+ attr. span,
156+ E0736 ,
157+ "cannot use `#[track_caller]` with `#[naked]`" ,
158+ )
159+ . emit ( ) ;
160+ false
161+ } else {
162+ true
163+ }
164+ }
165+
138166 /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
139167 fn check_non_exhaustive (
140168 & self ,
0 commit comments