@@ -25,7 +25,7 @@ use rustc_hir::def_id::LocalModId;
2525use rustc_hir:: intravisit:: { self , Visitor } ;
2626use rustc_hir:: {
2727 self as hir, Attribute , CRATE_HIR_ID , Constness , FnSig , ForeignItem , GenericParam ,
28- GenericParamKind , HirId , Item , ItemKind , MethodKind , Node , ParamName , Target , TraitItem ,
28+ GenericParamKind , HirId , Item , ItemKind , MethodKind , Mod , Node , ParamName , Target , TraitItem ,
2929 find_attr,
3030} ;
3131use rustc_macros:: Diagnostic ;
@@ -291,7 +291,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
291291 AttributeKind :: Optimize ( ..) => ( ) ,
292292 AttributeKind :: PanicRuntime => ( ) ,
293293 AttributeKind :: PatchableFunctionEntry { .. } => ( ) ,
294- AttributeKind :: Path ( .. ) => ( ) ,
294+ AttributeKind :: Path ( _ , span ) => self . check_path ( * span , hir_id ) ,
295295 AttributeKind :: PatternComplexityLimit { .. } => ( ) ,
296296 AttributeKind :: PinV2 ( ..) => ( ) ,
297297 AttributeKind :: PreludeImport => ( ) ,
@@ -411,6 +411,52 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
411411 }
412412 }
413413
414+ fn check_path ( & self , span : Span , hir_id : HirId ) {
415+ let Node :: Item ( item) = self . tcx . hir_node ( hir_id) else {
416+ return ;
417+ } ;
418+
419+ let ItemKind :: Mod ( _, module) = & item. kind else {
420+ return ;
421+ } ;
422+
423+ if !item. span . contains ( module. spans . inner_span ) {
424+ return ;
425+ }
426+
427+ // Do not warn when a nested module uses `#[path]` or is out-of-line,
428+ // because the attribute may affect nested module path resolution.
429+ if self . has_nested_module_path_dependency ( module) {
430+ return ;
431+ }
432+
433+ self . tcx . emit_node_span_lint (
434+ UNUSED_ATTRIBUTES ,
435+ hir_id,
436+ span,
437+ diagnostics:: Unused {
438+ attr_span : span,
439+ note : diagnostics:: UnusedNote :: PathOnInlineModule ,
440+ } ,
441+ ) ;
442+ }
443+
444+ fn has_nested_module_path_dependency ( & self , module : & Mod < ' tcx > ) -> bool {
445+ module. item_ids . iter ( ) . any ( |item_id| {
446+ let child = self . tcx . hir_item ( * item_id) ;
447+
448+ let ItemKind :: Mod ( _, child_module) = & child. kind else {
449+ return false ;
450+ } ;
451+
452+ let is_out_of_line = !child. span . contains ( child_module. spans . inner_span ) ;
453+
454+ let has_path_attr = find_attr ! ( self . tcx, child. hir_id( ) , Path ( ..) ) ;
455+
456+ is_out_of_line || has_path_attr || self . has_nested_module_path_dependency ( child_module)
457+ } )
458+ }
459+
414460 fn check_rustc_must_implement_one_of (
415461 & self ,
416462 attr_span : Span ,
0 commit comments