From 4526afc29fe7cc04779909dcb804227824a753fa Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 19 Jan 2026 15:25:25 +0100 Subject: [PATCH] Rust: Paths to associated types resolve to the associated type if implementation is unclear --- .../codeql/rust/internal/PathResolution.qll | 162 ++++++++++-------- .../library-tests/path-resolution/main.rs | 8 +- .../path-resolution/path-resolution.expected | 60 +++---- .../PathResolutionConsistency.expected | 5 - .../TypeInferenceConsistency.expected | 3 - .../type-inference/associated_types.rs | 8 +- .../type-inference/type-inference.expected | 20 --- 7 files changed, 123 insertions(+), 143 deletions(-) delete mode 100644 rust/ql/test/library-tests/type-inference/CONSISTENCY/TypeInferenceConsistency.expected diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index f30625807b4..00582e584f8 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -110,18 +110,15 @@ pragma[nomagic] private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind kind) { item = result.getImmediateParent() and name = result.getName() and + // Associated types in `impl` and `trait` blocks are handled elsewhere + not (item instanceof ImplOrTraitItemNode and result instanceof AssocItem) and // type parameters are only available inside the declaring item if result instanceof TypeParam then kind.isInternal() else - // associated items must always be qualified, also within the declaring - // item (using `Self`) - if item instanceof ImplOrTraitItemNode and result instanceof AssocItem - then kind.isExternal() - else - if result.isPublic() - then kind.isBoth() - else kind.isInternal() + if result.isPublic() + then kind.isBoth() + else kind.isInternal() } private module UseOption = Option; @@ -327,30 +324,24 @@ abstract class ItemNode extends Locatable { ) ) or - // a trait has access to the associated items of its supertraits - this = - any(TraitItemNodeImpl trait | - result = trait.resolveABoundCand().getASuccessor(name, kind, useOpt) and - kind.isExternalOrBoth() and - result instanceof AssocItemNode and - not trait.hasAssocItem(name) - ) + exists(TraitItemNodeImpl trait | this = trait | + result = trait.getAssocItem(name) + or + // a trait has access to the associated items of its supertraits + not trait.hasAssocItem(name) and + result = trait.resolveABoundCand().getASuccessor(name).(AssocItemNode) + ) and + kind.isExternal() and + useOpt.isNone() or // items made available by an implementation where `this` is the implementing type - typeImplEdge(this, _, name, kind, result, useOpt) + typeImplEdge(this, _, name, result) and + kind.isExternal() and + useOpt.isNone() or - // trait items with default implementations made available in an implementation - exists(ImplItemNodeImpl impl, TraitItemNode trait | - this = impl and - trait = impl.resolveTraitTyCand() and - result = trait.getASuccessor(name, kind, useOpt) and - // do not inherit default implementations from super traits; those are inherited by - // their `impl` blocks - result = trait.getAssocItem(name) and - result.(AssocItemNode).hasImplementation() and - kind.isExternalOrBoth() and - not impl.hasAssocItem(name) - ) + implEdge(this, name, result) and + kind.isExternal() and + useOpt.isNone() or // type parameters have access to the associated items of its bounds result = @@ -413,14 +404,8 @@ abstract class ItemNode extends Locatable { this instanceof SourceFile and builtin(name, result) or - exists(ImplOrTraitItemNode i | - name = "Self" and - this = i.getAnItemInSelfScope() - | - result = i.(Trait) - or - result = i.(ImplItemNodeImpl).resolveSelfTyCand() - ) + name = "Self" and + this = result.(ImplOrTraitItemNode).getAnItemInSelfScope() or name = "crate" and this = result.(CrateItemNode).getASourceFile() @@ -755,7 +740,7 @@ abstract class ImplOrTraitItemNode extends ItemNode { } /** Gets an associated item belonging to this trait or `impl` block. */ - abstract AssocItemNode getAnAssocItem(); + AssocItemNode getAnAssocItem() { result = this.getADescendant() } /** Gets the associated item named `name` belonging to this trait or `impl` block. */ pragma[nomagic] @@ -807,12 +792,12 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl { TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) } - override AssocItemNode getAnAssocItem() { result = this.getADescendant() } - override string getName() { result = "(impl)" } override Namespace getNamespace() { - result.isType() // can be referenced with `Self` + // `impl` blocks are referred to using `Self` paths which can appear both as + // types and as values (when the implementing type is a tuple-like struct). + result.isType() or result.isValue() } override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) } @@ -985,6 +970,18 @@ private class ImplItemNodeImpl extends ImplItemNode { } TraitItemNodeImpl resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) } + + /** + * Gets the associated item named `name` in this impl block or the default + * inherited from the trait being implemented. + */ + AssocItemNode getAssocItemOrDefault(string name) { + result = this.getAssocItem(name) + or + not this.hasAssocItem(name) and + result = this.resolveTraitTyCand().getAssocItem(name) and + result.hasImplementation() + } } private class StructItemNode extends TypeItemTypeItemNode, ParameterizableItemNode instanceof Struct @@ -1020,8 +1017,6 @@ final class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof T ItemNode resolveABound() { result = this.resolveBound(_) } - override AssocItemNode getAnAssocItem() { result = this.getADescendant() } - override string getName() { result = Trait.super.getName().getText() } override Namespace getNamespace() { result.isType() } @@ -1790,7 +1785,15 @@ private module DollarCrateResolution { pragma[nomagic] private ItemNode resolvePathCand0(PathExt path, Namespace ns) { - result = unqualifiedPathLookup(path, ns, _) + exists(ItemNode res | + res = unqualifiedPathLookup(path, ns, _) and + if + not any(PathExt parent).getQualifier() = path and + isUnqualifiedSelfPath(path) and + res instanceof ImplItemNode + then result = res.(ImplItemNodeImpl).resolveSelfTyCand() + else result = res + ) or DollarCrateResolution::resolveDollarCrate(path, result) and ns = result.getNamespace() @@ -1852,35 +1855,12 @@ private predicate checkQualifiedVisibility( not i instanceof TypeParam } -pragma[nomagic] -private predicate isImplSelfQualifiedPath( - ImplItemNode impl, PathExt qualifier, PathExt path, string name -) { - qualifier = impl.getASelfPath() and - qualifier = path.getQualifier() and - name = path.getText() -} - -private ItemNode resolveImplSelfQualified(PathExt qualifier, PathExt path, Namespace ns) { - exists(ImplItemNode impl, string name | - isImplSelfQualifiedPath(impl, qualifier, path, name) and - result = impl.getAssocItem(name) and - ns = result.getNamespace() - ) -} - /** * Gets the item that `path` resolves to in `ns` when `qualifier` is the * qualifier of `path` and `qualifier` resolves to `q`, if any. */ pragma[nomagic] private ItemNode resolvePathCandQualified(PathExt qualifier, ItemNode q, PathExt path, Namespace ns) { - // Special case for `Self::Assoc`; this always refers to the associated - // item in the enclosing `impl` block, if available. - q = resolvePathCandQualifier(qualifier, path, _) and - result = resolveImplSelfQualified(qualifier, path, ns) - or - not exists(resolveImplSelfQualified(qualifier, path, ns)) and exists(string name, SuccessorKind kind, UseOption useOpt | q = resolvePathCandQualifier(qualifier, path, name) and result = getASuccessor(q, name, ns, kind, useOpt) and @@ -1940,6 +1920,37 @@ private predicate macroExportEdge(CrateItemNode crate, string name, MacroItemNod name = macro.getName() } +/** + * Holds if a `Self` path inside `impl` might refer to a function named `name` + * from another impl block. + */ +pragma[nomagic] +private predicate relevantSelfFunctionName(ImplItemNodeImpl impl, string name) { + any(Path path | path.getQualifier() = impl.getASelfPath()).getText() = name and + not impl.hasAssocItem(name) +} + +/** + * Holds if `impl` has a `node` available externally at `name`. + * + * Since `Self` in an impl block resolves to the impl block, this corresponds to + * the items that should be available on `Self` within the `impl` block. + */ +private predicate implEdge(ImplItemNodeImpl impl, string name, ItemNode node) { + node = impl.getAssocItemOrDefault(name) + or + // Associated types from the implemented trait are available on `Self`. + not impl.hasAssocItem(name) and + node = impl.resolveTraitTyCand().getASuccessor(name).(TypeAliasItemNode) + or + // Items available on the implementing type are available on `Self`. We only + // add these edges when they are relevant. If a type has `n` impl blocks with + // `m` functions each, we would otherwise end up always constructing something + // proportional to `O(n * m)`. + relevantSelfFunctionName(impl, name) and + node = impl.resolveSelfTyCand().getASuccessor(name) +} + /** * Holds if item `i` contains a `mod` or `extern crate` definition that * makes the macro `macro` named `name` available using a `#[macro_use]` @@ -2009,9 +2020,10 @@ private ItemNode resolvePathCand(PathExt path) { /** Get a trait that should be visible when `path` resolves to `node`, if any. */ private Trait getResolvePathTraitUsed(PathExt path, AssocItemNode node) { - exists(TypeItemNode type, ImplItemNodeImpl impl | - node = resolvePathCandQualified(_, type, path, _) and - typeImplEdge(type, impl, _, _, node, _) and + exists(TypeItemNode type, ItemNode qual, ImplItemNodeImpl impl | + node = resolvePathCandQualified(_, qual, path, _) and + type = [qual, qual.(ImplItemNodeImpl).resolveSelfTyCand()] and + typeImplEdge(type, impl, _, node) and result = impl.resolveTraitTyCand() ) } @@ -2182,12 +2194,14 @@ private predicate externCrateEdge( * makes `assoc` available as `name` at `kind`. */ private predicate typeImplEdge( - TypeItemNode typeItem, ImplItemNodeImpl impl, string name, SuccessorKind kind, - AssocItemNode assoc, UseOption useOpt + TypeItemNode typeItem, ImplItemNodeImpl impl, string name, AssocItemNode assoc ) { + assoc = impl.getAssocItemOrDefault(name) and typeItem = impl.resolveSelfTyCand() and - assoc = impl.getASuccessor(name, kind, useOpt) and - kind.isExternalOrBoth() + // Functions in `impl` blocks are made available on the implementing type + // (e.g., `S::fun` is valid) but associated types are not (e.g., `S::Output` + // is invalid). + (assoc instanceof FunctionItemNode or assoc instanceof ConstItemNode) } pragma[nomagic] diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 3397d3a7000..9336666b477 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -729,7 +729,7 @@ mod m23 { fn f(&self) { println!("m23::>::f"); // $ item=println } // I5 - } + } // implTrait1forS #[rustfmt::skip] pub fn f() { @@ -906,14 +906,14 @@ mod associated_types_subtrait { #[rustfmt::skip] impl Sub for S { // $ item=Sub item=S item=i32 - fn f() -> Self::Out { // $ MISSING: item=SuperAssoc SPURIOUS: item=S::Out item=S::Out item=S::Out + fn f() -> Self::Out { // $ item=SuperAssoc 'a' } } #[rustfmt::skip] impl Sub for S { // $ item=Sub item=S item=bool - fn f() -> Self::Out { // $ MISSING: item=SuperAssoc SPURIOUS: item=S::Out item=S::Out item=S::Out + fn f() -> Self::Out { // $ item=SuperAssoc 1 } } @@ -936,7 +936,7 @@ mod associated_types_subtrait { #[rustfmt::skip] impl SubAlt for S { // $ item=SubAlt item=S item=A - fn f(self) -> Self::Out { // $ MISSING: item=SuperAltAssoc SPURIOUS: item=S::Out item=S::Out item=S::Out + fn f(self) -> Self::Out { // $ item=SuperAltAssoc self.0 } } diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index 00d38d6e70d..fd1e5fd8503 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -135,7 +135,7 @@ resolvePath | main.rs:169:22:169:29 | MyStruct | main.rs:162:5:162:22 | struct MyStruct | | main.rs:171:13:171:19 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:172:13:172:13 | f | main.rs:164:5:166:5 | fn f | -| main.rs:173:13:173:16 | Self | main.rs:162:5:162:22 | struct MyStruct | +| main.rs:173:13:173:16 | Self | main.rs:168:5:179:5 | impl MyTrait for MyStruct { ... } | | main.rs:173:13:173:19 | ...::g | main.rs:176:9:178:9 | fn g | | main.rs:177:13:177:19 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:182:10:182:17 | MyStruct | main.rs:162:5:162:22 | struct MyStruct | @@ -199,7 +199,7 @@ resolvePath | main.rs:341:10:341:15 | Trait1 | main.rs:307:5:311:5 | trait Trait1 | | main.rs:342:11:342:11 | S | main.rs:338:5:338:13 | struct S | | main.rs:344:13:344:19 | println | {EXTERNAL LOCATION} | MacroRules | -| main.rs:345:13:345:16 | Self | main.rs:338:5:338:13 | struct S | +| main.rs:345:13:345:16 | Self | main.rs:340:5:352:5 | impl Trait1 for S { ... } | | main.rs:345:13:345:19 | ...::g | main.rs:349:9:351:9 | fn g | | main.rs:350:13:350:19 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:355:10:355:15 | Trait2 | main.rs:313:5:321:5 | trait Trait2 | @@ -232,11 +232,11 @@ resolvePath | main.rs:418:11:418:11 | S | main.rs:412:5:412:13 | struct S | | main.rs:419:24:419:24 | S | main.rs:412:5:412:13 | struct S | | main.rs:420:13:420:19 | println | {EXTERNAL LOCATION} | MacroRules | -| main.rs:421:13:421:16 | Self | main.rs:412:5:412:13 | struct S | +| main.rs:421:13:421:16 | Self | main.rs:414:5:432:5 | impl Trait1::<...> for S { ... } | | main.rs:421:13:421:19 | ...::g | main.rs:425:9:428:9 | fn g | | main.rs:425:24:425:24 | S | main.rs:412:5:412:13 | struct S | | main.rs:426:13:426:19 | println | {EXTERNAL LOCATION} | MacroRules | -| main.rs:427:13:427:16 | Self | main.rs:412:5:412:13 | struct S | +| main.rs:427:13:427:16 | Self | main.rs:414:5:432:5 | impl Trait1::<...> for S { ... } | | main.rs:427:13:427:19 | ...::c | main.rs:430:9:431:9 | Const | | main.rs:430:18:430:18 | S | main.rs:412:5:412:13 | struct S | | main.rs:430:22:430:22 | S | main.rs:412:5:412:13 | struct S | @@ -244,10 +244,10 @@ resolvePath | main.rs:436:7:436:7 | S | main.rs:412:5:412:13 | struct S | | main.rs:438:11:438:11 | S | main.rs:412:5:412:13 | struct S | | main.rs:439:24:439:24 | S | main.rs:412:5:412:13 | struct S | -| main.rs:440:13:440:16 | Self | main.rs:412:5:412:13 | struct S | +| main.rs:440:13:440:16 | Self | main.rs:434:5:444:5 | impl Trait2::<...> for S { ... } | | main.rs:440:13:440:19 | ...::g | main.rs:425:9:428:9 | fn g | | main.rs:441:13:441:19 | println | {EXTERNAL LOCATION} | MacroRules | -| main.rs:442:13:442:16 | Self | main.rs:412:5:412:13 | struct S | +| main.rs:442:13:442:16 | Self | main.rs:434:5:444:5 | impl Trait2::<...> for S { ... } | | main.rs:442:13:442:19 | ...::c | main.rs:430:9:431:9 | Const | | main.rs:448:9:448:15 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:449:17:449:17 | S | main.rs:412:5:412:13 | struct S | @@ -269,42 +269,42 @@ resolvePath | main.rs:487:10:487:15 | Trait3 | main.rs:472:5:476:5 | trait Trait3 | | main.rs:487:21:487:22 | S2 | main.rs:484:5:484:14 | struct S2 | | main.rs:488:26:488:28 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:492:20:492:23 | Self | main.rs:484:5:484:14 | struct S2 | +| main.rs:492:20:492:23 | Self | main.rs:486:5:494:5 | impl Trait3 for S2 { ... } | | main.rs:492:20:492:34 | ...::AssocType | main.rs:487:26:489:9 | type AssocType | | main.rs:497:10:497:15 | Trait4 | main.rs:478:5:482:5 | trait Trait4 | | main.rs:497:21:497:22 | S2 | main.rs:484:5:484:14 | struct S2 | | main.rs:498:26:498:29 | bool | {EXTERNAL LOCATION} | struct bool | -| main.rs:502:13:502:16 | Self | main.rs:484:5:484:14 | struct S2 | +| main.rs:502:13:502:16 | Self | main.rs:496:5:506:5 | impl Trait4 for S2 { ... } | | main.rs:502:13:502:19 | ...::f | main.rs:489:11:493:9 | fn f | | main.rs:503:13:503:14 | S2 | main.rs:484:5:484:14 | struct S2 | | main.rs:503:13:503:17 | ...::f | main.rs:489:11:493:9 | fn f | -| main.rs:504:20:504:23 | Self | main.rs:484:5:484:14 | struct S2 | +| main.rs:504:20:504:23 | Self | main.rs:496:5:506:5 | impl Trait4 for S2 { ... } | | main.rs:504:20:504:34 | ...::AssocType | main.rs:497:26:499:9 | type AssocType | | main.rs:511:23:511:26 | Self | main.rs:508:5:512:5 | trait Trait5 | | main.rs:511:23:511:33 | ...::Assoc | main.rs:509:9:509:19 | type Assoc | | main.rs:515:10:515:15 | Trait5 | main.rs:508:5:512:5 | trait Trait5 | | main.rs:515:21:515:21 | S | main.rs:412:5:412:13 | struct S | | main.rs:516:22:516:24 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:520:16:520:19 | Self | main.rs:412:5:412:13 | struct S | +| main.rs:520:16:520:19 | Self | main.rs:514:5:523:5 | impl Trait5 for S { ... } | | main.rs:520:16:520:26 | ...::Assoc | main.rs:515:25:517:9 | type Assoc | -| main.rs:521:13:521:16 | Self | main.rs:412:5:412:13 | struct S | +| main.rs:521:13:521:16 | Self | main.rs:514:5:523:5 | impl Trait5 for S { ... } | | main.rs:521:13:521:23 | ...::Assoc | main.rs:519:9:522:9 | fn Assoc | | main.rs:525:19:525:20 | T3 | main.rs:525:15:525:16 | T3 | | main.rs:528:10:528:15 | Trait5 | main.rs:508:5:512:5 | trait Trait5 | | main.rs:528:21:528:27 | S3::<...> | main.rs:525:5:525:22 | struct S3 | | main.rs:528:24:528:26 | i32 | {EXTERNAL LOCATION} | struct i32 | | main.rs:529:22:529:24 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:533:16:533:19 | Self | main.rs:525:5:525:22 | struct S3 | +| main.rs:533:16:533:19 | Self | main.rs:527:5:536:5 | impl Trait5 for S3::<...> { ... } | | main.rs:533:16:533:26 | ...::Assoc | main.rs:528:31:530:9 | type Assoc | -| main.rs:534:13:534:16 | Self | main.rs:525:5:525:22 | struct S3 | +| main.rs:534:13:534:16 | Self | main.rs:527:5:536:5 | impl Trait5 for S3::<...> { ... } | | main.rs:534:13:534:23 | ...::Assoc | main.rs:532:9:535:9 | fn Assoc | | main.rs:539:10:539:15 | Trait5 | main.rs:508:5:512:5 | trait Trait5 | | main.rs:539:21:539:28 | S3::<...> | main.rs:525:5:525:22 | struct S3 | | main.rs:539:24:539:27 | bool | {EXTERNAL LOCATION} | struct bool | | main.rs:540:22:540:25 | bool | {EXTERNAL LOCATION} | struct bool | -| main.rs:544:16:544:19 | Self | main.rs:525:5:525:22 | struct S3 | +| main.rs:544:16:544:19 | Self | main.rs:538:5:547:5 | impl Trait5 for S3::<...> { ... } | | main.rs:544:16:544:26 | ...::Assoc | main.rs:539:32:541:9 | type Assoc | -| main.rs:545:14:545:17 | Self | main.rs:525:5:525:22 | struct S3 | +| main.rs:545:14:545:17 | Self | main.rs:538:5:547:5 | impl Trait5 for S3::<...> { ... } | | main.rs:545:14:545:24 | ...::Assoc | main.rs:543:9:546:9 | fn Assoc | | main.rs:550:10:550:16 | S3::<...> | main.rs:525:5:525:22 | struct S3 | | main.rs:550:13:550:15 | i32 | {EXTERNAL LOCATION} | struct i32 | @@ -338,7 +338,7 @@ resolvePath | main.rs:608:13:608:13 | X | main.rs:586:9:586:21 | struct X | | main.rs:608:13:608:23 | ...::a_method | main.rs:588:26:591:13 | fn a_method | | main.rs:611:18:611:18 | X | main.rs:586:9:586:21 | struct X | -| main.rs:613:21:613:24 | Self | main.rs:586:9:586:21 | struct X | +| main.rs:613:21:613:24 | Self | main.rs:610:13:615:13 | impl X { ... } | | main.rs:613:21:613:34 | ...::a_method | main.rs:588:26:591:13 | fn a_method | | main.rs:619:17:619:17 | m | main.rs:577:5:599:5 | mod m | | main.rs:619:17:619:22 | ...::Bar | main.rs:582:9:584:9 | trait Bar | @@ -441,17 +441,17 @@ resolvePath | main.rs:852:13:852:17 | Error | main.rs:848:13:848:17 | Error | | main.rs:855:22:858:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result | | main.rs:856:13:856:17 | Input | main.rs:847:13:847:17 | Input | -| main.rs:857:13:857:16 | Self | main.rs:840:5:843:5 | struct MyImpl | +| main.rs:857:13:857:16 | Self | main.rs:845:5:877:5 | impl Reduce for MyImpl::<...> { ... } | | main.rs:857:13:857:23 | ...::Error | main.rs:859:11:863:9 | type Error | | main.rs:860:22:862:9 | Option::<...> | {EXTERNAL LOCATION} | enum Option | | main.rs:861:11:861:15 | Error | main.rs:848:13:848:17 | Error | | main.rs:865:13:865:17 | Input | main.rs:847:13:847:17 | Input | -| main.rs:870:19:870:22 | Self | main.rs:840:5:843:5 | struct MyImpl | +| main.rs:870:19:870:22 | Self | main.rs:845:5:877:5 | impl Reduce for MyImpl::<...> { ... } | | main.rs:870:19:870:29 | ...::Input | main.rs:855:9:859:9 | type Input | | main.rs:871:14:874:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result | -| main.rs:872:13:872:16 | Self | main.rs:840:5:843:5 | struct MyImpl | +| main.rs:872:13:872:16 | Self | main.rs:845:5:877:5 | impl Reduce for MyImpl::<...> { ... } | | main.rs:872:13:872:24 | ...::Output | main.rs:863:11:866:9 | type Output | -| main.rs:873:13:873:16 | Self | main.rs:840:5:843:5 | struct MyImpl | +| main.rs:873:13:873:16 | Self | main.rs:845:5:877:5 | impl Reduce for MyImpl::<...> { ... } | | main.rs:873:13:873:23 | ...::Error | main.rs:859:11:863:9 | type Error | | main.rs:885:16:885:20 | Super | main.rs:881:5:883:5 | trait Super | | main.rs:887:19:887:22 | Self | main.rs:885:5:889:5 | trait Sub | @@ -468,17 +468,13 @@ resolvePath | main.rs:908:10:908:12 | Sub | main.rs:885:5:889:5 | trait Sub | | main.rs:908:18:908:23 | S::<...> | main.rs:891:5:893:6 | struct S | | main.rs:908:20:908:22 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:909:19:909:22 | Self | main.rs:891:5:893:6 | struct S | -| main.rs:909:19:909:27 | ...::Out | main.rs:896:29:898:9 | type Out | -| main.rs:909:19:909:27 | ...::Out | main.rs:902:30:904:9 | type Out | -| main.rs:909:19:909:27 | ...::Out | main.rs:932:33:934:9 | type Out | +| main.rs:909:19:909:22 | Self | main.rs:907:5:912:5 | impl Sub for S::<...> { ... } | +| main.rs:909:19:909:27 | ...::Out | main.rs:882:9:882:17 | type Out | | main.rs:915:10:915:12 | Sub | main.rs:885:5:889:5 | trait Sub | | main.rs:915:18:915:24 | S::<...> | main.rs:891:5:893:6 | struct S | | main.rs:915:20:915:23 | bool | {EXTERNAL LOCATION} | struct bool | -| main.rs:916:19:916:22 | Self | main.rs:891:5:893:6 | struct S | -| main.rs:916:19:916:27 | ...::Out | main.rs:896:29:898:9 | type Out | -| main.rs:916:19:916:27 | ...::Out | main.rs:902:30:904:9 | type Out | -| main.rs:916:19:916:27 | ...::Out | main.rs:932:33:934:9 | type Out | +| main.rs:916:19:916:22 | Self | main.rs:914:5:919:5 | impl Sub for S::<...> { ... } | +| main.rs:916:19:916:27 | ...::Out | main.rs:882:9:882:17 | type Out | | main.rs:925:19:925:26 | SuperAlt | main.rs:921:5:923:5 | trait SuperAlt | | main.rs:927:23:927:26 | Self | main.rs:925:5:929:5 | trait SubAlt | | main.rs:927:23:927:31 | ...::Out | main.rs:922:9:922:17 | type Out | @@ -489,10 +485,8 @@ resolvePath | main.rs:938:13:938:18 | SubAlt | main.rs:925:5:929:5 | trait SubAlt | | main.rs:938:24:938:27 | S::<...> | main.rs:891:5:893:6 | struct S | | main.rs:938:26:938:26 | A | main.rs:938:10:938:10 | A | -| main.rs:939:23:939:26 | Self | main.rs:891:5:893:6 | struct S | -| main.rs:939:23:939:31 | ...::Out | main.rs:896:29:898:9 | type Out | -| main.rs:939:23:939:31 | ...::Out | main.rs:902:30:904:9 | type Out | -| main.rs:939:23:939:31 | ...::Out | main.rs:932:33:934:9 | type Out | +| main.rs:939:23:939:26 | Self | main.rs:937:5:942:5 | impl SubAlt for S::<...> { ... } | +| main.rs:939:23:939:31 | ...::Out | main.rs:922:9:922:17 | type Out | | main.rs:945:5:945:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | | main.rs:945:11:945:14 | self | {EXTERNAL LOCATION} | Crate(std@0.0.0) | | main.rs:947:15:947:17 | ztd | {EXTERNAL LOCATION} | Crate(std@0.0.0) | @@ -536,7 +530,7 @@ resolvePath | main.rs:1041:13:1041:15 | i32 | {EXTERNAL LOCATION} | struct i32 | | main.rs:1046:10:1046:15 | MyEnum | main.rs:1039:5:1043:5 | enum MyEnum | | main.rs:1047:25:1047:27 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:1049:17:1049:20 | Self | main.rs:1039:5:1043:5 | enum MyEnum | +| main.rs:1049:17:1049:20 | Self | main.rs:1045:5:1056:5 | impl MyEnum { ... } | | main.rs:1049:17:1049:23 | ...::A | main.rs:1040:9:1042:9 | A | | main.rs:1060:5:1060:6 | my | main.rs:1:1:1:7 | mod my | | main.rs:1060:5:1060:14 | ...::nested | my.rs:1:1:1:15 | mod nested | diff --git a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected index 7b751c9ea8b..97dfe4bc278 100644 --- a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected @@ -1,7 +1,2 @@ multipleResolvedTargets -| associated_types.rs:393:13:393:30 | ...::default(...) | -| associated_types.rs:400:13:400:30 | ...::default(...) | | main.rs:2871:13:2871:17 | x.f() | -multiplePathResolutions -| associated_types.rs:391:34:391:45 | ...::Output | -| associated_types.rs:399:34:399:45 | ...::Output | diff --git a/rust/ql/test/library-tests/type-inference/CONSISTENCY/TypeInferenceConsistency.expected b/rust/ql/test/library-tests/type-inference/CONSISTENCY/TypeInferenceConsistency.expected deleted file mode 100644 index f2551bcad6c..00000000000 --- a/rust/ql/test/library-tests/type-inference/CONSISTENCY/TypeInferenceConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -nonUniqueCertainType -| associated_types.rs:391:47:394:9 | { ... } | | -| associated_types.rs:399:47:401:9 | { ... } | | diff --git a/rust/ql/test/library-tests/type-inference/associated_types.rs b/rust/ql/test/library-tests/type-inference/associated_types.rs index b517b63403f..332b1d55417 100644 --- a/rust/ql/test/library-tests/type-inference/associated_types.rs +++ b/rust/ql/test/library-tests/type-inference/associated_types.rs @@ -390,14 +390,14 @@ mod associated_type_in_supertrait { // Odd::get_content fn get_content(&self) -> Self::Output { // let _x = Self::get(self); - Default::default() // $ target=default + Default::default() // $ MISSING: target=default } } impl Subtrait for Odd { // Odd::get_content fn get_content(&self) -> Self::Output { - Default::default() // $ target=default + Default::default() // $ MISSING: target=default } } @@ -417,8 +417,8 @@ mod associated_type_in_supertrait { let item2 = MyType(true); let _content2 = get_content(&item2); // $ target=get_content MISSING: type=_content2:bool - let _content3 = Odd(42i32).get_content(); // $ target=Odd::get_content type=_content3:bool SPURIOUS: type=_content3:char - let _content4 = Odd(true).get_content(); // $ target=Odd::get_content type=_content4:char SPURIOUS: type=_content4:bool + let _content3 = Odd(42i32).get_content(); // $ target=Odd::get_content MISSING: type=_content3:bool + let _content4 = Odd(true).get_content(); // $ target=Odd::get_content MISSING: type=_content4:char } } diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 14d6ae3115e..80ee3a2b1d5 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -192,13 +192,9 @@ inferCertainType | associated_types.rs:391:24:391:28 | SelfParam | | {EXTERNAL LOCATION} | & | | associated_types.rs:391:24:391:28 | SelfParam | TRef | associated_types.rs:67:1:67:23 | Odd | | associated_types.rs:391:24:391:28 | SelfParam | TRef.OddT | {EXTERNAL LOCATION} | i32 | -| associated_types.rs:391:47:394:9 | { ... } | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:391:47:394:9 | { ... } | | {EXTERNAL LOCATION} | char | | associated_types.rs:399:24:399:28 | SelfParam | | {EXTERNAL LOCATION} | & | | associated_types.rs:399:24:399:28 | SelfParam | TRef | associated_types.rs:67:1:67:23 | Odd | | associated_types.rs:399:24:399:28 | SelfParam | TRef.OddT | {EXTERNAL LOCATION} | bool | -| associated_types.rs:399:47:401:9 | { ... } | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:399:47:401:9 | { ... } | | {EXTERNAL LOCATION} | char | | associated_types.rs:404:33:404:36 | item | | {EXTERNAL LOCATION} | & | | associated_types.rs:404:33:404:36 | item | TRef | associated_types.rs:404:20:404:30 | T | | associated_types.rs:405:9:405:12 | item | | {EXTERNAL LOCATION} | & | @@ -5020,17 +5016,9 @@ inferType | associated_types.rs:391:24:391:28 | SelfParam | | {EXTERNAL LOCATION} | & | | associated_types.rs:391:24:391:28 | SelfParam | TRef | associated_types.rs:67:1:67:23 | Odd | | associated_types.rs:391:24:391:28 | SelfParam | TRef.OddT | {EXTERNAL LOCATION} | i32 | -| associated_types.rs:391:47:394:9 | { ... } | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:391:47:394:9 | { ... } | | {EXTERNAL LOCATION} | char | -| associated_types.rs:393:13:393:30 | ...::default(...) | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:393:13:393:30 | ...::default(...) | | {EXTERNAL LOCATION} | char | | associated_types.rs:399:24:399:28 | SelfParam | | {EXTERNAL LOCATION} | & | | associated_types.rs:399:24:399:28 | SelfParam | TRef | associated_types.rs:67:1:67:23 | Odd | | associated_types.rs:399:24:399:28 | SelfParam | TRef.OddT | {EXTERNAL LOCATION} | bool | -| associated_types.rs:399:47:401:9 | { ... } | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:399:47:401:9 | { ... } | | {EXTERNAL LOCATION} | char | -| associated_types.rs:400:13:400:30 | ...::default(...) | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:400:13:400:30 | ...::default(...) | | {EXTERNAL LOCATION} | char | | associated_types.rs:404:33:404:36 | item | | {EXTERNAL LOCATION} | & | | associated_types.rs:404:33:404:36 | item | TRef | associated_types.rs:404:20:404:30 | T | | associated_types.rs:405:9:405:12 | item | | {EXTERNAL LOCATION} | & | @@ -5062,19 +5050,11 @@ inferType | associated_types.rs:418:37:418:42 | &item2 | TRef.T | {EXTERNAL LOCATION} | bool | | associated_types.rs:418:38:418:42 | item2 | | associated_types.rs:368:5:368:24 | MyType | | associated_types.rs:418:38:418:42 | item2 | T | {EXTERNAL LOCATION} | bool | -| associated_types.rs:420:13:420:21 | _content3 | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:420:13:420:21 | _content3 | | {EXTERNAL LOCATION} | char | | associated_types.rs:420:25:420:34 | Odd(...) | | associated_types.rs:67:1:67:23 | Odd | | associated_types.rs:420:25:420:34 | Odd(...) | OddT | {EXTERNAL LOCATION} | i32 | -| associated_types.rs:420:25:420:48 | ... .get_content() | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:420:25:420:48 | ... .get_content() | | {EXTERNAL LOCATION} | char | | associated_types.rs:420:29:420:33 | 42i32 | | {EXTERNAL LOCATION} | i32 | -| associated_types.rs:421:13:421:21 | _content4 | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:421:13:421:21 | _content4 | | {EXTERNAL LOCATION} | char | | associated_types.rs:421:25:421:33 | Odd(...) | | associated_types.rs:67:1:67:23 | Odd | | associated_types.rs:421:25:421:33 | Odd(...) | OddT | {EXTERNAL LOCATION} | bool | -| associated_types.rs:421:25:421:47 | ... .get_content() | | {EXTERNAL LOCATION} | bool | -| associated_types.rs:421:25:421:47 | ... .get_content() | | {EXTERNAL LOCATION} | char | | associated_types.rs:421:29:421:32 | true | | {EXTERNAL LOCATION} | bool | | associated_types.rs:435:16:435:20 | SelfParam | | {EXTERNAL LOCATION} | & | | associated_types.rs:435:16:435:20 | SelfParam | TRef | associated_types.rs:428:5:428:20 | ST |