@@ -8,6 +8,7 @@ use std::mem;
8
8
use base_db:: CrateId ;
9
9
use either:: Either ;
10
10
use hir_expand:: {
11
+ mod_path:: tool_path,
11
12
name:: { AsName , Name } ,
12
13
span_map:: { ExpansionSpanMap , SpanMap } ,
13
14
InFile , MacroDefId ,
@@ -27,6 +28,7 @@ use text_size::TextSize;
27
28
use triomphe:: Arc ;
28
29
29
30
use crate :: {
31
+ attr:: Attrs ,
30
32
body:: { Body , BodyDiagnostic , BodySourceMap , ExprPtr , HygieneId , LabelPtr , PatPtr } ,
31
33
builtin_type:: BuiltinUint ,
32
34
data:: adt:: StructKind ,
@@ -212,6 +214,43 @@ impl ExprCollector<'_> {
212
214
body : Option < ast:: Expr > ,
213
215
is_async_fn : bool ,
214
216
) -> ( Body , BodySourceMap ) {
217
+ let skip_body = match self . owner {
218
+ DefWithBodyId :: FunctionId ( it) => self . db . attrs ( it. into ( ) ) ,
219
+ DefWithBodyId :: StaticId ( it) => self . db . attrs ( it. into ( ) ) ,
220
+ DefWithBodyId :: ConstId ( it) => self . db . attrs ( it. into ( ) ) ,
221
+ DefWithBodyId :: InTypeConstId ( _) => Attrs :: EMPTY ,
222
+ DefWithBodyId :: VariantId ( it) => self . db . attrs ( it. into ( ) ) ,
223
+ }
224
+ . rust_analyzer_tool ( )
225
+ . any ( |attr| * attr. path ( ) == tool_path ! [ skip] ) ;
226
+ // If #[rust_analyzer::skip] annotated, only construct enough information for the signature
227
+ // and skip the body.
228
+ if skip_body {
229
+ self . body . body_expr = self . missing_expr ( ) ;
230
+ if let Some ( ( param_list, mut attr_enabled) ) = param_list {
231
+ if let Some ( self_param) =
232
+ param_list. self_param ( ) . filter ( |_| attr_enabled. next ( ) . unwrap_or ( false ) )
233
+ {
234
+ let is_mutable =
235
+ self_param. mut_token ( ) . is_some ( ) && self_param. amp_token ( ) . is_none ( ) ;
236
+ let binding_id: la_arena:: Idx < Binding > = self . alloc_binding (
237
+ Name :: new_symbol_root ( sym:: self_. clone ( ) ) ,
238
+ BindingAnnotation :: new ( is_mutable, false ) ,
239
+ ) ;
240
+ self . body . self_param = Some ( binding_id) ;
241
+ self . source_map . self_param =
242
+ Some ( self . expander . in_file ( AstPtr :: new ( & self_param) ) ) ;
243
+ }
244
+ self . body . params = param_list
245
+ . params ( )
246
+ . zip ( attr_enabled)
247
+ . filter ( |( _, enabled) | * enabled)
248
+ . map ( |_| self . missing_pat ( ) )
249
+ . collect ( ) ;
250
+ } ;
251
+ return ( self . body , self . source_map ) ;
252
+ }
253
+
215
254
self . awaitable_context . replace ( if is_async_fn {
216
255
Awaitable :: Yes
217
256
} else {
0 commit comments