Ir al contenido

Error E0027 de Rust: pattern does not mention field X (faltan campos en el patrón)

E0027 significa: estás desarmando un struct o una variante de enum con un patrón, como let Order { item, quantity } = order;, y no mencionaste todos los campos. En Rust, un patrón de struct tiene que tener en cuenta todos los campos, o nombrándolos o diciendo “y el resto” con ... Es uno de los errores más amables que hay: rustc te escribe la solución exacta, y casi siempre son dos puntos. (Esta página forma parte de Errores del compilador de Rust explicados.)

error[E0027]: pattern does not mention fields `id`, `paid`
--> src/main.rs:10:9
|
10 | let Order { item, quantity } = order; // ❌ `id` and `paid` are not mentioned
| ^^^^^^^^^^^^^^^^^^^^^^^^ missing fields `id`, `paid`
|
help: include the missing fields in the pattern
|
10 | let Order { item, quantity, id, paid } = order; // ❌ `id` and `paid` are not mentioned
| ++++++++++
help: if you don't care about these missing fields, you can explicitly ignore them
|
10 | let Order { item, quantity, id: _, paid: _ } = order; // ❌ `id` and `paid` are not mentioned
| ++++++++++++++++
help: or always ignore missing fields here
|
10 | let Order { item, quantity, .. } = order; // ❌ `id` and `paid` are not mentioned
| ++++

“Pattern does not mention fields id, paid” quiere decir “el patrón no menciona los campos id y paid”. La etiqueta missing fields significa “faltan campos”, y debajo vienen tres sugerencias que te explicamos enseguida.

Este es el programa que lo produce:

struct Order {
id: u32,
item: String,
quantity: u32,
paid: bool,
}
fn main() {
let order = Order { id: 1, item: String::from("keyboard"), quantity: 2, paid: true };
let Order { item, quantity } = order; // ❌ `id` and `paid` are not mentioned
println!("{} x {}", quantity, item);
}

El titular enumera los campos que tu patrón dejó fuera (id y paid). El ^^^ subraya el patrón entero, porque el problema no es una palabra equivocada, sino algo que falta.

Luego rustc te da tres sugerencias help:. Todas son válidas, y significan cosas distintas:

  • include the missing fields (incluye los campos que faltan): nómbralos, y así también obtienes las variables id y paid.
  • explicitly ignore them (ignóralos de forma explícita): escribe id: _, paid: _. No obtienes variables, pero has nombrado todos los campos.
  • always ignore missing fields here (ignora siempre aquí los campos que falten): escribe ... Significa “y cualquier otro campo, no me importan”.

Es como una lista de control en la entrada que dice “marca todas las casillas, o marca Otros: omitir”. No puedes dejar casillas en blanco sin más.

En Rust, un patrón de struct tiene que estar completo salvo que digas lo contrario. Así tu intención queda clara para quien lea el código después. Order { item, quantity, .. } dice “solo necesito estos dos”. Order { id, item, quantity, paid } dice “he pensado en todos los campos”. Mira Ignorar partes con _ y ...

La verdadera ventaja llega cuando el struct cambia. Si alguien añade un campo discount a Order, un patrón que nombra todos los campos se rompe con E0027, y eso te señala código que quizá tenga que tratar el campo nuevo. Un patrón con .. sigue compilando. Rust te deja elegir qué comportamiento quieres, pero no lo adivina por ti.

Solución 1: Añade .. para ignorar el resto

Sección titulada «Solución 1: Añade .. para ignorar el resto»

Elige esta la mayoría de las veces. Si solo necesitas algunos campos, termina el patrón con ... Funciona en let, match, if let y en los parámetros de funciones, y tiene que ir al final.

struct Order {
id: u32,
item: String,
quantity: u32,
paid: bool,
}
fn main() {
let order = Order { id: 1, item: String::from("teclado"), quantity: 2, paid: true };
let Order { item, quantity, .. } = order; // ✅ `..` se salta `id` y `paid`
println!("{} x {}", quantity, item);
let orders = [
Order { id: 2, item: String::from("auriculares"), quantity: 1, paid: false },
Order { id: 3, item: String::from("monitor"), quantity: 1, paid: true },
];
for order in &orders {
match order {
Order { paid: true, item, .. } => println!("listo para enviar: {}", item),
Order { id, .. } => println!("el pedido #{} espera el pago", id),
}
}
}

Salida:

