@@ -116,7 +116,7 @@ abstract class ItemNode extends Locatable {
116
116
}
117
117
118
118
pragma [ nomagic]
119
- private ItemNode getASuccessorRec ( string name ) {
119
+ ItemNode getASuccessorRec ( string name ) {
120
120
sourceFileEdge ( this , name , result )
121
121
or
122
122
this = result .getImmediateParent ( ) and
@@ -613,11 +613,11 @@ private predicate fileModule(SourceFile f, string name, Folder folder) {
613
613
}
614
614
615
615
/**
616
- * Holds if `m` is a `mod name;` module declaration happening in a file named
617
- * `fileName.rs`, inside the folder `parent` .
616
+ * Holds if `m` is a `mod name;` module declaration, where the corresponding
617
+ * module file needs to be looked up in `lookup` or one of its descandants .
618
618
*/
619
- private predicate modImport ( Module m , string fileName , string name , Folder parent ) {
620
- exists ( File f |
619
+ private predicate modImport0 ( Module m , string name , Folder lookup ) {
620
+ exists ( File f , Folder parent , string fileName |
621
621
f = m .getFile ( ) and
622
622
not m .hasItemList ( ) and
623
623
// TODO: handle
@@ -629,17 +629,63 @@ private predicate modImport(Module m, string fileName, string name, Folder paren
629
629
name = m .getName ( ) .getText ( ) and
630
630
parent = f .getParentContainer ( ) and
631
631
fileName = f .getStem ( )
632
+ |
633
+ // sibling import
634
+ lookup = parent and
635
+ (
636
+ m .getFile ( ) = any ( CrateItemNode c ) .getModuleNode ( ) .( SourceFileItemNode ) .getFile ( )
637
+ or
638
+ m .getFile ( ) .getBaseName ( ) = "mod.rs"
639
+ )
640
+ or
641
+ // child import
642
+ lookup = parent .getFolder ( fileName )
643
+ )
644
+ }
645
+
646
+ /**
647
+ * Holds if `m` is a `mod name;` module declaration, which happens inside a
648
+ * nested module, and `pred -> succ` is a module edge leading to `m`.
649
+ */
650
+ private predicate modImportNested ( ModuleItemNode m , ModuleItemNode pred , ModuleItemNode succ ) {
651
+ pred .getAnItemInScope ( ) = succ and
652
+ (
653
+ modImport0 ( m , _, _) and
654
+ succ = m
655
+ or
656
+ modImportNested ( m , succ , _)
657
+ )
658
+ }
659
+
660
+ /**
661
+ * Holds if `m` is a `mod name;` module declaration, which happens inside a
662
+ * nested module, where `ancestor` is a reflexive transitive ancestor module
663
+ * of `m` with corresponding lookup folder `lookup`.
664
+ */
665
+ private predicate modImportNestedLookup ( Module m , ModuleItemNode ancestor , Folder lookup ) {
666
+ modImport0 ( m , _, lookup ) and
667
+ modImportNested ( m , ancestor , _) and
668
+ not modImportNested ( m , _, ancestor )
669
+ or
670
+ exists ( ModuleItemNode m1 , Folder mid |
671
+ modImportNestedLookup ( m , m1 , mid ) and
672
+ modImportNested ( m , m1 , ancestor ) and
673
+ lookup = mid .getFolder ( m1 .getName ( ) )
632
674
)
633
675
}
634
676
635
677
/** Holds if `m` is a `mod name;` item importing file `f`. */
636
678
private predicate fileImport ( Module m , SourceFile f ) {
637
- exists ( string fileName , string name , Folder parent | modImport ( m , fileName , name , parent ) |
638
- // sibling import
679
+ exists ( string name , Folder parent |
680
+ modImport0 ( m , name , _ ) and
639
681
fileModule ( f , name , parent )
682
+ |
683
+ // `m` is not inside a nested module
684
+ modImport0 ( m , name , parent ) and
685
+ not modImportNested ( m , _, _)
640
686
or
641
- // child import
642
- fileModule ( f , name , parent . getFolder ( fileName ) )
687
+ // `m` is inside a nested module
688
+ modImportNestedLookup ( m , m , parent )
643
689
)
644
690
}
645
691
@@ -651,7 +697,7 @@ pragma[nomagic]
651
697
private predicate fileImportEdge ( Module mod , string name , ItemNode item ) {
652
698
exists ( SourceFileItemNode f |
653
699
fileImport ( mod , f ) and
654
- item = f .getASuccessor ( name )
700
+ item = f .getASuccessorRec ( name )
655
701
)
656
702
}
657
703
@@ -660,7 +706,7 @@ private predicate fileImportEdge(Module mod, string name, ItemNode item) {
660
706
*/
661
707
pragma [ nomagic]
662
708
private predicate crateDefEdge ( CrateItemNode c , string name , ItemNode i ) {
663
- i = c .getModuleNode ( ) .getASuccessor ( name ) and
709
+ i = c .getModuleNode ( ) .getASuccessorRec ( name ) and
664
710
not i instanceof Crate
665
711
}
666
712
@@ -742,7 +788,16 @@ private predicate unqualifiedPathLookup(RelevantPath p, string name, Namespace n
742
788
// lookup in an outer scope, but only if the item is not declared in inner scope
743
789
exists ( ItemNode mid |
744
790
unqualifiedPathLookup ( p , name , ns , mid ) and
745
- not declares ( mid , ns , name )
791
+ not declares ( mid , ns , name ) and
792
+ not name = [ "super" , "self" ] and
793
+ not (
794
+ name = "Self" and
795
+ mid = any ( ImplOrTraitItemNode i ) .getAnItemInSelfScope ( )
796
+ ) and
797
+ not (
798
+ name = "crate" and
799
+ mid = any ( CrateItemNode i ) .getASourceFile ( )
800
+ )
746
801
|
747
802
// nested modules do not have unqualified access to items from outer modules,
748
803
// except for items declared at top-level in the source file
@@ -943,15 +998,19 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
943
998
encl .getADescendant ( ) = use and
944
999
item = getASuccessor ( used , name , ns ) and
945
1000
// glob imports can be shadowed
946
- not declares ( encl , ns , name )
1001
+ not declares ( encl , ns , name ) and
1002
+ not name = [ "super" , "self" , "Self" , "crate" ]
947
1003
)
948
- else item = used
949
- |
950
- not tree .hasRename ( ) and
951
- name = item .getName ( )
952
- or
953
- name = tree .getRename ( ) .getName ( ) .getText ( ) and
954
- name != "_"
1004
+ else (
1005
+ item = used and
1006
+ (
1007
+ not tree .hasRename ( ) and
1008
+ name = item .getName ( )
1009
+ or
1010
+ name = tree .getRename ( ) .getName ( ) .getText ( ) and
1011
+ name != "_"
1012
+ )
1013
+ )
955
1014
)
956
1015
}
957
1016
@@ -961,7 +1020,7 @@ private module Debug {
961
1020
exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
962
1021
result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
963
1022
filepath .matches ( "%/main.rs" ) and
964
- startline = 1
1023
+ startline = [ 1 , 3 ]
965
1024
)
966
1025
}
967
1026
0 commit comments