@@ -11,7 +11,7 @@ use crate::ty::TyCtxt;
11
11
use crate :: ty:: query:: Providers ;
12
12
13
13
use std:: fmt:: { self , Display } ;
14
- use syntax:: symbol:: sym;
14
+ use syntax:: { attr , symbol:: sym} ;
15
15
use syntax_pos:: Span ;
16
16
17
17
#[ derive( Copy , Clone , PartialEq ) ]
@@ -103,6 +103,8 @@ impl CheckAttrVisitor<'tcx> {
103
103
self . check_marker ( attr, item, target)
104
104
} else if attr. check_name ( sym:: target_feature) {
105
105
self . check_target_feature ( attr, item, target)
106
+ } else if attr. check_name ( sym:: track_caller) {
107
+ self . check_track_caller ( attr, & item, target)
106
108
} else {
107
109
true
108
110
} ;
@@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
135
137
}
136
138
}
137
139
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
+
138
166
/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
139
167
fn check_non_exhaustive (
140
168
& self ,
0 commit comments