Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions rust/ql/lib/change-notes/2026-09-07-self-path-trait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fix path resolution for `m::{self}` paths where `m` is a trait.
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/internal/PathResolution.qll
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ abstract class ItemNode extends Locatable {
if
this instanceof Module or
this instanceof Enum or
this instanceof Struct or
this instanceof Trait or
this instanceof Crate
then (
kind.isBoth() and
Expand Down
12 changes: 12 additions & 0 deletions rust/ql/test/library-tests/path-resolution/invalid/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@ struct A; // A1
struct A; // A2

fn f(x: A) {} // $ item=A2 (the latter occurence takes precedence)

/// Test `m::{self}` where `m` is a struct. Per the Rust specification `m` must
/// resolve to a module, trait, or enum:
/// https://doc.rust-lang.org/reference/items/use-declarations.html#r-items.use.self.module
mod self_import_from_struct {
struct MyStruct; // Struct

#[rustfmt::skip]
use self::MyStruct::{ // $ item=Struct
self // $ SPURIOUS: item=self_import_from_struct
};
}
33 changes: 21 additions & 12 deletions rust/ql/test/library-tests/path-resolution/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,29 +685,38 @@ mod m18 {
}
}

mod m21 {
mod m22 {
/// Test importing modules, traits, and enums with `{self}`.
mod self_imports {
mod definitions {
pub mod my_module {
pub fn f() {} // I107
} // I104
pub trait MyTrait {} // I105
pub enum MyEnum {
A, // I104
} // I105
A, // I108
} // I106
}

pub struct MyStruct; // I106
} // I107
mod imports {
#[rustfmt::skip]
use super::definitions::my_module::{ // $ item=I104
self // $ item=I104
};

mod m33 {
#[rustfmt::skip]
use super::m22::MyEnum::{ // $ item=I105
use super::definitions::MyTrait::{ // $ item=I105
self // $ item=I105
};

#[rustfmt::skip]
use super::m22::MyStruct::{ // $ item=I106
use super::definitions::MyEnum::{ // $ item=I106
self // $ item=I106
};

fn f() {
let _ = MyEnum::A; // $ item=I104
let _ = MyStruct {}; // $ item=I106
#[rustfmt::skip]
fn f<T: MyTrait>() { // $ item=I105
my_module::f(); // $ item=I107
let _ = MyEnum::A; // $ item=I108
}
}
}
Expand Down
Loading
Loading