es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Puede el óxido razonar sobre los tiempos de vida en todas las rutas de flujo de control?

Considere el siguiente ejemplo:

impl Foo {
    fn measure<'a>(&'a self) -> Vec<&'a Bar> {...}

<pre><code>fn try_action<'a>(&'a mut self) -> Result<(), Vec<&'a Bar>> {
    let measurement = self.measure(); // esto crea referencias que podemos querer devolver desde este ámbito
    if measurement.is_empty() {
        drop(measurement); // solo para ser explícito y demostrar que esto es seguro
        self.baz = 0;
        Ok(())
    } else {
        Err(measurement) // aquí no mutamos self, en cambio, queremos devolver una razón por la que no pudimos
    }
}
</code></pre>

<p>}

A partir de Rust 1.57.0, el comprobador de préstamos no aceptará este programa. Está molesto porque no puedo pedir prestado *self como mutable debido a la existencia de un préstamo inmutable (el creado por la llamada a measure).

Mi comprensión de esto es que cree que hay un problema porque las referencias contenidas dentro de measurement técnicamente pueden durar hasta el final del ámbito de la función (en el caso del bloque else). Sin embargo, como humanos, podemos ver que esto debería ser seguro porque todos los préstamos inmutables se eliminan antes de cualquier mutación. No los eliminamos en todos los flujos de control, pero aquellos en los que persisten no tienen ninguna mutación en ellos. Por lo tanto, para todos los flujos de control, eliminamos los préstamos inmutables (aunque la falta de uso debería ser suficiente aquí), O nunca mutamos la estructura.

¿Por qué Rust no puede razonar sobre esto?
¿Es esto un error en la lógica de Rust?
¿Es esto una limitación del diseño de las lifetimes?
¿Es esto unsound?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Rust no puede razonar sobre esto porque el verificador de préstamos está diseñado para ser conservador y prevenir cualquier posible carrera de datos o problemas de seguridad de memoria. Mientras que los humanos pueden ver que debería ser seguro devolver las referencias contenidas en “medición” porque no son mutadas y todos los préstamos inmutables se eliminan antes de que ocurra cualquier mutación, el verificador de préstamos no puede hacer esa misma deducción.

    Esto no es un error en la lógica de rustc, sino más bien una limitación del diseño actual de las duraciones y el verificador de préstamos. Es posible que mejoras futuras permitan realizar razonamientos y análisis más complejos, pero por ahora, es mejor seguir las reglas del verificador de préstamos y refactorizar el código según sea necesario para satisfacer sus restricciones.

    El código tal como está escrito es considerado inseguro por el verificador de préstamos, pero con la explicación proporcionada, es razonable argumentar que debería ser seguro en la práctica. Sin embargo, siempre es mejor errar por el lado de la precaución cuando se trata de la seguridad de la memoria y seguir las reglas del verificador de préstamos.

Comments are closed.