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.
Le message d’erreur
Section intitulée « Le message d’erreur »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 partCe que ça veut dire
Section intitulée « Ce que ça veut dire »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.
Pourquoi Rust fait ça
Section intitulée « Pourquoi Rust fait ça »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.
Comment corriger
Section intitulée « Comment corriger »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 centimesmoyenne : 549 centimesVous 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.
Solution 2 : sortir main du module
Section intitulée « Solution 2 : sortir main du module »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 definitionsIci, 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...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 :
cargo new --lib cart # crée src/lib.rs : une bibliothèque, pas besoin de maincargo new shop # crée src/main.rs avec fn main() : un programmeMettez 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 :
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 :
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.
Où vous le verrez souvent
Section intitulée « Où vous le verrez souvent »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.
Erreurs liées
Section intitulée « Erreurs liées »- E0425 : cannot find value in this scope : un nom mal écrit ailleurs dans le programme, par exemple un appel à
totl(). - E0433 : failed to resolve :
main.rsne trouve pas un module ou la crate bibliothèque, par exemplecart::totalavec un mauvais nom de paquet. - E0603 : item is private :
maina trouvé la fonction de la bibliothèque, mais elle n’est paspub. - E0463 : can’t find crate : une crate que vous utilisez avec
usen’est pas dansCargo.toml. - Toutes les erreurs du compilateur : la liste complète des pages d’erreurs.
Petit quiz
Section intitulée « Petit quiz »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
Pour aller plus loin
Section intitulée « Pour aller plus loin »- E0601 — Rust error codes index (en anglais) : l’explication officielle de cette erreur.
- Hello, World! — The Rust Book (en anglais) : votre première fonction
main, et pourquoi tout programme commence là. - Packages and Crates — The Rust Book (en anglais) : crates binaires et crates bibliothèques,
src/main.rsetsrc/lib.rs. - Cargo Targets — The Cargo Book (en anglais) : bibliothèques, binaires,
src/bin/et la façon dont Cargo trouve chacun d’eux. - Main functions — The Rust Reference (en anglais) : les règles exactes pour
main, y compris l’endroit où elle peut être définie.