Skip to content

Commit a687859

Browse files
authored
Update for new Rust error messages (#1486)
Rust emits different error messages on recent nightlies. This commit adjusts the first post for those messages. The new error messages were introduced in rust-lang/rust#116343 Reported in #997 (comment)
2 parents 2d23521 + eee63b4 commit a687859

12 files changed

Lines changed: 298 additions & 185 deletions

File tree

blog/content/edition-2/posts/01-freestanding-rust-binary/index.ar.md

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,16 @@ fn main() {}
118118
```
119119
> cargo build
120120
error: `#[panic_handler]` function required, but not found
121-
error: language item required, but not found: `eh_personality`
121+
error: unwinding panics are not supported without std
122122
```
123123

124-
الآن يفتقد المترجم إلى دالة `#[panic_handler]` و_عنصر اللغة_ (language item).
124+
الآن يفتقد المترجم إلى دالة `#[panic_handler]` ويشتكي من أن _الفك_ (unwinding) غير ممكن بدون المكتبة القياسية. سننظر في كلا الخطأين في الأقسام التالية.
125+
126+
<div class="note">
127+
128+
في سلاسل أدوات Rust الأقدم، يظهر الخطأ الثاني بدلاً من ذلك كـ `language item required, but not found: eh_personality`، والذي له نفس سبب خطأ `unwinding panics are not supported without std`.
129+
130+
</div>
125131

126132
## تنفيذ Panic
127133

@@ -147,16 +153,15 @@ fn panic(_info: &PanicInfo) -> ! {
147153
[diverging function]: https://doc.rust-lang.org/1.30.0/book/first-edition/functions.html#diverging-functions
148154
[`!`]: https://doc.rust-lang.org/nightly/std/primitive.never.html
149155

150-
## عنصر اللغة `eh_personality`
156+
## الفك
151157

152-
عناصر اللغة هي عناصر خاصة (سمات ودوال وأنواع وما إلى ذلك) مطلوبة داخليًا من قِبَل المترجم. على سبيل المثال، سمة [`Copy`] هي عنصر لغة يخبر المترجم بالأنواع التي لها [_دلالات النسخ_][`Copy`]. عند النظر إلى [التنفيذ][copy code]، نرى أنه يحتوي على السمة الخاصة `#[lang = "copy"]` التي تعرّفه كعنصر لغة.
158+
يستخدم Rust [فك تسلسل المكدس][stack unwinding] بشكل افتراضي لتشغيل المدمِّرات لجميع متغيرات المكدس الحية في حالة حدوث [panic]. هذا يضمن تحرير جميع الذاكرة المستخدمة ويسمح للخيط الرئيسي بالتقاط الـ panic ومواصلة التنفيذ. ومع ذلك، فإن الفك عملية معقدة وتتطلب بعض المكتبات الخاصة بنظام التشغيل (مثل [libunwind] على Linux أو [معالجة الاستثناءات المنظمة][structured exception handling] على Windows)، والتي تتطلب مكتبة Rust القياسية. والنتيجة هي أننا لا نستطيع استخدام الفك لنواة نظام التشغيل `no_std` الخاصة بنا.
153159

154-
[`Copy`]: https://doc.rust-lang.org/nightly/core/marker/trait.Copy.html
155-
[copy code]: https://github.com/rust-lang/rust/blob/485397e49a02a3b7ff77c17e4a3f16c653925cb3/src/libcore/marker.rs#L296-L299
160+
<div class="note">
156161

157-
في حين أن توفير تنفيذات مخصصة لعناصر اللغة ممكن، إلا أنه يجب القيام بذلك فقط كملاذ أخير. والسبب هو أن عناصر اللغة هي تفاصيل تنفيذ غير مستقرة للغاية ولا يتم التحقق من أنواعها حتى (أي أن المترجم لا يتحقق حتى مما إذا كانت الدالة تحتوي على أنواع الوسيطات الصحيحة). لحسن الحظ، هناك طريقة أكثر استقرارًا لإصلاح خطأ عنصر اللغة أعلاه.
162+
خطأ `language item required, but not found: eh_personality` في سلاسل أدوات Rust الأقدم يشير أيضًا إلى الفك. يُميِّز [عنصر اللغة `eh_personality`][`eh_personality` language item] الدالة التي يجب استخدامها لتنفيذ فك تسلسل المكدس. عناصر اللغة هي عناصر خاصة (سمات ودوال وأنواع وما إلى ذلك) مطلوبة داخليًا من قِبَل المترجم. في سلاسل أدوات Rust الأحدث، تم تحسين رسالة الخطأ لتجنب ذكر تفصيل التنفيذ هذا.
158163

159-
يُميِّز [عنصر اللغة `eh_personality`][`eh_personality` language item] دالة تُستخدم لتنفيذ [فك تسلسل المكدس][stack unwinding]. بشكل افتراضي، يستخدم Rust الفك لتشغيل المدمِّرات لجميع متغيرات المكدس الحية في حالة حدوث [panic]. هذا يضمن تحرير جميع الذاكرة المستخدمة ويسمح للخيط الرئيسي بالتقاط الـ panic ومواصلة التنفيذ. ومع ذلك، فإن الفك عملية معقدة وتتطلب بعض المكتبات الخاصة بنظام التشغيل (مثل [libunwind] على Linux أو [معالجة الاستثناءات المنظمة][structured exception handling] على Windows)، لذا لا نريد استخدامها لنظام التشغيل الخاص بنا.
164+
</div>
160165

161166
[`eh_personality` language item]: https://github.com/rust-lang/rust/blob/edb368491551a77d77a48446d4ee88b35490c565/src/libpanic_unwind/gcc.rs#L11-L45
162167
[stack unwinding]: https://www.bogotobogo.com/cplusplus/stackunwinding.php
@@ -175,30 +180,34 @@ panic = "abort"
175180
panic = "abort"
176181
```
177182

178-
يضبط هذا استراتيجية الـ panic على `abort` لكل من ملف التعريف `dev` (المستخدم لـ `cargo build`) وملف التعريف `release` (المستخدم لـ `cargo build --release`). الآن لم يعد عنصر اللغة `eh_personality` مطلوبًا.
183+
يضبط هذا استراتيجية الـ panic على `abort` لكل من ملف التعريف `dev` (المستخدم لـ `cargo build`) وملف التعريف `release` (المستخدم لـ `cargo build --release`). الآن يجب أن يكون خطأ `unwinding panics are not supported without std` قد أُصلح.
179184

180185
[abort on panic]: https://github.com/rust-lang/rust/pull/32900
181186

182-
الآن أصلحنا كلا الخطأين أعلاه. ومع ذلك، إذا حاولنا تجميعه الآن، يحدث خطأ آخر:
187+
إذا حاولنا تجميعه الآن، يحدث خطأ جديد:
183188

184189
```
185190
> cargo build
186-
error: requires `start` lang_item
191+
error: using `fn main` requires the standard library
187192
```
188193

189-
يفتقر برنامجنا إلى عنصر اللغة `start`، الذي يعرّف نقطة الدخول.
194+
<div class="note">
195+
196+
تُبلِّغ سلاسل أدوات Rust الأقدم عن هذا كـ `error: requires start lang_item` بدلاً من ذلك. يعرّف عنصر اللغة `start` نقطة الدخول الأساسية التي تستدعي دالة `main` لاحقًا. لذا فإن هذا الخطأ له نفس سبب خطأ ``using `fn main` requires the standard library`` في سلاسل الأدوات الأحدث.
197+
198+
</div>
190199

191-
## سمة `start`
200+
## نقطة الدخول
192201

193-
قد يظن المرء أن دالة `main` هي أول دالة تُستدعى عند تشغيل برنامج. ومع ذلك، فإن معظم اللغات لديها [نظام وقت تشغيل][runtime system] مسؤول عن أشياء مثل جمع القمامة (مثلاً في Java) أو خيوط البرمجيات (مثلاً goroutines في Go). يحتاج وقت التشغيل هذا إلى الاستدعاء قبل `main`، لأنه يحتاج إلى تهيئة نفسه.
202+
قد يظن المرء أن دالة `main` هي "نقطة الدخول" للبرنامج، أي أول دالة تُستدعى عند تشغيل برنامج. ومع ذلك، فإن معظم اللغات لديها [نظام وقت تشغيل][runtime system] مسؤول عن أشياء مثل جمع القمامة (مثلاً في Java) أو خيوط البرمجيات (مثلاً goroutines في Go). يحتاج وقت التشغيل هذا إلى الاستدعاء قبل `main`، لأنه يحتاج إلى تهيئة نفسه.
194203

195204
[runtime system]: https://en.wikipedia.org/wiki/Runtime_system
196205

197206
في ثنائي Rust نموذجي يربط المكتبة القياسية، يبدأ التنفيذ في مكتبة وقت تشغيل C تسمى `crt0` ("C runtime zero")، والتي تُهيئ البيئة لتطبيق C. يتضمن ذلك إنشاء مكدس ووضع الوسيطات في السجلات الصحيحة. ثم يستدعي وقت تشغيل C [نقطة دخول وقت تشغيل Rust][rt::lang_start]، والمميَّزة بعنصر اللغة `start`. يمتلك Rust وقت تشغيل بسيطًا للغاية يعتني ببعض الأشياء الصغيرة مثل إعداد حراس فائض المكدس أو طباعة تتبع المكدس عند الـ panic. ثم يستدعي وقت التشغيل أخيرًا دالة `main`.
198207

199208
[rt::lang_start]: https://github.com/rust-lang/rust/blob/bb4d1491466d8239a7a5fd68bd605e3276e97afb/src/libstd/rt.rs#L32-L73
200209

201-
لا يمتلك ملفنا القابل للتنفيذ المستقل وصولاً إلى وقت تشغيل Rust و`crt0`، لذا نحتاج إلى تعريف نقطة الدخول الخاصة بنا. تنفيذ عنصر اللغة `start` لن يساعد، لأنه سيتطلب `crt0` أيضًا. بدلاً من ذلك، نحتاج إلى الكتابة فوق نقطة دخول `crt0` مباشرةً.
210+
لا يمتلك ملفنا القابل للتنفيذ المستقل وصولاً إلى وقت تشغيل Rust و`crt0`، لذا نحتاج إلى تعريف نقطة الدخول الخاصة بنا ولا يمكننا فقط تعريف دالة `main`.
202211

203212
### الكتابة فوق نقطة الدخول
204213

blog/content/edition-2/posts/01-freestanding-rust-binary/index.es.md

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,16 @@ fn main() {}
117117
```
118118
> cargo build
119119
error: `#[panic_handler]` function required, but not found
120-
error: language item required, but not found: `eh_personality`
120+
error: unwinding panics are not supported without std
121121
```
122122

123-
Ahora el compilador indica que falta una función `#[panic_handler]` y un _elemento de lenguaje_ (_language item_).
123+
Ahora el compilador indica que falta una función `#[panic_handler]` y se queja de que el _unwinding_ no es posible sin la biblioteca estándar. Examinaremos ambos errores en las siguientes secciones.
124+
125+
<div class="note">
126+
127+
En versiones antiguas de las toolchains de Rust, el segundo error dice en su lugar `language item required, but not found: eh_personality`, que tiene la misma causa que el error `unwinding panics are not supported without std`.
128+
129+
</div>
124130

125131
## Implementación de Panic
126132

@@ -146,16 +152,15 @@ El [parámetro `PanicInfo`][PanicInfo] contiene el archivo y la línea donde ocu
146152
[diverging function]: https://doc.rust-lang.org/1.30.0/book/first-edition/functions.html#diverging-functions
147153
[“never” type]: https://doc.rust-lang.org/nightly/std/primitive.never.html
148154

149-
## El Elemento de Lenguaje `eh_personality`
155+
## Unwinding
150156

151-
Los elementos de lenguaje son elementos especiales (traits, funciones, tipos, etc.) que el compilador requiere internamente. Por ejemplo, el trait [`Copy`] es un elemento de lenguaje que indica al compilador qué tipos tienen [_semántica de copia_][`Copy`]. Si observamos su [implementación][copy code], veremos que tiene el atributo especial `#[lang = "copy"]`, que lo define como un elemento de lenguaje.
157+
Rust utiliza el [desenrollado de pila][stack unwinding] por defecto para ejecutar los destructores de todas las variables de pila activas en caso de un [pánico][panic]. Esto asegura que toda la memoria utilizada sea liberada y permite que el hilo principal capture el pánico y continúe su ejecución. Sin embargo, el unwinding es un proceso complicado y requiere algunas bibliotecas específicas del sistema operativo (por ejemplo, [libunwind] en Linux o [manejadores estructurados de excepciones][structured exception handling] en Windows), que requieren la biblioteca estándar de Rust. La consecuencia es que no podemos usar unwinding para nuestro kernel de sistema operativo `no_std`.
152158

153-
[`Copy`]: https://doc.rust-lang.org/nightly/core/marker/trait.Copy.html
154-
[copy code]: https://github.com/rust-lang/rust/blob/485397e49a02a3b7ff77c17e4a3f16c653925cb3/src/libcore/marker.rs#L296-L299
159+
<div class="note">
155160

156-
Aunque es posible proporcionar implementaciones personalizadas de elementos de lenguaje, esto debería hacerse solo como último recurso. La razón es que los elementos de lenguaje son detalles de implementación altamente inestables y ni siquiera están verificados por tipos (el compilador no comprueba si una función tiene los tipos de argumento correctos). Afortunadamente, hay una forma más estable de solucionar el error relacionado con el elemento de lenguaje mencionado.
161+
El error `language item required, but not found: eh_personality` en versiones antiguas de las toolchains de Rust también apunta al unwinding. El [elemento de lenguaje `eh_personality`][`eh_personality` language item] marca la función que debe usarse para implementar el desenrollado de pila. Los elementos de lenguaje son elementos especiales (traits, funciones, tipos, etc.) que el compilador requiere internamente. En versiones más recientes de las toolchains de Rust, el mensaje de error se mejoró para evitar mencionar este detalle de implementación.
157162

158-
El [elemento de lenguaje `eh_personality`][`eh_personality` language item] marca una función utilizada para implementar el [desenrollado de pila][stack unwinding]. Por defecto, Rust utiliza unwinding para ejecutar los destructores de todas las variables de pila activas en caso de un [pánico][panic]. Esto asegura que toda la memoria utilizada sea liberada y permite que el hilo principal capture el pánico y continúe ejecutándose. Sin embargo, el unwinding es un proceso complicado y requiere algunas bibliotecas específicas del sistema operativo (por ejemplo, [libunwind] en Linux o [manejadores estructurados de excepciones][structured exception handling] en Windows), por lo que no queremos usarlo en nuestro sistema operativo.
163+
</div>
159164

160165
[`eh_personality` language item]: https://github.com/rust-lang/rust/blob/edb368491551a77d77a48446d4ee88b35490c565/src/libpanic_unwind/gcc.rs#L11-L45
161166
[stack unwinding]: https://www.bogotobogo.com/cplusplus/stackunwinding.php
@@ -175,30 +180,34 @@ panic = "abort"
175180
panic = "abort"
176181
```
177182

178-
Esto establece la estrategia de pánico en `abort` tanto para el perfil `dev` (utilizado en `cargo build`) como para el perfil `release` (utilizado en `cargo build --release`). Ahora, el elemento de lenguaje `eh_personality` ya no debería ser necesario.
183+
Esto establece la estrategia de pánico en `abort` tanto para el perfil `dev` (utilizado en `cargo build`) como para el perfil `release` (utilizado en `cargo build --release`). Ahora, el error `unwinding panics are not supported without std` debería estar solucionado.
179184

180185
[abort on panic]: https://github.com/rust-lang/rust/pull/32900
181186

182-
Ahora hemos solucionado ambos errores anteriores. Sin embargo, si intentamos compilarlo ahora, ocurre otro error:
187+
Si intentamos compilarlo ahora, ocurre un nuevo error:
183188

184189
```
185190
> cargo build
186-
error: requires `start` lang_item
191+
error: using `fn main` requires the standard library
187192
```
188193

189-
Nuestro programa carece del elemento de lenguaje `start`, que define el punto de entrada.
194+
<div class="note">
195+
196+
En versiones antiguas de las toolchains de Rust, esto se reporta como `error: requires start lang_item` en su lugar. El elemento de lenguaje `start` define el punto de entrada subyacente que luego llama a la función `main`. Por lo tanto, este error tiene la misma causa que el error ``using `fn main` requires the standard library`` en versiones más recientes de las toolchains.
197+
198+
</div>
190199

191-
## El Atributo `start`
200+
## Punto de Entrada
192201

193-
Podría pensarse que la función `main` es la primera que se ejecuta al correr un programa. Sin embargo, la mayoría de los lenguajes tienen un [sistema de tiempo de ejecución][runtime system], encargado de tareas como la recolección de basura (por ejemplo, en Java) o los hilos de software (por ejemplo, goroutines en Go). Este sistema de tiempo de ejecución necesita ejecutarse antes de `main`, ya que debe inicializarse.
202+
Podría pensarse que la función `main` es el "punto de entrada" del programa, es decir, la primera función que se ejecuta al correr un programa. Sin embargo, la mayoría de los lenguajes tienen un [sistema de tiempo de ejecución][runtime system], encargado de tareas como la recolección de basura (por ejemplo, en Java) o los hilos de software (por ejemplo, goroutines en Go). Este sistema de tiempo de ejecución necesita ejecutarse antes de `main`, ya que debe inicializarse.
194203

195204
[runtime system]: https://en.wikipedia.org/wiki/Runtime_system
196205

197206
En un binario típico de Rust que enlaza con la biblioteca estándar, la ejecución comienza en una biblioteca de tiempo de ejecución de C llamada `crt0` ("C runtime zero"), que configura el entorno para una aplicación en C. Esto incluye la creación de una pila y la colocación de los argumentos en los registros adecuados. Luego, el tiempo de ejecución de C invoca el [punto de entrada del tiempo de ejecución de Rust][rt::lang_start], que está marcado por el elemento de lenguaje `start`. Rust tiene un tiempo de ejecución muy minimalista, que se encarga de tareas menores como configurar los guardias de desbordamiento de pila o imprimir un backtrace en caso de pánico. Finalmente, el tiempo de ejecución llama a la función `main`.
198207

199208
[rt::lang_start]: https://github.com/rust-lang/rust/blob/bb4d1491466d8239a7a5fd68bd605e3276e97afb/src/libstd/rt.rs#L32-L73
200209

201-
Nuestro ejecutable autónomo no tiene acceso al tiempo de ejecución de Rust ni a `crt0`, por lo que necesitamos definir nuestro propio punto de entrada. Implementar el elemento de lenguaje `start` no ayudaría, ya que aún requeriría `crt0`. En su lugar, debemos sobrescribir directamente el punto de entrada de `crt0`.
210+
Nuestro ejecutable autónomo no tiene acceso al tiempo de ejecución de Rust ni a `crt0`, por lo que necesitamos definir nuestro propio punto de entrada y no podemos simplemente definir una función `main`.
202211

203212
### Sobrescribiendo el Punto de Entrada
204213

0 commit comments

Comments
 (0)