如何在不查看代码的情况下阅读生命周期错误?

时间:2018-03-21 13:52:08

标签: rust borrow-checker

我收到以下生命周期错误:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> prusti-viper/src/procedures_table.rs:42:40
   |
42 |         let mut cfg = self.cfg_factory.new_cfg_method(
   |                                        ^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 40:5...
  --> prusti-viper/src/procedures_table.rs:40:5
   |
40 | /     pub fn set_used(&mut self, proc_def_id: ProcedureDefId) {
41 | |         let procedure = self.env.get_procedure(proc_def_id);
42 | |         let mut cfg = self.cfg_factory.new_cfg_method(
43 | |             // method name
...  |
135| |         self.procedures.insert(proc_def_id, method);
136| |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> prusti-viper/src/procedures_table.rs:42:23
   |
42 |         let mut cfg = self.cfg_factory.new_cfg_method(
   |                       ^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'v as defined on the impl at 22:1...
  --> prusti-viper/src/procedures_table.rs:22:1
   |
22 | impl<'v, P: Procedure> ProceduresTable<'v, P> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: ...so that the expression is assignable:
           expected viper::Method<'v>
              found viper::Method<'_>

error: aborting due to previous error

不看代码,只需阅读错误信息,是否有可能了解哪些生命周期/引用/借用是指错误信息?以下是用我的问题注释的消息:

  

错误[E0495]:由于需求冲突,无法推断autoref (什么是autoref?)的适当生命周期

     

注意:首先,生命周期(生命周期?)不能超过匿名生命#1 &mut self,ok)中定义的生命周期方法体40:5 ......

     

...所以参考(参考?)并不比借来的内容(借用内容?)

     

但是,生命周期必须在生命周期内有效,并且在22:1的impl上定义... (为什么这些约束?)

例如,我正在寻找类似&#34的解释;在错误消息E0495中,不能超过匿名生命#1的生命周期始终是self的生命周期,换句话说#1再次&#34;

通过查看类似问题(https://stackoverflow.com/a/35519236/2491528https://stackoverflow.com/a/30869059/2491528https://stackoverflow.com/a/41271422/2491528)的现有答案,我无法找到错误消息所指的内容的解释。有时答案只是写了#34;在这种情况下,生命周期是'a&#34;但我想知道如何理解它'a而不是其他一些'b。其他时候答案涉及对源代码的推理,但对我来说这将是以下步骤之一:首先阅读消息并理解它所引用的内容,然后理解错误(在这种情况下,可能是冲突的生命周期要求),然后查看代码并尝试修复错误。

1 个答案:

答案 0 :(得分:5)

  由于需求冲突,

无法推断autoref的适当生命周期

这是错误的关键部分。一生中有两个(或更多)要求,它们会发生冲突。 &#34; autoref&#34;表示通过调用&self的方法所引用的引用。引用的代码行指示哪个方法调用是错误的。

  

注意:首先,生命周期不能超过方法体40:5定义的匿名生命#1

这是第一个相互矛盾的要求。 &#34;生命周期&#34;表示第一条消息中提到的那个:它为此autoref推断的那个。它可以比您调用该方法的对象更长久。引用的代码表示该对象的生命周期。在这种情况下,生命周期是错误行所在的整个方法,因为您借用的对象是该方法的成员&mut self

  

注意:......所以引用不会超过借来的内容

这只是进一步解释了。 &#34;那个参考&#34; - 您尝试拍摄的自动曝光 - 可能比&mut self引用的对象更长。

  

注意:但是,生命周期必须在生命周期内有效,并且在22:1的impl上定义...

&#34;但是&#34;这里介绍第二个要求,它与第一个要求相冲突。

你问&#34;为什么这些约束?&#34;,编译器立即解释:

  

注意:......以便表达式可分配:
             预期的viper ::方法&lt;&#t; v&gt;
                发现了viper :: Method&lt;&#39; _&gt;

有问题的作业是错误行中的作业。您已将new_cfg_method的结果分配给cfg。 &#34;预期&#34;是作业的左侧cfg,必须是viper::Method<'v>类型。 &#34;发现&#34;是右侧,方法调用的结果,类型为viper::Method<'_>'_表示编译器尝试推断的生命周期。也就是说,它是您随后使用cfg的方式,这意味着它必须具有生命周期'v。为什么这取决于错误消息中未引用的代码。

要解决此问题,您需要执行以下操作之一:

  1. 删除第一个要求。更改new_cfg_method,以便其结果的生命周期与您调用它的对象的生命周期无关:可能通过删除它包含的一些引用。
  2. 删除第二项要求。更改使用cfg的代码,以便它不需要具有生命周期'v。同样,这可以通过删除viper::Method中的一些引用来实现。
  3. 如果您不能这样做,则可能需要引入Cell或其他内容来动态管理生命周期而不是静态管理生命周期。