Lewati ke konten

Error Rust E0412: cannot find type in this scope (tipe tidak ditemukan)

E0412 artinya: kamu menulis nama tipe yang tidak bisa dilihat Rust dari tempat itu, misalnya di signature fungsi seperti fn print_invoice(inv: &Invoce). Error ini sangat umum dan gampang diperbaiki: salah ketik, baris use yang belum ada, atau generic <T> yang lupa kamu deklarasikan. Ada satu hal yang mungkin membuatmu bingung dulu: sejak Rust 1.93, compiler menampilkan error ini sebagai E0425, dengan pesan yang sama, cannot find type. Halaman ini membahas keduanya. (Halaman ini bagian dari Penjelasan error compiler Rust.)

Ini yang ditampilkan Rust 1.93 dan yang lebih baru (compiler saat ini versi 1.97):

error[E0425]: cannot find type `Invoce` in this scope
--> src/main.rs:2:24
|
1 | struct Invoice { total: u32 }
| -------------- similarly named struct `Invoice` defined here
2 | fn print_invoice(inv: &Invoce) { // ❌ salah ketik: Invoce
| ^^^^^^
|
help: a struct with a similar name exists
|
2 | fn print_invoice(inv: &Invoice) { // ❌ salah ketik: Invoce
| +

Dan ini program yang sama di Rust 1.92 atau yang lebih lama, versi yang dipakai saat sebagian besar artikel blog dan jawaban Stack Overflow ditulis:

error[E0412]: cannot find type `Invoce` in this scope
--> src/main.rs:2:24
|
1 | struct Invoice { total: u32 }
| -------------- similarly named struct `Invoice` defined here
2 | fn print_invoice(inv: &Invoce) {
| ^^^^^^ help: a struct with a similar name exists: `Invoice`

Artinya (di kedua versi): tipe Invoce tidak ditemukan di cakupan (scope) ini, tapi ada struct dengan nama yang mirip, yaitu Invoice.

Ini program yang menghasilkan keduanya:

struct Invoice { total: u32 }
fn print_invoice(inv: &Invoce) { // ❌ salah ketik: Invoce
println!("{}", inv.total);
}
fn main() {
print_invoice(&Invoice { total: 120 });
}

Halaman resmi E0412 (bahasa Inggris) sekarang diawali dengan “this error code is no longer emitted by the compiler” (kode error ini tidak lagi dipakai oleh compiler). Masalahnya tidak hilang, hanya pindah ke E0425, yang juga mencakup variabel dan fungsi yang tidak ditemukan. Semua penjelasan di bawah berlaku sama untuk kedua kode itu.

Tanda ^^^^^^ menunjuk ke Invoce di signature. Untuk memeriksa fungsi ini, Rust harus tahu apa itu Invoce: seberapa besar ukurannya, field apa saja yang dimilikinya. Rust sudah melihat setiap tipe yang terlihat dari baris 2 (struct dan enum buatanmu, baris use-mu, dan prelude) dan tidak menemukan apa pun dengan nama itu.

Baris help: memberi tahu kamu sedang berada di situasi yang mana:

  • “a struct with a similar name exists” (ada struct dengan nama mirip): salah ketik. Tanda + menunjukkan huruf yang hilang.
  • “consider importing this struct” (coba import struct ini): tipenya ada di tempat lain, dan kamu butuh baris use.
  • “you might be missing a type parameter” (mungkin kamu belum menulis parameter tipe): kamu memakai generic T tanpa mendeklarasikan <T>.
  • tidak ada help sama sekali: tipenya memang belum ada. Kamu belum menulisnya, atau tipenya ada di file yang tidak diketahui Rust.

Ini seperti resep yang bilang “tambahkan 200 g Invoce”. Juru masaknya tahu apa itu tepung dan gula, tapi tidak tahu “Invoce”, jadi dia berhenti bahkan sebelum mulai.

Rust memeriksa signature setiap fungsi sebelum program dijalankan. Setiap parameter dan tipe kembalian harus menyebut tipe yang nyata dan dikenal, karena Rust memakainya untuk menentukan berapa banyak memori yang dibutuhkan nilai itu, serta method dan field apa saja yang dimilikinya. Nama yang tidak ditemukan bukanlah sesuatu yang mau ditebak oleh Rust.

Hanya sedikit nama tipe yang terlihat di mana-mana tanpa use: yaitu prelude, dengan String, Vec, Option, Result, Box, dan beberapa lagi. Selebihnya butuh definisimu sendiri, baris use, atau path lengkap seperti std::num::ParseIntError. Lihat Modul untuk cara kerja path dan use.

Kenapa kodenya berubah? Sejak Rust 1.93, rustc melaporkan tipe yang tidak ditemukan dengan E0425, kode yang sudah dipakainya untuk variabel atau fungsi yang tidak ditemukan. Pesannya tetap menyebut type, jadi kamu selalu bisa tahu jenis nama apa yang hilang.

Perbaikan 1: Betulkan ejaannya, atau definisikan tipenya

Section titled “Perbaikan 1: Betulkan ejaannya, atau definisikan tipenya”

Pilih ini kalau rustc bilang ada nama yang mirip, atau tidak memberi help sama sekali. Nama tipe peka huruf besar-kecil: invoice, Invoce, dan Invoice adalah tiga nama yang berbeda. Kalau tidak ada nama yang mirip, tulis dulu struct atau enum-nya:

struct Invoice {
total: u32,
}
fn print_invoice(inv: &Invoice) {
println!("Total faktur: {} EUR", inv.total);
}
fn main() {
print_invoice(&Invoice { total: 120 });
}

Output:

Total faktur: 120 EUR
▶ Coba sendiri

Perbaikan 2: Tambahkan baris use yang disarankan rustc

Section titled “Perbaikan 2: Tambahkan baris use yang disarankan rustc”

Pilih ini kalau help-nya bilang consider importing this struct (atau enum, atau type alias). Tipe dari standard library yang tidak ada di prelude, seperti HashMap, ParseIntError, atau Ordering, butuh baris use. Di sini sebuah fungsi mengembalikan error parsing:

error[E0425]: cannot find type `ParseIntError` in this scope
--> src/main.rs:1:40
|
1 | fn parse_age(text: &str) -> Result<u8, ParseIntError> {
| ^^^^^^^^^^^^^ not found in this scope
|
help: consider importing this struct
|
1 + use std::num::ParseIntError;
|

Artinya: ParseIntError tidak ditemukan di cakupan ini, dan rustc menyarankan untuk meng-import struct itu.

Salin baris yang disarankan ke bagian paling atas file:

use std::num::ParseIntError;
fn parse_age(text: &str) -> Result<u8, ParseIntError> {
text.trim().parse()
}
fn main() {
println!("{:?}", parse_age(" 42 "));
println!("{:?}", parse_age("empat puluh").is_err());
}

Output:

Ok(42)
true
▶ Coba sendiri

Kalau yang kamu tulis adalah HashMap::new() (path dengan ::), bukan tipe di signature, error-nya adalah E0433, dan baris use yang sama memperbaikinya. Kalau rustc menyarankan beberapa import, baca dulu sebelum memilih; itu adalah tipe-tipe berbeda yang kebetulan bernama sama.

Perbaikan 3: Deklarasikan parameter tipe generic-nya

Section titled “Perbaikan 3: Deklarasikan parameter tipe generic-nya”

Pilih ini kalau help-nya bilang you might be missing a type parameter. Di Rust, T bukan kata khusus. Itu nama yang kamu buat sendiri, dan kamu harus mengumumkannya di dalam kurung sudut setelah nama fungsi. Tanpa <T>, Rust mencari tipe sungguhan bernama T:

error[E0425]: cannot find type `T` in this scope
--> src/main.rs:1:21
|
1 | fn largest(items: &[T]) -> &T {
| ^ not found in this scope
|
help: you might be missing a type parameter
|
1 | fn largest<T>(items: &[T]) -> &T {
| +++

Artinya: tipe T tidak ditemukan, dan rustc menduga kamu lupa mendeklarasikan parameter tipe <T>.

Kamu mendapat error yang sama sekali untuk setiap tempat T muncul. Tambahkan <T>, ditambah trait apa pun yang dibutuhkan fungsinya. Untuk membandingkan item dengan >, T harus mengimplementasikan PartialOrd:

fn largest<T: PartialOrd>(items: &[T]) -> &T {
let mut best = &items[0];
for item in items {
if item > best {
best = item;
}
}
best
}
fn main() {
println!("{}", largest(&[34, 50, 25, 100, 65]));
println!("{}", largest(&['y', 'm', 'a', 'q']));
}

Output:

100
y
▶ Coba sendiri

Hal yang sama berlaku untuk struct: struct Wrapper { items: Vec<Item> } gagal kecuali kamu menulis struct Wrapper<Item> atau mendefinisikan tipe Item yang sungguhan. Kalau kamu tidak menulis : PartialOrd, kamu malah mendapat E0369 di tanda >. Lihat Generics.

Pilih ini kalau tipenya buatanmu sendiri tapi berada di modul lain. Ini sering mengejutkan: modul yang berada di dalam file-mu juga tidak bisa melihat tipe-tipe di bagian atas file. Setiap modul punya cakupannya sendiri:

error[E0425]: cannot find type `Order` in this scope
--> src/main.rs:7:26
|
7 | pub fn print(order: &Order) -> String {
| ^^^^^ not found in this scope
|
help: consider importing this struct
|
7 + use crate::Order;
|

Artinya: Order tidak terlihat di dalam modul ini, dan rustc menyarankan untuk meng-import-nya.

7 + artinya “tambahkan baris ini di dalam modul, di baris 7”. crate::Order adalah path dari akar crate-mu; super::Order (“dari modul induk”) juga bisa:

struct Order {
id: u32,
total: u32,
}
mod receipts {
use crate::Order;
pub fn print(order: &Order) -> String {
format!("Pesanan #{}: {} EUR", order.id, order.total)
}
}
fn main() {
let order = Order { id: 7, total: 42 };
println!("{}", receipts::print(&order));
}

Output:

Pesanan #7: 42 EUR
▶ Coba sendiri

Arah sebaliknya juga sama: tipe yang didefinisikan di mod shop butuh pub struct Product dan use crate::shop::Product; (atau path lengkap shop::Product) sebelum main bisa menyebutnya. Kamu paling sering menemui ini di mod tests, tempat use super::*; di bagian atas meng-import semua isi modul induknya.

Tipe dari file yang belum kamu deklarasikan. fn save(user: models::User) dengan file src/models.rs tapi tanpa baris mod models; bukan E0412 atau E0425, melainkan E0433: cannot find module or crate `models` in this scope. Perbaikannya: tambahkan mod models; di bagian atas main.rs, dan jadikan struct-nya pub.

Self di luar impl. fn new_counter() -> Self di level paling atas punya kodenya sendiri, E0411: cannot find type `Self` in this scope, dengan label `Self` is only available in impls, traits, and type definitions (Self hanya tersedia di impl, trait, dan definisi tipe). Perbaikannya: pindahkan fungsinya ke dalam impl Counter { ... }, atau tulis Counter alih-alih Self.

Trait, bukan tipe. impl Display for Point tanpa meng-import Display memberi E0405, cannot find trait `Display` in this scope, dengan help: consider importing this trait, use std::fmt::Display;. Idenya sama, perbaikannya sama: tambahkan baris use. Lihat Trait.

  • E0425: nilai atau fungsi tidak ditemukan, dan sejak Rust 1.93 juga tipe. Kode inilah yang benar-benar akan kamu lihat sekarang.
  • E0433: bagian pertama sebuah path tidak ditemukan, seperti HashMap::new() atau models::User.
  • E0432: unresolved import, saat baris use-nya sendiri tidak menunjuk ke apa pun.
  • E0603: tipenya ditemukan, tapi tidak pub.
  • E0405 (trait tidak ditemukan) dan E0411 (Self di luar impl): kerabat dekat yang ditunjukkan di atas.
  • Semua error compiler: daftar lengkap halaman error.

Kuis singkat

1. Kamu mengikuti tutorial yang menampilkan error[E0412]: cannot find type, tapi compiler-mu menampilkan error[E0425]: cannot find type. Kenapa?

2. fn first(items: &[T]) -> &T memberi cannot find type T. Bagaimana memperbaikinya?

3. Sebuah fungsi di dalam mod billing memakai Order, struct yang didefinisikan di bagian atas main.rs. Baris mana, di dalam modul itu, yang memperbaikinya?

Skor: 0 / 3