Skip to content

Include macro should link to modules #106118

Closed
@coastalwhite

Description

@coastalwhite

Location

include! macro

Summary

Having talked to some new people who are learning rust, the module system is something people often take some time to understand. People coming from C may search rust include file and find the include! macro. I feel like this should clearly link to the modules documentation.

Currently, there is a small part on include being something that usually a bad idea:

Using this macro is often a bad idea, because if the file is parsed as an expression, it is going to be placed in the surrounding code unhygienically. This could result in variables or functions being different from what the file expected if there are variables or functions that have the same name in the current file.

I feel like this part of the documentation should very directly and plainly reference resources about the module system and how that is what they should probably be using. This can link to one or multiple official resources (e.g. The Reference, Rust-by-Example - Modules: File Hierarchy or The Book). Possibly, we can refer to all these resources, although that might be overwhelming to the reader. I would say to add this after the first line as a sort of warning.

It would also be interesting to add where you might then actually use include! macro similar to the Uses header in the assert macro. From my experience, the include macro has two primary uses:

  • Including large parts of documentation
  • Including build artifacts from the OUT_DIR of build scripts

A very primitive draft of the adjusted documentation would be:

Parses a file as an expression or an item according to the context.

For multi-file Rust projects, the include! macro is probably not what you are looking for. Usually, multi-file Rust projects use modules. Multi-file projects and modules are explained in the Rust-by-Example book here and the module system is explained in the Rust Book here.

The included file is parsed as an expression, it is going to be placed in the surrounding code unhygienically. This could result in variables or functions being different from what the file expected if there are variables or functions that have the same name in the current file.

The file is located relative to the current file (similarly to how modules are found). The provided path is interpreted in a platform-specific way at compile time. So, for instance, an invocation with a Windows path containing backslashes \ would not compile correctly on Unix.

Uses

The include! macro is primarily used for two purposes. The macro can be used to include long stretches of documentation. This can also be done with #![doc = include_str!("...")]. The second common use-case for the include! macro is when including the output artifacts of the build script.

Examples

Assume there are two files in the same directory with the following contents:

File 'monkeys.in':

['🙈', '🙊', '🙉']
    .iter()
    .cycle()
    .take(6)
    .collect::<String>()

File 'main.rs':

fn main() {
    let my_string = include!("monkeys.in");
    assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
    println!("{my_string}");
}

Compiling 'main.rs' and running the resulting binary will print
"🙈🙊🙉🙈🙊🙉".

I can create a PR if that is wanted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and tools

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions