【问题标题】:Rust doesn't recognize that a borrow ends at the end of a loopRust 无法识别借用在循环结束时结束
【发布时间】:2021-02-15 09:25:00
【问题描述】:

在下面的代码中,似乎 rust 编译器存在问题,即在代码执行结束时删除了借用。即使我将 for 循环括在括号中,使其具有自己的范围,它似乎也没有认识到借用结束。

use std::ops::RangeBounds;
use std::any::Any;

pub trait UpdateTables<T> {
    fn apply_first<'a>(&mut self, table: &'a mut T) -> Box<dyn Any + 'a>;
}

struct Drain<R>
where
    R: 'static + Clone + RangeBounds<usize>,
{
   pub r: R,
}
    
impl<T, R> UpdateTables<Vec<T>> for Drain<R>
where
    R: 'static + Clone + RangeBounds<usize>,
{
    fn apply_first<'a>(&mut self, table: &'a mut Vec<T>) -> Box<dyn Any + 'a> {
        Box::new(table.drain(self.r.clone()))
    }
}
    
fn main() {
    let mut v = vec![1, 2, 4, 5, 7, 8];
    let mut d = Drain {
        r: (1..),
    };
    
    println!("{:?}", &v);
    for i in d.apply_first(&mut v).downcast::<std::vec::Drain<'_, i32>>().unwrap() {
        println!("{:?}", i);
    }
    println!("{:?}", &v);
}

编译错误:

error[E0597]: `v` does not live long enough
  --> src/main.rs:32:28
   |
32 |     for i in d.apply_first(&mut v).downcast::<std::vec::Drain<'_, i32>>().unwrap() {
   |              --------------^^^^^^-
   |              |             |
   |              |             borrowed value does not live long enough
   |              argument requires that `v` is borrowed for `'static`
...
37 | }
   | - `v` dropped here while still borrowed

error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
  --> src/main.rs:36:22
   |
32 |     for i in d.apply_first(&mut v).downcast::<std::vec::Drain<'_, i32>>().unwrap() {
   |              ---------------------
   |              |             |
   |              |             mutable borrow occurs here
   |              argument requires that `v` is borrowed for `'static`
...
36 |     println!("{:?}", &v);
   |                      ^^ immutable borrow occurs here

【问题讨论】:

    标签: rust borrow-checker


    【解决方案1】:

    循环不是问题。这个简化示例中的错误是相同的:

    use std::any::Any;
    
    fn apply_first<'a, T>(table: &'a mut Vec<T>) -> Box<dyn Any + 'a> {
        Box::new(table.drain(1..))
    }
        
    fn main() {
        let mut v = vec![1, 2, 4, 5, 7, 8];
        let _ = apply_first(&mut v);
        println!("{:?}", &v);
    }
    
    error[E0597]: `v` does not live long enough
      --> src/main.rs:9:25
       |
    9  |     let _ = apply_first(&mut v);
       |             ------------^^^^^^-
       |             |           |
       |             |           borrowed value does not live long enough
       |             argument requires that `v` is borrowed for `'static`
    10 |     println!("{:?}", &v);
    11 | }
       | - `v` dropped here while still borrowed
    
    error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
      --> src/main.rs:10:22
       |
    9  |     let _ = apply_first(&mut v);
       |             -------------------
       |             |           |
       |             |           mutable borrow occurs here
       |             argument requires that `v` is borrowed for `'static`
    10 |     println!("{:?}", &v);
       |                      ^^ immutable borrow occurs here
    

    核心问题是Any只适用于'static类型,所以dyn Any + 'a是没有意义的,暗示'a: 'static。我确实希望编译器能提供更多关于'static 约束来自哪里的信息,但我离题了。

    另请参阅:Lifetime issue when using the Any trait to get references to structs containing references

    【讨论】:

    • 好收获。在我看来,错误消息只是指向错误的方法; downcast 是实际具有'static 界限的那个。 (Any 上的超特征要求实现者是 'static,但它是协变的,所以当被问到时,没有什么能阻止编译器将 dyn Any + 'static 缩小到 dyn Any + 'a,即使这样的生命周期对于 Any 是无用的。)
    • @trentcl 简化示例不使用 downcast 并显示相同的错误。 Any 仅针对 'staticstd::vec::Drain&lt;'a, T&gt; 不是的类型实现,dyn Any + 'staticdyn Any + 'a 是否正常无关紧要。
    • 对不起,我一定是在我完全清醒之前发布的。你是对的,它不是downcast,但我不同意它与std::vec::Drain 不是'static 有任何关系,因为dyn Any 的转换发生在apply_first 内部,但错误在main 中。 No drain, same error 似乎编译器知道dyn Any + 'a 毕竟暗示'a: 'static
    • @trentcl 哦,我明白你现在在说什么了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    相关资源
    最近更新 更多