@@ -83,9 +83,8 @@ mod handlers {
8383#[ cfg( test) ]
8484mod tests;
8585
86- use std:: { iter , sync:: LazyLock } ;
86+ use std:: sync:: LazyLock ;
8787
88- use either:: Either ;
8988use hir:: {
9089 Crate , DisplayTarget , InFile , Semantics , db:: ExpandDatabase , diagnostics:: AnyDiagnostic ,
9190} ;
@@ -97,11 +96,9 @@ use ide_db::{
9796 imports:: insert_use:: InsertUseConfig ,
9897 label:: Label ,
9998 source_change:: SourceChange ,
100- syntax_helpers:: node_ext:: parse_tt_as_comma_sep_paths,
10199} ;
102- use itertools:: Itertools ;
103100use syntax:: {
104- AstPtr , Edition , NodeOrToken , SmolStr , SyntaxKind , SyntaxNode , SyntaxNodePtr , T , TextRange ,
101+ AstPtr , Edition , SmolStr , SyntaxNode , SyntaxNodePtr , TextRange ,
105102 ast:: { self , AstNode } ,
106103} ;
107104
@@ -483,7 +480,7 @@ pub fn semantic_diagnostics(
483480
484481 // The edition isn't accurate (each diagnostics may have its own edition due to macros),
485482 // but it's okay as it's only being used for error recovery.
486- handle_lints ( & ctx. sema , & mut lints, editioned_file_id. edition ( db) ) ;
483+ handle_lints ( & ctx. sema , krate , & mut lints, editioned_file_id. edition ( db) ) ;
487484
488485 res. retain ( |d| d. severity != Severity :: Allow ) ;
489486
@@ -591,6 +588,7 @@ fn build_lints_map(
591588
592589fn handle_lints (
593590 sema : & Semantics < ' _ , RootDatabase > ,
591+ krate : hir:: Crate ,
594592 diagnostics : & mut [ ( InFile < SyntaxNode > , & mut Diagnostic ) ] ,
595593 edition : Edition ,
596594) {
@@ -606,10 +604,10 @@ fn handle_lints(
606604 }
607605
608606 let mut diag_severity =
609- lint_severity_at ( sema, node, & lint_groups ( & diag. code , edition) , edition ) ;
607+ lint_severity_at ( sema, krate , node, & lint_groups ( & diag. code , edition) ) ;
610608
611609 if let outline_diag_severity @ Some ( _) =
612- find_outline_mod_lint_severity ( sema, node, diag, edition)
610+ find_outline_mod_lint_severity ( sema, krate , node, diag, edition)
613611 {
614612 diag_severity = outline_diag_severity;
615613 }
@@ -632,6 +630,7 @@ fn default_lint_severity(lint: &Lint, edition: Edition) -> Severity {
632630
633631fn find_outline_mod_lint_severity (
634632 sema : & Semantics < ' _ , RootDatabase > ,
633+ krate : hir:: Crate ,
635634 node : & InFile < SyntaxNode > ,
636635 diag : & Diagnostic ,
637636 edition : Edition ,
@@ -648,8 +647,8 @@ fn find_outline_mod_lint_severity(
648647 let lint_groups = lint_groups ( & diag. code , edition) ;
649648 lint_attrs (
650649 sema,
651- & ast :: AnyHasAttrs :: cast ( module_source_file . value ) . expect ( "SourceFile always has attrs" ) ,
652- edition ,
650+ krate ,
651+ ast :: AnyHasAttrs :: cast ( module_source_file . value ) . expect ( "SourceFile always has attrs" ) ,
653652 )
654653 . for_each ( |( lint, severity) | {
655654 if lint_groups. contains ( & lint) {
@@ -661,106 +660,36 @@ fn find_outline_mod_lint_severity(
661660
662661fn lint_severity_at (
663662 sema : & Semantics < ' _ , RootDatabase > ,
663+ krate : hir:: Crate ,
664664 node : & InFile < SyntaxNode > ,
665665 lint_groups : & LintGroups ,
666- edition : Edition ,
667666) -> Option < Severity > {
668667 node. value
669668 . ancestors ( )
670669 . filter_map ( ast:: AnyHasAttrs :: cast)
671670 . find_map ( |ancestor| {
672- lint_attrs ( sema, & ancestor , edition )
671+ lint_attrs ( sema, krate , ancestor )
673672 . find_map ( |( lint, severity) | lint_groups. contains ( & lint) . then_some ( severity) )
674673 } )
675674 . or_else ( || {
676- lint_severity_at ( sema, & sema. find_parent_file ( node. file_id ) ?, lint_groups, edition )
675+ lint_severity_at ( sema, krate , & sema. find_parent_file ( node. file_id ) ?, lint_groups)
677676 } )
678677}
679678
680679// FIXME: Switch this to analysis' `expand_cfg_attr`.
681- fn lint_attrs < ' a > (
682- sema : & ' a Semantics < ' a , RootDatabase > ,
683- ancestor : & ' a ast:: AnyHasAttrs ,
684- edition : Edition ,
685- ) -> impl Iterator < Item = ( SmolStr , Severity ) > + ' a {
686- ast:: attrs_including_inner ( ancestor)
687- . filter_map ( |attr| {
688- attr. as_simple_call ( ) . and_then ( |( name, value) | match & * name {
689- "allow" | "expect" => Some ( Either :: Left ( iter:: once ( ( Severity :: Allow , value) ) ) ) ,
690- "warn" => Some ( Either :: Left ( iter:: once ( ( Severity :: Warning , value) ) ) ) ,
691- "forbid" | "deny" => Some ( Either :: Left ( iter:: once ( ( Severity :: Error , value) ) ) ) ,
692- "cfg_attr" => {
693- let mut lint_attrs = Vec :: new ( ) ;
694- cfg_attr_lint_attrs ( sema, & value, & mut lint_attrs) ;
695- Some ( Either :: Right ( lint_attrs. into_iter ( ) ) )
696- }
697- _ => None ,
698- } )
699- } )
700- . flatten ( )
701- . flat_map ( move |( severity, lints) | {
702- parse_tt_as_comma_sep_paths ( lints, edition) . into_iter ( ) . flat_map ( move |lints| {
703- // Rejoin the idents with `::`, so we have no spaces in between.
704- lints. into_iter ( ) . map ( move |lint| {
705- (
706- lint. segments ( ) . filter_map ( |segment| segment. name_ref ( ) ) . join ( "::" ) . into ( ) ,
707- severity,
708- )
709- } )
710- } )
711- } )
712- }
713-
714- fn cfg_attr_lint_attrs (
680+ fn lint_attrs (
715681 sema : & Semantics < ' _ , RootDatabase > ,
716- value : & ast:: TokenTree ,
717- lint_attrs : & mut Vec < ( Severity , ast:: TokenTree ) > ,
718- ) {
719- let prev_len = lint_attrs. len ( ) ;
720-
721- let mut iter = value. token_trees_and_tokens ( ) . filter ( |it| match it {
722- NodeOrToken :: Node ( _) => true ,
723- NodeOrToken :: Token ( it) => !it. kind ( ) . is_trivia ( ) ,
724- } ) ;
725-
726- // Skip the condition.
727- for value in & mut iter {
728- if value. as_token ( ) . is_some_and ( |it| it. kind ( ) == T ! [ , ] ) {
729- break ;
730- }
731- }
732-
733- while let Some ( value) = iter. next ( ) {
734- if let Some ( token) = value. as_token ( )
735- && token. kind ( ) == SyntaxKind :: IDENT
736- {
737- let severity = match token. text ( ) {
738- "allow" | "expect" => Some ( Severity :: Allow ) ,
739- "warn" => Some ( Severity :: Warning ) ,
740- "forbid" | "deny" => Some ( Severity :: Error ) ,
741- "cfg_attr" => {
742- if let Some ( NodeOrToken :: Node ( value) ) = iter. next ( ) {
743- cfg_attr_lint_attrs ( sema, & value, lint_attrs) ;
744- }
745- None
746- }
747- _ => None ,
748- } ;
749- if let Some ( severity) = severity {
750- let lints = iter. next ( ) ;
751- if let Some ( NodeOrToken :: Node ( lints) ) = lints {
752- lint_attrs. push ( ( severity, lints) ) ;
753- }
754- }
755- }
756- }
757-
758- if prev_len != lint_attrs. len ( )
759- && let Some ( false ) | None = sema. check_cfg_attr ( value)
760- {
761- // Discard the attributes when the condition is false.
762- lint_attrs. truncate ( prev_len) ;
763- }
682+ krate : hir:: Crate ,
683+ ancestor : ast:: AnyHasAttrs ,
684+ ) -> impl Iterator < Item = ( SmolStr , Severity ) > {
685+ sema. lint_attrs ( krate, ancestor) . map ( |( lint_attr, lint) | {
686+ let severity = match lint_attr {
687+ hir:: LintAttr :: Allow | hir:: LintAttr :: Expect => Severity :: Allow ,
688+ hir:: LintAttr :: Warn => Severity :: Warning ,
689+ hir:: LintAttr :: Deny | hir:: LintAttr :: Forbid => Severity :: Error ,
690+ } ;
691+ ( lint, severity)
692+ } )
764693}
765694
766695#[ derive( Debug ) ]
0 commit comments