2 x teclado
el pedido #2 espera el pago
listo para enviar: monitor
▶ Pruébalo tú mismo

Fíjate en paid: true en el primer brazo: en un patrón, un campo también se puede comparar con un valor, y .. se sigue encargando de los demás.

Solución 2: Nombra el campo que falta, o ignóralo por su nombre con _

Sección titulada «Solución 2: Nombra el campo que falta, o ignóralo por su nombre con _»

Elige esta cuando de verdad necesitas el campo, o cuando quieres que el patrón se rompa si más adelante se añade un campo. El mismo error aparece en un match sobre una variante de enum con campos con nombre:

error[E0027]: pattern does not mention field `y`
--> src/main.rs:9:9
|
9 | Message::Move { x } => println!("move to x = {}", x), // ❌ `y` is not mentioned
| ^^^^^^^^^^^^^^^^^^^ missing field `y`

Aquí el patrón no menciona el campo y, y la etiqueta lo repite: falta el campo y.

El programa que hay detrás:

enum Message {
Move { x: i32, y: i32 },
Quit,
}
fn main() {
let m = Message::Move { x: 1, y: 2 };
match m {
Message::Move { x } => println!("move to x = {}", x), // ❌ `y` is not mentioned
Message::Quit => println!("quit"),
}
}

Un movimiento tiene dos coordenadas, y el código debería usar las dos. Así que nombra y. Cuando un campo de verdad no importa, y: _ lo dice en voz alta, y aun así lo nombra:

enum Message {
Move { x: i32, y: i32 },
Quit,
}
fn main() {
let messages = [Message::Move { x: 1, y: 2 }, Message::Move { x: 5, y: 0 }, Message::Quit];
for m in &messages {
match m {
Message::Move { x, y: 0 } => println!("deslízate por el suelo hasta x = {}", x),
Message::Move { x, y } => println!("muévete a ({}, {})", x, y), // ✅ los dos campos
Message::Quit => println!("salir"),
}
}
// todos los campos nombrados: añadir un campo a `Move` romperá esto a propósito
if let Message::Move { x, y: _ } = &messages[0] {
println!("primera x = {}", x);
}
}

Salida:

muévete a (1, 2)
deslízate por el suelo hasta x = 5
salir
primera x = 1
▶ Pruébalo tú mismo

Si nombras un campo solo para ignorarlo, escribe y: _, no un simple y. Un y que nunca usas da un aviso de “unused variable” (variable sin usar).

Solución 3: Corrige un nombre de campo mal escrito

Sección titulada «Solución 3: Corrige un nombre de campo mal escrito»

Elige esta cuando E0027 aparece junto con E0026 en la misma línea. Por ejemplo, Shape::Circle { r } para una variante cuyo campo es radius da los dos: E0026 por r (ese campo no existe) y E0027 por radius (no se menciona). El help de E0027 te sugerirá añadir radius al lado de r, pero eso no es lo que quieres. La solución real es cambiar el nombre equivocado: Shape::Circle { radius }, o Shape::Circle { radius: r } para mantener el nombre corto de la variable. Entonces los dos errores desaparecen a la vez. Mira la página de E0026 para ver ejemplos.

Después de añadir un campo a un struct. Añades created_at a Order, y cada patrón que nombraba todos los campos ahora da E0027. Es la comprobación haciendo su trabajo. Decide en cada caso: ¿este código necesita created_at? Si es así, nómbralo; si no, añade ...

Parámetros de funciones. fn print_order(&Order { item, quantity }: &Order) también da E0027. Solución: &Order { item, quantity, .. }. Mira Patrones en let y en los parámetros de funciones.

Tuple structs y variantes de tupla. Para struct Color(u8, u8, u8);, el patrón Color(r) también está incompleto, pero rustc lo informa como E0023, “this pattern has 1 field, but the corresponding tuple struct has 3 fields” (este patrón tiene 1 campo, pero el tuple struct correspondiente tiene 3). La solución sigue la misma idea: Color(r, ..) o Color(r, _, _).

Comprueba lo aprendido

1. struct Point { x: i32, y: i32, z: i32 }. ¿Qué patrón compila y te da solo x?

2. ¿Qué diferencia hay entre Order { item, .. } y Order { item, id: _, quantity: _, paid: _ }?

3. Te sale E0026 por r y E0027 por radius en la misma línea. ¿Cuál es la mejor solución?

Puntuación: 0 / 3