Aller au contenu

Erreur Rust E0601 : `main` function not found in crate (pas de fn main)

E0601 veut dire : Rust voulait construire un programme, mais n’a pas trouvé où il commence. Tout programme Rust démarre dans une fonction qui s’appelle exactement main, écrite au niveau supérieur de src/main.rs. Si elle manque, si son nom est mal écrit ou si elle est rangée dans un module, vous obtenez cette erreur. C’est très courant quand on copie un extrait d’un tutoriel ou de la documentation d’une bibliothèque, et ça se corrige toujours vite. Cette page fait partie du guide des erreurs du compilateur Rust.

error[E0601]: `main` function not found in crate `main`
--> src/main.rs:7:2
|
7 | } // ❌ fin du fichier, et aucune `fn main` nulle part
| ^ consider adding a `main` function to `src/main.rs`

Le compilateur vous dit : « fonction main introuvable dans la crate main », et il propose d’ajouter une fonction main à src/main.rs.

Voici le programme qui la provoque :

fn total(prices: &[u32]) -> u32 {
prices.iter().sum()
}
fn average(prices: &[u32]) -> u32 {
total(prices) / prices.len() as u32
} // ❌ fin du fichier, et aucune `fn main` nulle part

Le ^ pointe la toute fin du fichier, juste après le dernier }. Ça paraît bizarre, mais c’est logique : rustc a lu tout le fichier en cherchant fn main, et il est arrivé au bout sans en trouver. Il n’y a pas de mauvaise ligne à montrer : le problème, c’est une ligne qui n’existe pas.

Le nom de la crate dans le message dépend de la façon dont vous compilez. Cette sortie vient de rustc src/main.rs, donc la crate s’appelle main, d’après le fichier. Avec cargo run, vous verrez plutôt le nom de votre paquet tiré de Cargo.toml, par exemple `main` function not found in crate `shop`. Même erreur, mêmes solutions.

C’est comme une pièce de théâtre avec de superbes scènes, mais sans « Acte 1, scène 1 ». Les comédiens sont prêts, mais personne ne sait où commence le spectacle.

Un binaire Rust (un programme que vous lancez) a besoin d’un point d’entrée unique et fixe. Quand vous démarrez le programme, le système d’exploitation appelle main, et tout le reste se produit parce que main l’appelle. Rust ne devine pas : ni la première fonction du fichier, ni une fonction nommée start, ni Main. Le nom doit être exactement main, tout en minuscules, au niveau supérieur de la crate.

Du code qui n’est pas un programme à lui seul, comme un ensemble de fonctions utilitaires dont se sert un autre code, est une bibliothèque (library). Une bibliothèque n’a pas de main et s’écrit dans src/lib.rs. E0601 veut souvent dire que le code est bon, mais qu’il est dans la mauvaise sorte de crate. Voir Crate binaire et crate bibliothèque ensemble et Premiers pas.

Solution 1 : ajouter une fonction main (ou corriger son nom)

Section intitulée « Solution 1 : ajouter une fonction main (ou corriger son nom) »

Choisissez-la la plupart du temps : vous avez copié des fonctions de quelque part, ou vous avez commencé à écrire des fonctions d’aide sans avoir encore écrit main. Ajoutez fn main() et appelez votre code depuis elle :

fn total(prices: &[u32]) -> u32 {
prices.iter().sum()
}
fn average(prices: &[u32]) -> u32 {
total(prices) / prices.len() as u32
}
fn main() { // ✅ le programme commence ici
let prices = [250, 199, 1200];
println!("total : {} centimes", total(&prices));
println!("moyenne : {} centimes", average(&prices));
}

Sortie :

total : 1649 centimes
moyenne : 549 centimes
▶ Essayez par vous-même

Vous avez déjà une main ? Vérifiez alors son orthographe. fn Main(), fn mian() ou fn main_() donnent tous exactement la même E0601, car pour Rust ce sont juste d’autres fonctions. Le nom respecte la casse, et ce doit être une fonction : fn main(), avec les parenthèses.

Choisissez-la quand le message dit the main function must be defined at the crate level. Vous avez une main, mais elle est dans un mod : c’est donc en réalité app::main, pas le point d’entrée du programme :

