@@ -16,7 +16,7 @@ use syntax::{
1616 self , ArgListOwner , ArrayExprKind , AstChildren , LiteralKind , LoopBodyOwner , NameOwner ,
1717 SlicePatComponents ,
1818 } ,
19- AstNode , AstPtr ,
19+ AstNode , AstPtr , SyntaxNodePtr ,
2020} ;
2121use test_utils:: mark;
2222
@@ -25,6 +25,7 @@ use crate::{
2525 body:: { Body , BodySourceMap , Expander , PatPtr , SyntheticSyntax } ,
2626 builtin_type:: { BuiltinFloat , BuiltinInt } ,
2727 db:: DefDatabase ,
28+ diagnostics:: InactiveCode ,
2829 expr:: {
2930 dummy_expr_id, ArithOp , Array , BinaryOp , BindingAnnotation , CmpOp , Expr , ExprId , Literal ,
3031 LogicOp , MatchArm , Ordering , Pat , PatId , RecordFieldPat , RecordLitField , Statement ,
@@ -37,7 +38,7 @@ use crate::{
3738 StaticLoc , StructLoc , TraitLoc , TypeAliasLoc , UnionLoc ,
3839} ;
3940
40- use super :: { ExprSource , PatSource } ;
41+ use super :: { diagnostics :: BodyDiagnostic , ExprSource , PatSource } ;
4142
4243pub ( crate ) struct LowerCtx {
4344 hygiene : Hygiene ,
@@ -176,7 +177,7 @@ impl ExprCollector<'_> {
176177
177178 fn collect_expr ( & mut self , expr : ast:: Expr ) -> ExprId {
178179 let syntax_ptr = AstPtr :: new ( & expr) ;
179- if ! self . expander . is_cfg_enabled ( & expr) {
180+ if self . check_cfg ( & expr) . is_none ( ) {
180181 return self . missing_expr ( ) ;
181182 }
182183
@@ -354,13 +355,15 @@ impl ExprCollector<'_> {
354355 let arms = if let Some ( match_arm_list) = e. match_arm_list ( ) {
355356 match_arm_list
356357 . arms ( )
357- . map ( |arm| MatchArm {
358- pat : self . collect_pat_opt ( arm. pat ( ) ) ,
359- expr : self . collect_expr_opt ( arm. expr ( ) ) ,
360- guard : arm
361- . guard ( )
362- . and_then ( |guard| guard. expr ( ) )
363- . map ( |e| self . collect_expr ( e) ) ,
358+ . filter_map ( |arm| {
359+ self . check_cfg ( & arm) . map ( |( ) | MatchArm {
360+ pat : self . collect_pat_opt ( arm. pat ( ) ) ,
361+ expr : self . collect_expr_opt ( arm. expr ( ) ) ,
362+ guard : arm
363+ . guard ( )
364+ . and_then ( |guard| guard. expr ( ) )
365+ . map ( |e| self . collect_expr ( e) ) ,
366+ } )
364367 } )
365368 . collect ( )
366369 } else {
@@ -406,9 +409,8 @@ impl ExprCollector<'_> {
406409 . fields ( )
407410 . inspect ( |field| field_ptrs. push ( AstPtr :: new ( field) ) )
408411 . filter_map ( |field| {
409- if !self . expander . is_cfg_enabled ( & field) {
410- return None ;
411- }
412+ self . check_cfg ( & field) ?;
413+
412414 let name = field. field_name ( ) ?. as_name ( ) ;
413415
414416 Some ( RecordLitField {
@@ -620,15 +622,23 @@ impl ExprCollector<'_> {
620622 . filter_map ( |s| {
621623 let stmt = match s {
622624 ast:: Stmt :: LetStmt ( stmt) => {
625+ self . check_cfg ( & stmt) ?;
626+
623627 let pat = self . collect_pat_opt ( stmt. pat ( ) ) ;
624628 let type_ref = stmt. ty ( ) . map ( |it| TypeRef :: from_ast ( & self . ctx ( ) , it) ) ;
625629 let initializer = stmt. initializer ( ) . map ( |e| self . collect_expr ( e) ) ;
626630 Statement :: Let { pat, type_ref, initializer }
627631 }
628632 ast:: Stmt :: ExprStmt ( stmt) => {
633+ self . check_cfg ( & stmt) ?;
634+
629635 Statement :: Expr ( self . collect_expr_opt ( stmt. expr ( ) ) )
630636 }
631- ast:: Stmt :: Item ( _) => return None ,
637+ ast:: Stmt :: Item ( item) => {
638+ self . check_cfg ( & item) ?;
639+
640+ return None ;
641+ }
632642 } ;
633643 Some ( stmt)
634644 } )
@@ -872,6 +882,28 @@ impl ExprCollector<'_> {
872882
873883 ( args, ellipsis)
874884 }
885+
886+ /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when
887+ /// not.
888+ fn check_cfg ( & mut self , owner : & dyn ast:: AttrsOwner ) -> Option < ( ) > {
889+ match self . expander . parse_attrs ( owner) . cfg ( ) {
890+ Some ( cfg) => {
891+ if self . expander . cfg_options ( ) . check ( & cfg) != Some ( false ) {
892+ return Some ( ( ) ) ;
893+ }
894+
895+ self . source_map . diagnostics . push ( BodyDiagnostic :: InactiveCode ( InactiveCode {
896+ file : self . expander . current_file_id ,
897+ node : SyntaxNodePtr :: new ( owner. syntax ( ) ) ,
898+ cfg,
899+ opts : self . expander . cfg_options ( ) . clone ( ) ,
900+ } ) ) ;
901+
902+ None
903+ }
904+ None => Some ( ( ) ) ,
905+ }
906+ }
875907}
876908
877909impl From < ast:: BinOp > for BinaryOp {
0 commit comments