Streamlining Rust Code: Understanding the ‘super’ Keyword for Imports

Drashti Shah
2 min readApr 13, 2023

--

Rust is well-known for its focus on safety and performance, and a well-organised codebase is a key factor in achieving these goals. Using modules and sub-modules is a common approach to organize Rust code, but navigating nested modules can sometimes be challenging. The ‘super’ keyword in Rust is designed to alleviate this problem by streamlining imports from parent modules.

Understanding ‘super’

The super keyword in Rust refers to the parent module of the current module. By using super, you can easily reference items from the parent module without having to use the full path. Combined with the wildcard *, you can import all items from the parent module into the current module's scope.

Example

mod a {
pub fn foo() {
println!("Function 'foo' in module 'a'");
}

pub mod b {
pub fn foo() {
println!("Function 'foo' in module 'a::b'");
}

pub mod c {
use super::*;

pub fn call_foo() {
foo(); // This will call 'foo' from the parent module (module 'b')
}
}
}
}

fn main() {
a::b::c::call_foo(); // Output: "Function 'foo' in module 'a::b'"
}

In the example above, we have three nested modules: a, a::b, and a::b::c. Each module has a function named foo. Inside the a::b::c module, we use the super::* import statement to bring all items from the parent module a::b into its scope. This way, when the call_foo function is called, it will reference the foo function from module a::b without having to use the full path super::foo().

Using ‘super’ multiple times

It is also possible to use super multiple times to reference items from higher-level ancestor modules. For example, you can use super::super::foo to access a function foo from the grandparent module.

Example

mod a {
pub fn foo() {
println!("Function 'foo' in module 'a'");
}

pub mod b {
pub mod c {
use super::super::*;

pub fn call_foo() {
foo(); // This will call 'foo' from the grandparent module (module 'a')
}
}
}
}

fn main() {
a::b::c::call_foo(); // Output: "Function 'foo' in module 'a'"
}

Benefits of using ‘super’

  1. Simplified imports: Using super makes it easier to reference items from the parent module, resulting in cleaner and more concise code.
  2. Improved readability: With shorter import paths, your code becomes more readable and easier to understand for other developers.
  3. Easier refactoring: When you decide to reorganise your module hierarchy, using super can make refactoring less painful, as you won't have to update the full paths for every item in your nested modules.

To sum up, the ‘super’ keyword is a valuable asset for Rust developers working with nested modules. By streamlining imports from parent modules, it helps create a cleaner and more organised codebase.

--

--

Drashti Shah

ESG & climate data scientist by day. Aspiring computational biologist and game designer by night. A Rust fan who believes in an "open career".