@@ -211,6 +211,33 @@ abstract class ItemNode extends Locatable {
211211 ) .( Crate ) .getADependency * ( )
212212 }
213213
214+ /**
215+ * Gets the canonical path of this item, if any.
216+ *
217+ * See [The Rust Reference][1] for more details.
218+ *
219+ * [1]: https://doc.rust-lang.org/reference/paths.html#canonical-paths
220+ */
221+ cached
222+ abstract string getCanonicalPath ( Crate c ) ;
223+
224+ /** Gets the canonical path prefix that this node provides for `child`. */
225+ pragma [ nomagic]
226+ string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
227+ child .getImmediateParent ( ) = this and
228+ result = this .getCanonicalPath ( c )
229+ }
230+
231+ /** Gets the canonical path prefix of this node, if any. */
232+ pragma [ nomagic]
233+ final string getCanonicalPathPrefix ( Crate c ) {
234+ result = any ( ItemNode parent ) .getCanonicalPathPrefixFor ( c , this )
235+ }
236+
237+ /** Gets the canonical path prefix of this node, if any. */
238+ pragma [ nomagic]
239+ final Crate getACanonicalPathCrate ( ) { exists ( this .getCanonicalPathPrefix ( result ) ) }
240+
214241 /** Gets the location of this item. */
215242 Location getLocation ( ) { result = super .getLocation ( ) }
216243}
@@ -257,6 +284,8 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
257284 override predicate isPublic ( ) { any ( ) }
258285
259286 override TypeParam getTypeParam ( int i ) { none ( ) }
287+
288+ override string getCanonicalPath ( Crate c ) { none ( ) }
260289}
261290
262291class CrateItemNode extends ItemNode instanceof Crate {
@@ -304,12 +333,44 @@ class CrateItemNode extends ItemNode instanceof Crate {
304333 override predicate isPublic ( ) { any ( ) }
305334
306335 override TypeParam getTypeParam ( int i ) { none ( ) }
336+
337+ override string getCanonicalPath ( Crate c ) { c = this and result = Crate .super .getName ( ) }
338+
339+ override string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
340+ exists ( ModuleLikeNode m |
341+ result = this .getCanonicalPath ( c ) and
342+ m = this .getModuleNode ( )
343+ |
344+ child = m
345+ or
346+ child .getImmediateParent ( ) = m .( SourceFile ) and
347+ not m = child .( SourceFileItemNode ) .getSuper ( )
348+ )
349+ }
307350}
308351
309352/** An item that can occur in a trait or an `impl` block. */
310353abstract private class AssocItemNode extends ItemNode , AssocItem {
311354 /** Holds if this associated item has an implementation. */
312355 abstract predicate hasImplementation ( ) ;
356+
357+ bindingset [ c]
358+ private string getCanonicalPathPart ( Crate c , int i ) {
359+ i = 0 and
360+ result = this .getCanonicalPathPrefix ( c )
361+ or
362+ i = 1 and
363+ result = "::"
364+ or
365+ i = 2 and
366+ result = this .getName ( )
367+ }
368+
369+ language [ monotonicAggregates]
370+ override string getCanonicalPath ( Crate c ) {
371+ c = this .getACanonicalPathCrate ( ) and
372+ result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
373+ }
313374}
314375
315376private class ConstItemNode extends AssocItemNode instanceof Const {
@@ -332,6 +393,24 @@ private class EnumItemNode extends ItemNode instanceof Enum {
332393 override Visibility getVisibility ( ) { result = Enum .super .getVisibility ( ) }
333394
334395 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
396+
397+ bindingset [ c]
398+ private string getCanonicalPathPart ( Crate c , int i ) {
399+ i = 0 and
400+ result = this .getCanonicalPathPrefix ( c )
401+ or
402+ i = 1 and
403+ result = "::"
404+ or
405+ i = 2 and
406+ result = this .getName ( )
407+ }
408+
409+ language [ monotonicAggregates]
410+ override string getCanonicalPath ( Crate c ) {
411+ c = this .getACanonicalPathCrate ( ) and
412+ result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
413+ }
335414}
336415
337416private class VariantItemNode extends ItemNode instanceof Variant {
@@ -346,6 +425,24 @@ private class VariantItemNode extends ItemNode instanceof Variant {
346425 }
347426
348427 override Visibility getVisibility ( ) { result = super .getEnum ( ) .getVisibility ( ) }
428+
429+ bindingset [ c]
430+ private string getCanonicalPathPart ( Crate c , int i ) {
431+ i = 0 and
432+ result = this .getCanonicalPathPrefix ( c )
433+ or
434+ i = 1 and
435+ result = "::"
436+ or
437+ i = 2 and
438+ result = this .getName ( )
439+ }
440+
441+ language [ monotonicAggregates]
442+ override string getCanonicalPath ( Crate c ) {
443+ c = this .getACanonicalPathCrate ( ) and
444+ result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
445+ }
349446}
350447
351448class FunctionItemNode extends AssocItemNode instanceof Function {
@@ -467,6 +564,47 @@ class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
467564 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
468565
469566 override Visibility getVisibility ( ) { result = Impl .super .getVisibility ( ) }
567+
568+ pragma [ nomagic]
569+ private string getCanonicalPathTraitPart ( Crate c ) {
570+ exists ( Crate c2 | result = this .resolveTraitTy ( ) .getCanonicalPath ( c2 ) |
571+ c = c2
572+ or
573+ c2 = c .getADependency ( )
574+ )
575+ }
576+
577+ bindingset [ c]
578+ private string getCanonicalPathPart ( Crate c , int i ) {
579+ i = 0 and
580+ result = "<"
581+ or
582+ i = 1 and
583+ result = this .resolveSelfTy ( ) .getCanonicalPath ( c )
584+ or
585+ if exists ( this .getTraitPath ( ) )
586+ then
587+ i = 2 and
588+ result = " as "
589+ or
590+ i = 3 and
591+ result = this .getCanonicalPathTraitPart ( c )
592+ or
593+ i = 4 and
594+ result = ">"
595+ else (
596+ i = 2 and
597+ result = ">"
598+ )
599+ }
600+
601+ language [ monotonicAggregates]
602+ override string getCanonicalPath ( Crate c ) {
603+ c = this .getACanonicalPathCrate ( ) and
604+ exists ( int m | if exists ( this .getTraitPath ( ) ) then m = 4 else m = 2 |
605+ result = strictconcat ( int i | i in [ 0 .. m ] | this .getCanonicalPathPart ( c , i ) order by i )
606+ )
607+ }
470608}
471609
472610private class MacroCallItemNode extends AssocItemNode instanceof MacroCall {
@@ -479,6 +617,8 @@ private class MacroCallItemNode extends AssocItemNode instanceof MacroCall {
479617 override TypeParam getTypeParam ( int i ) { none ( ) }
480618
481619 override Visibility getVisibility ( ) { none ( ) }
620+
621+ override string getCanonicalPath ( Crate c ) { none ( ) }
482622}
483623
484624private class ModuleItemNode extends ModuleLikeNode instanceof Module {
@@ -489,6 +629,44 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
489629 override Visibility getVisibility ( ) { result = Module .super .getVisibility ( ) }
490630
491631 override TypeParam getTypeParam ( int i ) { none ( ) }
632+
633+ bindingset [ c]
634+ private string getCanonicalPathPart ( Crate c , int i ) {
635+ i = 0 and
636+ result = this .getCanonicalPathPrefix ( c )
637+ or
638+ i = 1 and
639+ result = "::"
640+ or
641+ i = 2 and
642+ result = this .getName ( )
643+ }
644+
645+ language [ monotonicAggregates]
646+ override string getCanonicalPath ( Crate c ) {
647+ c = this .getACanonicalPathCrate ( ) and
648+ result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
649+ }
650+
651+ pragma [ nomagic]
652+ private ItemNode getACanonicalPathChild ( ) {
653+ exists ( SourceFile f |
654+ fileImport ( this , f ) and
655+ sourceFileEdge ( f , _, result )
656+ )
657+ or
658+ this = result .getImmediateParent ( )
659+ or
660+ exists ( ItemNode mid |
661+ mid = this .getACanonicalPathChild ( ) and
662+ mid .( MacroCallItemNode ) = result .getImmediateParent ( )
663+ )
664+ }
665+
666+ override string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
667+ child = this .getACanonicalPathChild ( ) and
668+ result = this .getCanonicalPath ( c )
669+ }
492670}
493671
494672private class StructItemNode extends ItemNode instanceof Struct {
@@ -504,6 +682,24 @@ private class StructItemNode extends ItemNode instanceof Struct {
504682 override Visibility getVisibility ( ) { result = Struct .super .getVisibility ( ) }
505683
506684 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
685+
686+ bindingset [ c]
687+ private string getCanonicalPathPart ( Crate c , int i ) {
688+ i = 0 and
689+ result = this .getCanonicalPathPrefix ( c )
690+ or
691+ i = 1 and
692+ result = "::"
693+ or
694+ i = 2 and
695+ result = this .getName ( )
696+ }
697+
698+ language [ monotonicAggregates]
699+ override string getCanonicalPath ( Crate c ) {
700+ c = this .getACanonicalPathCrate ( ) and
701+ result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
702+ }
507703}
508704
509705class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
@@ -524,6 +720,36 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
524720 override Visibility getVisibility ( ) { result = Trait .super .getVisibility ( ) }
525721
526722 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
723+
724+ bindingset [ c]
725+ private string getCanonicalPathPart ( Crate c , int i ) {
726+ i = 0 and
727+ result = "<_ as "
728+ or
729+ i = 1 and
730+ result = this .getCanonicalPathPrefix ( c )
731+ or
732+ i = 2 and
733+ result = "::"
734+ or
735+ i = 3 and
736+ result = this .getName ( )
737+ or
738+ i = 4 and
739+ result = ">"
740+ }
741+
742+ language [ monotonicAggregates]
743+ override string getCanonicalPath ( Crate c ) {
744+ c = this .getACanonicalPathCrate ( ) and
745+ result = strictconcat ( int i | i in [ 1 .. 3 ] | this .getCanonicalPathPart ( c , i ) order by i )
746+ }
747+
748+ language [ monotonicAggregates]
749+ override string getCanonicalPathPrefixFor ( Crate c , ItemNode child ) {
750+ result = strictconcat ( int i | i in [ 0 .. 4 ] | this .getCanonicalPathPart ( c , i ) order by i ) and
751+ child = this .getAnAssocItem ( )
752+ }
527753}
528754
529755class TypeAliasItemNode extends AssocItemNode instanceof TypeAlias {
@@ -546,6 +772,24 @@ private class UnionItemNode extends ItemNode instanceof Union {
546772 override Visibility getVisibility ( ) { result = Union .super .getVisibility ( ) }
547773
548774 override TypeParam getTypeParam ( int i ) { result = super .getGenericParamList ( ) .getTypeParam ( i ) }
775+
776+ bindingset [ c]
777+ private string getCanonicalPathPart ( Crate c , int i ) {
778+ i = 0 and
779+ result = this .getCanonicalPathPrefix ( c )
780+ or
781+ i = 1 and
782+ result = "::"
783+ or
784+ i = 2 and
785+ result = this .getName ( )
786+ }
787+
788+ language [ monotonicAggregates]
789+ override string getCanonicalPath ( Crate c ) {
790+ c = this .getACanonicalPathCrate ( ) and
791+ result = strictconcat ( int i | i in [ 0 .. 2 ] | this .getCanonicalPathPart ( c , i ) order by i )
792+ }
549793}
550794
551795private class UseItemNode extends ItemNode instanceof Use {
@@ -556,6 +800,8 @@ private class UseItemNode extends ItemNode instanceof Use {
556800 override Visibility getVisibility ( ) { result = Use .super .getVisibility ( ) }
557801
558802 override TypeParam getTypeParam ( int i ) { none ( ) }
803+
804+ override string getCanonicalPath ( Crate c ) { none ( ) }
559805}
560806
561807private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
@@ -566,6 +812,8 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
566812 override Visibility getVisibility ( ) { none ( ) }
567813
568814 override TypeParam getTypeParam ( int i ) { none ( ) }
815+
816+ override string getCanonicalPath ( Crate c ) { none ( ) }
569817}
570818
571819private class TypeParamItemNode extends ItemNode instanceof TypeParam {
@@ -622,6 +870,8 @@ private class TypeParamItemNode extends ItemNode instanceof TypeParam {
622870 override TypeParam getTypeParam ( int i ) { none ( ) }
623871
624872 override Location getLocation ( ) { result = TypeParam .super .getName ( ) .getLocation ( ) }
873+
874+ override string getCanonicalPath ( Crate c ) { none ( ) }
625875}
626876
627877/** Holds if `item` has the name `name` and is a top-level item inside `f`. */
0 commit comments