@@ -8,6 +8,7 @@ use std::mem;
88use base_db:: CrateId ;
99use either:: Either ;
1010use hir_expand:: {
11+ mod_path:: tool_path,
1112 name:: { AsName , Name } ,
1213 span_map:: { ExpansionSpanMap , SpanMap } ,
1314 InFile , MacroDefId ,
@@ -27,6 +28,7 @@ use text_size::TextSize;
2728use triomphe:: Arc ;
2829
2930use crate :: {
31+ attr:: Attrs ,
3032 body:: { Body , BodyDiagnostic , BodySourceMap , ExprPtr , HygieneId , LabelPtr , PatPtr } ,
3133 builtin_type:: BuiltinUint ,
3234 data:: adt:: StructKind ,
@@ -212,6 +214,43 @@ impl ExprCollector<'_> {
212214 body : Option < ast:: Expr > ,
213215 is_async_fn : bool ,
214216 ) -> ( 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+
215254 self . awaitable_context . replace ( if is_async_fn {
216255 Awaitable :: Yes
217256 } else {
0 commit comments