error[E0601]: `main` function not found in crate `main`
--> src/main.rs:5:2
|
5 | }
| ^ the main function must be defined at the crate level (in `src/main.rs`)
|
note: here is a function named `main`
--> src/main.rs:2:5
|
2 | pub fn main() { // ❌ dans un module, pas au niveau supérieur
| ^^^^^^^^^^^^^
= note: you have one or more functions named `main` not defined at the crate level
= help: consider moving the `main` function definitions

Ici, rustc dit que la fonction main doit être définie au niveau de la crate (dans src/main.rs). La note montre la fonction nommée main qu’il a trouvée ailleurs, et l’aide propose de la déplacer.

Le programme qui la provoque :

mod app {
pub fn main() { // ❌ dans un module, pas au niveau supérieur
println!("Ouverture de la boutique...");
}
}

Mettez la vraie main au niveau supérieur. Le code du module peut rester où il est ; donnez-lui un nom plus clair, comme run, et appelez-le depuis main :

mod app {
pub fn run() {
println!("Ouverture de la boutique...");
}
}
fn main() { // ✅ au niveau supérieur de src/main.rs
app::run();
}

Sortie :

Ouverture de la boutique...
▶ Essayez par vous-même

C’est pareil pour les modules dans d’autres fichiers : une pub fn main() dans src/app.rs est app::main, jamais le point d’entrée. Voir Les modules.

Solution 3 : en faire une bibliothèque, si ce n’est pas fait pour se lancer seul

Section intitulée « Solution 3 : en faire une bibliothèque, si ce n’est pas fait pour se lancer seul »

Choisissez-la quand le code est un ensemble de fonctions d’aide dont se sert un autre code, sans rien à « lancer ». Les bibliothèques n’ont pas de main. Créez le projet avec --lib :

Terminal window
cargo new --lib cart # crée src/lib.rs : une bibliothèque, pas besoin de main
cargo new shop # crée src/main.rs avec fn main() : un programme

Mettez les fonctions d’aide dans src/lib.rs, marquez avec pub ce que les autres ont le droit d’utiliser, et vérifiez-les avec des tests plutôt qu’avec cargo run :

src/lib.rs
pub fn total(prices: &[u32]) -> u32 {
prices.iter().sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds_prices() {
assert_eq!(total(&[3, 4]), 7);
}
}

Sur une bibliothèque, lancez cargo build ou cargo test. cargo run n’y marche pas ; il répond error: a bin target must be available for `cargo run`, la façon de Cargo de dire « il n’y a aucun programme dans ce paquet ». Si vous voulez les deux, ajoutez un src/main.rs à côté de src/lib.rs. Il utilise la bibliothèque par le nom du paquet :

src/main.rs
fn main() {
let sum = cart::total(&[250, 199, 1200]);
println!("total : {} centimes", sum);
}

Maintenant, cargo run affiche total : 1649 centimes. Voir Crate binaire et crate bibliothèque ensemble et Les tests.

En collant un extrait d’une documentation ou d’un tutoriel. Beaucoup d’exemples ne montrent qu’une fonction ou une struct, pas un programme complet. Collés dans src/main.rs, ils donnent E0601. Correction : entourez les lignes qui font quelque chose avec fn main() { ... }, et laissez les fonctions et les structs à l’extérieur. (Le Rust Playground remarque l’absence de main et propose de compiler le code au lieu de l’exécuter : là-bas, vous ne verrez donc en général pas cette erreur.)

Votre éditeur souligne en rouge la dernière ligne de main.rs. rust-analyzer lance cargo check en arrière-plan, donc vous voyez E0601 sur la dernière ligne pendant que vous écrivez encore vos fonctions d’aide. Pas d’inquiétude : la marque disparaît dès que vous ajoutez fn main().

Des programmes supplémentaires dans src/bin/. Chaque fichier de src/bin/, comme src/bin/import.rs, est un programme séparé, et chacun a besoin de sa propre fn main(). Correction : ajoutez main à ce fichier, ou déplacez le code partagé dans src/lib.rs. Voir le lien sur les cibles Cargo plus bas.

Petit quiz

1. Votre src/main.rs contient fn Main() { ... }. Que dit cargo run ?

2. Vous écrivez des fonctions d'aide pour d'autres programmes, sans rien à lancer. Quelle est la bonne organisation ?

3. rustc dit « the main function must be defined at the crate level ». Quel est le problème ?

Score : 0 / 3