Erreur Rust E0425 : cannot find value in this scope (nom introuvable)
L’erreur E0425 veut dire que Rust a cherché un nom à un endroit précis de votre code et ne l’a pas trouvé. C’est l’une des erreurs les plus fréquentes, et elle se corrige presque toujours très vite : en général, c’est une faute de frappe, une variable qui vit dans un autre bloc, ou une fonction qui a besoin du chemin de son module. Cette page fait partie du guide des erreurs du compilateur Rust.
Le message d’erreur
Section intitulée « Le message d’erreur »error[E0425]: cannot find value `total_scor` in this scope --> src/main.rs:3:33 |3 | println!("Final score: {}", total_scor); | ^^^^^^^^^^ |help: a local variable with a similar name exists |3 | println!("Final score: {}", total_score); | +Le compilateur vous dit : « impossible de trouver la valeur total_scor dans cette portée ». Il ajoute qu’une variable locale au nom très proche existe.
Voici le programme qui la provoque :
fn main() { let total_score = 42; println!("Final score: {}", total_scor);}Ce que ça veut dire
Section intitulée « Ce que ça veut dire »Les ^^^^ désignent le nom que Rust n’a pas trouvé : total_scor, à la ligne 3. « In this scope » (dans cette portée) veut dire « depuis l’endroit où se trouve cette ligne ». Rust a passé en revue toutes les variables, fonctions et imports visibles à ce point du code, et aucun ne portait ce nom.
Lisez aussi la ligne help:. Ici, rustc a repéré une variable au nom semblable (total_score) et vous montre même la lettre manquante avec un +. Quand vous voyez « a local variable with a similar name exists » (une variable locale au nom semblable existe), c’est une faute de frappe.
C’est comme appeler « Jon ! » à travers une pièce alors que votre ami s’appelle John. Il est juste là, mais personne ne répond au nom de « Jon ».
La même erreur apparaît aussi sous la forme cannot find function ... in this scope (fonction introuvable) quand le nom manquant est une fonction que vous appelez.
Pourquoi Rust fait ça
Section intitulée « Pourquoi Rust fait ça »Rust décide, avant même que votre programme tourne, à quoi correspond chaque nom. Une variable n’existe qu’entre sa ligne let et l’accolade fermante } du bloc où elle a été déclarée. C’est sa portée (scope). En dehors de cette zone, le nom n’existe tout simplement pas.
Beaucoup de langages vous laisseraient faire, et vous découvririez le problème plus tard. En JavaScript, une faute de frappe peut créer sans bruit une nouvelle variable globale ou vous donner undefined. En Python, vous obtiendriez une NameError à l’exécution, peut-être uniquement dans le cas que vos tests ne couvrent jamais. Rust la détecte à la compilation, à chaque fois.
Les fonctions suivent la même idée avec les modules : une fonction dans mod billing n’est pas visible depuis main tant que vous n’écrivez pas son chemin ou que vous ne l’importez pas avec use.
Comment corriger
Section intitulée « Comment corriger »Solution 1 : corriger l’orthographe
Section intitulée « Solution 1 : corriger l’orthographe »Choisissez-la quand la ligne help: dit qu’un nom semblable existe. C’est de loin la cause la plus fréquente. Les noms Rust sont aussi sensibles à la casse : Total_score et total_score sont deux noms différents.
fn main() { let total_score = 42; println!("Score final : {}", total_score);}Sortie :
Score final : 42Solution 2 : déclarer la variable là où les deux endroits la voient
Section intitulée « Solution 2 : déclarer la variable là où les deux endroits la voient »Choisissez-la quand l’aide dit « the binding is available in a different scope in the same function » (la variable existe dans une autre portée de la même fonction). Vous avez créé la variable dans une boucle ou un bloc if, puis vous l’avez utilisée après le }. La version qui ne compile pas ressemble à ceci :
fn main() { let prices = [120, 300, 80]; for price in prices { let with_tax = price + price / 10; println!("{with_tax}"); } println!("Last price with tax: {}", with_tax); // error[E0425]}with_tax est recréée à chaque tour de boucle et jetée au } de la boucle. Si vous avez besoin d’une valeur après la boucle, déclarez-la avant la boucle et mettez-la à jour à l’intérieur :
fn main() { let prices = [120, 300, 80]; let mut last_with_tax = 0;
for price in prices { let with_tax = price + price / 10; println!("{with_tax}"); last_with_tax = with_tax; }
println!("Dernier prix TTC : {}", last_with_tax);}Sortie :
13233088Dernier prix TTC : 88La même correction marche si vous avez utilisé une variable avant sa ligne let. Rust lit de haut en bas : remontez simplement le let.
Solution 3 : donner le chemin de la fonction, ou ajouter un use
Section intitulée « Solution 3 : donner le chemin de la fonction, ou ajouter un use »Choisissez-la pour cannot find function quand la fonction se trouve dans un autre module. Rust affiche :
error[E0425]: cannot find function `total_with_tax` in this scope --> src/main.rs:8:17 |8 | let total = total_with_tax(50.0); | ^^^^^^^^^^^^^^ not found in this scope |help: consider importing this function |1 + use crate::billing::total_with_tax; |Rustc vous propose d’importer la fonction. Vous pouvez soit l’appeler avec son chemin complet (billing::total_with_tax(50.0)), soit ajouter la ligne use suggérée :
mod billing { pub fn total_with_tax(amount: f64) -> f64 { amount * 1.2 }}
use crate::billing::total_with_tax;
fn main() { let total = total_with_tax(50.0); println!("{total}");}Sortie :
60La fonction doit aussi être pub. Sans ça, vous obtiendriez une autre erreur (E0603, « function is private », la fonction est privée). Voir Les modules pour comprendre comment fonctionnent les chemins et use.
Solution 4 : ajouter self. devant un champ
Section intitulée « Solution 4 : ajouter self. devant un champ »Choisissez-la dans une méthode, quand le nom manquant est l’un des champs de votre struct. Si vous venez de Java ou de C#, il est naturel d’écrire count en pensant au champ. En Rust, on écrit toujours self.count. Rustc vous le dit : help: you might have meant to use the available field (vous vouliez peut-être utiliser le champ disponible).
struct Counter { count: u32,}
impl Counter { fn report(&self) { println!("Compteur : {}", self.count); }}
fn main() { let c = Counter { count: 3 }; c.report();}Sortie :
Compteur : 3Où vous le verrez souvent
Section intitulée « Où vous le verrez souvent »-
Une variable définie dans un
if.if balance > 50 { let bonus = 10; }suivi deprintln!("{}", bonus)échoue, carbonusa disparu au}. Correction : faites produire la valeur par leif,let bonus = if balance > 50 { 10 } else { 0 };. -
Appeler un constructeur sans son type.
let p = new("ferris");donnecannot find function `new` in this scope. Correction :newappartient au type, écrivez doncPlayer::new("ferris"). -
Utiliser
selfdans une fonction sans paramètreself. C’est le proche cousin d’E0425, E0424 :error[E0424]: expected value, found module `self`--> src/main.rs:7:9|6 | fn reset() {| ----- this function doesn't have a `self` parameter7 | self.count = 0;| ^^^^ `self` value is a keyword only available in methods with a `self` parameterRustc explique que cette fonction n’a pas de paramètre
self, et queselfn’est disponible que dans les méthodes qui en ont un. Correction : ajoutez un paramètreself. Rustc propose&self, mais ici la fonction modifie un champ, il faut doncfn reset(&mut self).
Erreurs liées
Section intitulée « Erreurs liées »- E0599 : no method found : le nom que vous appelez comme méthode n’existe pas sur ce type.
- E0382 : use of moved value : la variable existe, mais sa valeur a été déplacée.
- E0308 : mismatched types : le nom a été trouvé, mais il n’a pas le bon type.
- E0277 : trait bound not satisfied : il manque à un type un trait dont du code a besoin.
- Toutes les erreurs du compilateur : la liste complète, avec un court résumé de chacune.
Petit quiz
Section intitulée « Petit quiz »Petit quiz
1. Rustc dit « help: a local variable with a similar name exists ». Quelle est la cause la plus probable ?
2. Vous écrivez let found = true; dans une boucle for et vous utilisez found après la boucle. Pourquoi ça échoue ?
3. Une fonction send se trouve dans mod mailer. Quelle ligne permet à main de l'appeler avec send() ?
Score : 0 / 3
Pour aller plus loin
Section intitulée « Pour aller plus loin »- E0425 — Rust error codes index (en anglais) : l’explication officielle, avec d’autres exemples.
- Bringing Paths into Scope with use — The Rust Book (en anglais) : comment
userend visibles les fonctions des autres modules. - Scope and Shadowing — Rust by Example (en anglais) : de courts exemples qui montrent où une variable naît et où elle disparaît.
- Method Syntax — The Rust Book (en anglais) : pourquoi les méthodes utilisent
selfet comment accéder aux champs à travers lui. - E0424 — Rust error codes index (en anglais) : l’erreur voisine, quand on utilise
selfen dehors d’une méthode.